摘要
本文对 如何使用 AURIX TM TC275 lite Kit 实现adc数据的读取、数字端口IO的操作以及串口输出数据进行了简要介绍,关键代码在文中被列出, 此外本文附加材料包括完整的实现代码。
本文介绍的内容对应于 Funpack第二季第二期活动规则中的任务二:
任务二项目描述:设计一个呼吸灯,通过旋转板卡上的电位计,改变呼吸灯闪烁速率,同时将ADC采集的数据通过串口/CAN,发送到另一台设备上显示.
一、基本功能拆分:
- 电位计所对应输入adc端口的数据读取。
- 数据处理后转换为对LED数字输出端口高低电平切换时间间隔的控制。
- 数据处理后通过串口输出数据至电脑。
- 电脑端读取串口数据并实时绘图。
二、功能实现:
- 读取电位计对应IO的电压
官方提供的电路原理图可以看到,电位计对应AN0 归属于 adc 中的 group 0 Chanel id 0
因此,配置ADC 读取 AN0 即可跟踪电位计变化。
对应部分程序:
/* Function to initialize the VADC group */
void initVADCGroup(void)
{
IfxVadc_Adc_GroupConfig adcGroupConf; /* Define a configuration structure */
IfxVadc_Adc_initGroupConfig(&adcGroupConf, &g_vadc); /* Fill it with default values */
adcGroupConf.groupId = IfxVadc_GroupId_0; /* Select the Group 0 */
adcGroupConf.master = adcGroupConf.groupId; /* Set the same group as master group */
/* Enable the background scan source and the background auto scan functionality */
adcGroupConf.arbiter.requestSlotBackgroundScanEnabled = TRUE;
adcGroupConf.backgroundScanRequest.autoBackgroundScanEnabled = TRUE;
/* Enable the gate in "always" mode (no edge detection) */
adcGroupConf.backgroundScanRequest.triggerConfig.gatingMode = IfxVadc_GatingMode_always;
IfxVadc_Adc_initGroup(&g_vadcGroup, &adcGroupConf); /* Apply the configuration */
}
/* Function to initialize the VADC used channels */
void initVADCChannels(void)
{
IfxVadc_Adc_ChannelConfig adcChannelConf[CHANNELS_NUM]; /* Array of configuration structures */
uint16 chn;
for(chn = 0; chn < CHANNELS_NUM; chn++) /* Initialize all the channels in a loop */
{
/* Fill the configuration with default values */
IfxVadc_Adc_initChannelConfig(&adcChannelConf[chn], &g_vadcGroup);
/* Set the channel ID and the corresponding result register */
adcChannelConf[chn].channelId = g_vadcChannelIDs[chn]; /* The channels are initialized */
adcChannelConf[chn].resultRegister = (IfxVadc_ChannelResult)(chn);
adcChannelConf[chn].backgroundChannel = TRUE; /* Enable background scan for the channel */
/* Apply the channel configuration */
IfxVadc_Adc_initChannel(&g_vadcChannel[chn], &adcChannelConf[chn]);
/* Add the channel to background scan */
unsigned chnEnableBit = (1 << adcChannelConf[chn].channelId); /* Set the the corresponding input channel */
unsigned mask = chnEnableBit; /* of the respective group to be added in */
IfxVadc_Adc_setBackgroundScan(&g_vadc, &g_vadcGroup, chnEnableBit, mask); /* the background scan sequence. */
}
}
2. 数据处理后转换为对LED数字输出端口高低电平切换时间间隔的控制
初始化LED对应IO并修改闪烁时间间隔,闪烁时间间隔是关于adc读取数据的函数。本文采用读取adc数据除以20 对应毫秒的闪烁间隔。此时间间隔较为恰当,肉眼可见闪烁频率随电位器的在较大范围内的调整而改变。
图中所示 1 2 对应LED所在位置
为了实现对多核的利用,LED闪烁部分代码运行于CPU core1
对应部分程序:
#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"
#include "Blinky_LED.h"
#include "Bsp.h"
extern IfxCpu_syncEvent g_cpuSyncEvent;
extern uint16 read_adc_result;
int core1_main(void)
{
IfxCpu_enableInterrupts();
/* !!WATCHDOG1 IS DISABLED HERE!!
* Enable the watchdog and service it periodically if it is required
*/
IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
initLED(); /* Initialize the LED port pin */
init_GPIOs();
/* Wait for CPU sync event */
IfxCpu_emitEvent(&g_cpuSyncEvent);
IfxCpu_waitEvent(&g_cpuSyncEvent, 1);
while(1)
{
blinkLED();
waitTime(IfxStm_getTicksFromMilliseconds(BSP_DEFAULT_TIMER, (read_adc_result/20))); /* unit :milliseconds */
}
return (1);
}
3. 数据处理后通过串口输出数据至电脑。
读取结果数据为 uint16 转换为 str 后发送至串口, 使用cpu core0 运行这部分程序。
void send_UART_message2(uint16 x)
{
char buf[4];
int n = sprintf( buf, "%d", x);
Ifx_SizeT count = sizeof(buf); /* Size of the message */
IfxAsclin_Asc_write(&g_asc, buf , &count, TIME_INFINITE); /* Transfer of data */
}
while(1)
{
chn36Measurement = readADCValue(CHN_36);
read_adc_result=chn36Measurement;
send_UART_message();
send_UART_message2(chn36Measurement);
send_UART_message3();
waitTime(IfxStm_getTicksFromMilliseconds(BSP_DEFAULT_TIMER, 100)); /* Wait 500 milliseconds */
}
4. 电脑端读取串口数据并实时绘图。
这部分的功能实现基于VOFA+ , 在符合匹配协议的情况下实时对串口数据进行绘图并显示。
配置格式例子 “ sample: 3000 \n ”
其中需要注意一定是\n 否则无法自动匹配
三、对本活动的心得体会:
感觉回到了本科的夏天,在选修课上用51单片机实现最基本的串口和模拟数据读取功能,也是一样的闷热,也是一样的基础功能的实现。
英飞凌的代码例程足够多,本文结尾附加代码是在范例的基础上进行的修改。