· 项目描述
- 项目框架
此次项目整体框架图如下:
1.通过ADC0 采集TC275 LK 上面的旋钮电平,并进行低通滤波
2.将滤波后的采样数据转换成电平数据,通过串口发给pc显示,pc 使用vofa+ 进行数据显示和波形显示
3.将低通滤波后的ADC 数据传给PWM 模块,并将此数据设置为PWM周期,从而达到控制闪烁频率的功能。
- 环境搭建
此次项目使用的IDE 是ADS ,参考这里进行环境安装,不得不吐槽下下载是真的慢呀,这里在CSDN传了一份1.7.2版本的,方便后面大家安装使用。
软件使用基本跟eclipse一致,上手很快的。板子自带仿真器,下载器,使用比较方便,一根usb线解决(mico usb 感觉要退出历史舞台了哈哈).
- iLLD 学习
iLLD 是英飞凌开放的开发功能库,和ST Hal库类似,直播时老师讲的很通透,每个例程都配套的dpf 例程讲解,学习起来比较方便。针对此次任务二,主要学习了点灯例程(熟悉基础GPIO配置,delay 设置)、异步串口例程(串口初始化、串口数据发送、接收) PWM ATOM例程(pwm 功能配置,呼吸灯控制逻辑)、ADC 例程( 背景ADC 值采集实现)。整合以上实例后,然后按项目框架进行更改代码、调试。
- 功能实现
查阅开发板手册,确认旋钮使用的AN0
设置ADC group 0,通道0
uart 使用的是p15.3 收发使用同一个管脚,此任务中,只需TC275 发送数据给PC
LED 使用的是P00.5,pwm atom指向此管脚,实现呼吸灯功能
pwm 实现原理
cnt2 为呼吸计数值,当cnt2 大于T(PWM周期时),cnt2开始逐渐减少;
当cnt2 小于0时,cnt2 逐渐增加;
cnt1 为循环计数值
当cnt2 小于cnt1 时,led 输出高电平,反之,输出低电平。
此次任务相同与调整T的值,cnt2的自加 自减值 x不用改变,并且保证T要大于x.
· 各功能对应的主要代码片段及说明
- ADC采集
初始化 VADC 时选用AN0所在的group 0
IfxVadc_Adc_GroupConfig adcGroupConf; /* Define a configuration structure */
IfxVadc_Adc_initGroupConfig(&adcGroupConf, &g_vadc); /* Fill it with default values */
#if 0
adcGroupConf.groupId = IfxVadc_GroupId_4;
#else
adcGroupConf.groupId = IfxVadc_GroupId_0;
#endif
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 */
并且配置为通道0
/* 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 4..7 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. */
主循环中,每隔20ms 获取ADC值,并通过一阶低通滤波器进行滤波
//get adc data ,and use 1st lowpass filter
adc_data = readADCValue(0);
filter_data = adc_data*filter_params +filter_params1*filter_stat;
filter_stat = filter_data;
2.串口初始化及使用
设定串口波特率115200 8N 1
UART GPIO 接口配置
指定FIFO 接口
指定TX RX GPIO管脚
/* Initialize an instance of IfxAsclin_Asc_Config with default values */
IfxAsclin_Asc_Config ascConfig;
IfxAsclin_Asc_initModuleConfig(&ascConfig, &MODULE_ASCLIN0);
/* Set the desired baud rate */
ascConfig.baudrate.baudrate = UART_BAUDRATE;
/* ISR priorities and interrupt target */
ascConfig.interrupt.txPriority = INTPRIO_ASCLIN0_TX;
ascConfig.interrupt.rxPriority = INTPRIO_ASCLIN0_RX;
ascConfig.interrupt.typeOfService = IfxCpu_Irq_getTos(IfxCpu_getCoreIndex());
/* FIFO configuration */
ascConfig.txBuffer = &g_ascTxBuffer;
ascConfig.txBufferSize = UART_TX_BUFFER_SIZE;
ascConfig.rxBuffer = &g_ascRxBuffer;
ascConfig.rxBufferSize = UART_RX_BUFFER_SIZE;
/* Pin configuration */
const IfxAsclin_Asc_Pins pins =
{
NULL_PTR, IfxPort_InputMode_pullUp, /* CTS pin not used */
&UART_PIN_RX, IfxPort_InputMode_pullUp, /* RX pin */
NULL_PTR, IfxPort_OutputMode_pushPull, /* RTS pin not used */
&UART_PIN_TX, IfxPort_OutputMode_pushPull, /* TX pin */
IfxPort_PadDriver_cmosAutomotiveSpeed1
};
ascConfig.pins = &pins;
IfxAsclin_Asc_initModule(&g_ascHandle, &ascConfig); /* Initialize module with above parameters */
串口发送
Ifx_SizeT send_len =0;
void send_uart_data(uint8_t *data,uint8_t len)
{
send_len = len;
IfxAsclin_Asc_write(&g_ascHandle, data, &send_len, TIME_INFINITE);
}
3.pwm 配置
指定atom gpio 管脚,指定pwm 周期
void initGtmATomPwm(void)
{
IfxGtm_enable(&MODULE_GTM); /* Enable GTM */
IfxGtm_Cmu_setClkFrequency(&MODULE_GTM, IfxGtm_Cmu_Clk_0, CLK_FREQ); /* Set the CMU clock 0 frequency */
IfxGtm_Cmu_enableClocks(&MODULE_GTM, IFXGTM_CMU_CLKEN_CLK0); /* Enable the CMU clock 0 */
IfxGtm_Atom_Pwm_initConfig(&g_atomConfig, &MODULE_GTM); /* Initialize default parameters */
g_atomConfig.atom = LED.atom; /* Select the ATOM depending on the LED */
g_atomConfig.atomChannel = LED.channel; /* Select the channel depending on the LED */
g_atomConfig.period = PWM_period; /* Set timer period */
g_atomConfig.pin.outputPin = &LED; /* Set LED as output */
g_atomConfig.synchronousUpdateEnabled = TRUE; /* Enable synchronous update */
IfxGtm_Atom_Pwm_init(&g_atomDriver, &g_atomConfig); /* Initialize the PWM */
IfxGtm_Atom_Pwm_start(&g_atomDriver, TRUE); /* Start the PWM */
}
更新周期值,更新计算值,这个在更新周期值时要注意不能小于step值,并且周期值无变换时,不用进行更新,只用更新cnt2的值
void fadeLED(uint16_t cycle)
{
if(cycle<100)
{
cycle = 100;
}
uint16_t calc_data = cycle - cycle%50;
if(calc_data!=PWM_period)
{
PWM_period = calc_data;
g_atomConfig.period = PWM_period;
}
if(g_fadeValue >= PWM_period)
{
g_fadeDir = -1; /* Set the direction of the fade */
}
else if(g_fadeValue <= 0)
{
g_fadeDir = 1; /* Set the direction of the fade */
}
g_fadeValue += g_fadeDir * PWM_STEP; /* Calculation of the new duty cycle */
setDutyCycle(g_fadeValue); /* Call the function which is setting the duty cycle of the PWM */
}
4.主循环控制
获得低通滤波的ADC 值后,传给fadeLED 更新计算值及周期值
获得低通滤波的ADC值后,转换成电平值,使用vofa+ justfloat 格式通过串口发送给PC
fadeLED(filter_data);
data = (float)filter_data*3.3f/4096;
send_uart_data((uint8*)&data,4);
send_uart_data(&uartdata[0],4);
waitTime(ticksFor10ms);
· 功能展示及说明
usb用于供电及调试
uart通过杜邦线连接uart转usb模块连接到PC
通过改锥修改ADC 输入值
观察LED1 的闪烁频率
PC 上观察ADC0的电平变化值及曲线
· 对本活动的心得体会(包括意见或建议)
提高funpack 频次,提供大家交流学习机会