Funpack2-2项目总结报告
1.板卡介绍
硬禾学堂官方介绍
TC275TP作为第一代 Aurix TC27xT系列产品,专为满足极高的安全标准,同时大幅提高性能而设计。采用创新多核心架构,三个独立的 32 位 TriCore CPU均可工作在200 MHz。可选择多种开发环境,包括Hightec/PLS/Infineon 的基于Eclipse的FreeEntryToolchain,或来自英飞凌基于Eslipse的免费IDE AURIX™ Development Studio,亦或是更多开发工具。
特性:
· 搭载了基于AURIX™ TriCore™ 单片三核微控制器TC275
· 板载Micro USB接口的miniWiggler调试器
· 两个Infineon Shield2Go扩展接口
· 兼容MikroBUS 和Arduino扩展连接
· 带有Infineon新一代CAN 收发器TLE9251VSJ ,可用于汽车和工业应用的HS CAN网络开发
· 已焊接可调旋转电位计,用于评估模拟电压的采集
· 一个用户输入按键
· 预留三个LED可作为工作指示灯
板卡图片:
2.设计思路及关键代码
本次做的是任务二,通过旋转板卡上的电位计,改变呼吸灯闪烁速率,并将ADC数据显示在电脑上。对项目需求进行分析,需要控制的部分分为一下几个模块。
- ADC数据采集
- PWM波形生成
- 串口发送
得益于TC275的丰富例程,使得以上几个模块的控制变得较为容易。
首先是ADC数据的采集,代码主要参考ADC_Single_Channel_1_KIT_TC275_LK
例程。ADC数据的采集分为以下几个步骤
- 确定电位器所在的通道及所在组
- 模块初始化
- 组初始化
- 通道初始化
- 最后循环采样,获取寄存器的值
由于tc275的adc初始化比较固定,只需要配置最后一个通道即可,这里主要参考了ADC_Single_Channel_1_KIT_TC275_LK的代码
初始化adc部分代码
void init_vadc(void)
{
/* Create and initialize the module configuration */
IfxVadc_Adc_Config adcConf; /* Define a configuration structure for the VADC module */
IfxVadc_Adc_initModuleConfig(&adcConf, &MODULE_VADC); /* Fill it with default values */
IfxVadc_Adc_initModule(&g_vadc, &adcConf); /* Apply the configuration to the module */
/* Create and initialize the group configuration */
IfxVadc_Adc_GroupConfig adcGroupConf; /* Define a configuration structure for the VADC group */
IfxVadc_Adc_initGroupConfig(&adcGroupConf, &g_vadc); /* Fill it with default values */
/* Configuration of the group */
adcGroupConf.groupId = IfxVadc_GroupId_0; /* Select the group */
adcGroupConf.master = adcGroupConf.groupId; /* Select the master group */
adcGroupConf.arbiter.requestSlotScanEnabled = TRUE; /* Enable scan source */
adcGroupConf.scanRequest.autoscanEnabled = TRUE; /* Enable auto scan mode */
/* Enable all gates in "always" mode (no edge detection) */
adcGroupConf.scanRequest.triggerConfig.gatingMode = IfxVadc_GatingMode_always;
IfxVadc_Adc_initGroup(&g_adcGroup, &adcGroupConf); /* Apply the configuration to the group */
/* Create and initialize the channels configuration */
uint32 chnIx;
/* Create channel configuration */
IfxVadc_Adc_ChannelConfig adcChannelConf[N_CHANNELS]; /* Define a configuration structure for the VADC channels */
for(chnIx = 0; chnIx < N_CHANNELS; ++chnIx)
{
IfxVadc_Adc_initChannelConfig(&adcChannelConf[chnIx], &g_adcGroup); /* Fill it with default values */
adcChannelConf[chnIx].channelId = g_vadcChannelIDs[chnIx]; /* Select the channel ID */
adcChannelConf[chnIx].resultRegister = (IfxVadc_ChannelResult)(chnIx); /* Use dedicated result register */
/* Initialize the channel */
IfxVadc_Adc_initChannel(&g_adcChannel[chnIx], &adcChannelConf[chnIx]);
/* Add the channel to the scan sequence */
uint32 enableChnBit = (1 << adcChannelConf[chnIx].channelId); /* Set the the corresponding input channel */
uint32 mask = enableChnBit; /* of the respective group to take part in */
IfxVadc_Adc_setScan(&g_adcGroup, enableChnBit, mask); /* the background scan sequence. */
}
/* Start the scan */
IfxVadc_Adc_startScan(&g_adcGroup);
adc的运行部分代码
void run_vadc(void)
{
uint32 chnIx;
/* Get the VADC conversions */
for(chnIx = 0; chnIx < N_CHANNELS; ++chnIx)
{
Ifx_VADC_RES conversionResult;
/* Wait for a new valid result */
do
{
conversionResult = IfxVadc_Adc_getResult(&g_adcChannel[chnIx]);
} while(!conversionResult.B.VF); /* B for Bitfield access, VF for Valid Flag */
/* Print the conversion to the UART */
send_vadc(chnIx, conversionResult.B.RESULT);
}
}
其次是pwm波形的形成,PWM输出使用了GTM,也就是通用定时器的PWM模式输出。代码主要参考GTM_TOM_PWM_1_KIT_TC275_LK。
IfxGtm_Tom_Pwm_Config g_tomConfig;
IfxGtm_Tom_Pwm_Driver g_tomDriver;
void PWM_Init(void) {
IfxGtm_enable(&MODULE_GTM); /* Enable GTM */
IfxGtm_Cmu_enableClocks(&MODULE_GTM, IFXGTM_CMU_CLKEN_FXCLK); /* Enable the FXU clock */
/* Initialize the configuration structure with default parameters */
IfxGtm_Tom_Pwm_initConfig(&g_tomConfig, &MODULE_GTM);
g_tomConfig.tom = LED.tom; /* Select the TOM depending on the LED */
g_tomConfig.tomChannel = LED.channel; /* Select the channel depending on the LED */
g_tomConfig.period = PWM_PERIOD; /* Set the timer period */
g_tomConfig.pin.outputPin = &LED; /* Set the LED port pin as output */
g_tomConfig.synchronousUpdateEnabled = TRUE; /* Enable synchronous update */
IfxGtm_Tom_Pwm_init(&g_tomDriver, &g_tomConfig); /* Initialize the GTM TOM */
IfxGtm_Tom_Pwm_start(&g_tomDriver, TRUE);
}
// duty should be between 0 and 100
void PWM_SetDuty(uint8_t dutyCycle) {
g_tomConfig.dutyCycle = dutyCycle * PWM_PERIOD / 100; /* Change the value of the duty cycle */
IfxGtm_Tom_Pwm_init(&g_tomDriver, &g_tomConfig); /* Re-initialize the PWM */
}
然后是uart数据的发送,这个是主要参考了ASCLIN_UART_1_KIT_TC275_LK例程。
/* This function initializes the ASCLIN UART module */
void Uart_Init(void) {
/* 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 = 115200;
/* 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 = {
.rx = &UART_PIN_RX,
.rxMode = IfxPort_InputMode_noPullDevice,
.tx = &UART_PIN_TX,
.txMode = IfxPort_OutputMode_pushPull,
.cts = NULL_PTR,
.ctsMode = IfxPort_InputMode_noPullDevice,
.rts = NULL_PTR,
.rtsMode = IfxPort_OutputMode_pushPull,
.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1
};
ascConfig.pins = &pins;
IfxAsclin_Asc_initModule(&g_ascHandle, &ascConfig); /* Initialize module with above parameters */
}
void Uart_SendStr(char* str) {
Ifx_SizeT len = (Ifx_SizeT)strlen(str);
IfxAsclin_Asc_write(&g_ascHandle, str, &len, TIME_INFINITE); /* Transmit data via TX */
}
最后就是将他们组合到一起,实现基本功能
while(1) {
// adc value should be between 0 and 4095
// 基准时间:adc_val = 2048, 呼吸灯周期2s,每个占空比延时10ms
// 最短周期:adc_val = 0, 呼吸灯周期0.5s,每个占空比延时2.5ms
// 最长周期:adc_val = 4095,呼吸灯周期8s,每个占空比延时40ms
// 每个占空比延时t = 2.5 + adc_val
// 500ms上报ADC数值
for (uint8_t i = 0; i < 100; i++) {
PWM_SetDuty(i);
adc_val = Adc_GetValue();
delay = 2.5 * pow(2, adc_val / 1024.0);
Timer_Delayms(delay);
send_count += delay;
if (send_count >= 500) {
send_count -= 500;
sprintf(ch, "adc_val:%d\r\n", (int)adc_val);
Uart_SendStr(ch);
}
}
for (uint8_t i = 100; i > 0; i--) {
PWM_SetDuty(i);
delay = 2.5 * pow(2, adc_val / 1024.0);
Timer_Delayms(delay);
send_count += delay;
if (send_count >= 500) {
send_count -= 500;
sprintf(ch, "adc_val:%d\r\n", (int)adc_val);
Uart_SendStr(ch);
}
}
}
3.图片展示
4.活动总结
感谢硬禾学堂提供的这次机会,能够学到很多关于英飞凌板卡的应用,板卡具有三个核心,例程丰富,可以较快的完成开发。