一、项目介绍:
这一期的板卡是英飞凌的TC275 Lite Kit 开发板,主控芯片是一块三核 32 位单片机。配合官方开发工具AURIX TM Development Studio能快速实现想要的功能。
本次活动我选择的题目是任务二:设计一个呼吸灯,通过旋转板卡上的电位计,改变呼吸灯闪烁速率。同时将ADC采集的数据通过串口发送到PC端显示。
二、实现思路和主要功能代码片段
题目涉及到呼吸灯,电位器,数据传输三个方面,对应到单片机的功能模块就是GPIO,ADC,UART。因为单片机具有三个核,所以可以随心所欲的堆代码,几乎不用考虑时序和逻辑,每个核实现一个功能是最方便的。
1.呼吸灯:
呼吸灯的实现是用简单的延时来做的,调节占空比的递增,递减就可以实现亮度渐变效果,最后通过调整延时步进长度来控制闪烁频率;步长参数由电位器AD值确定。
1.1LED灯GPIO初始化代码:
void initLED(void)
{
/* Initialization of the LED used in this example */
IfxPort_setPinModeOutput(LED, IfxPort_OutputMode_pushPull, IfxPort_OutputIdx_general);
/* Switch OFF the LED */
IfxPort_setPinHigh(LED);
}
1.2呼吸灯的实现代码:
void breath(uint16 speed) //speed 控制闪烁频率
{
uint16 i;
for(i=0;i<200;i++) //逐渐变亮
{
IfxPort_setPinLow(LED); //点亮led
delay_ms(speed,i); //占空比递增
IfxPort_setPinHigh(LED);
delay_ms(speed,200-i);
}
for(i=0;i<200;i++) //逐渐变暗
{
IfxPort_setPinHigh(LED); //熄灭led
delay_ms(speed,i); //占空比递增
IfxPort_setPinLow(LED);
delay_ms(speed,200-i);
}
}
2.读取电位器AD值
电位器需要用到单片机的ADC功能,经查原理图中电位器对应ADC通道为0;结合官方例程,调整ADC初始化代码中的组和通道就可以进行读取到电位器的AD值操作了。
ADC初始化代码:
/*********************************************************************************************************************/
/*---------------------------------------------Function Implementations----------------------------------------------*/
/*********************************************************************************************************************/
/* Function to initialize the VADC module */
void initADC(void)
{
initVADCModule(); /* Initialize the VADC module */
initVADCGroup(); /* Initialize the VADC group */
initVADCChannels(); /* Initialize the used channels */
/* Start the scan */
IfxVadc_Adc_startBackgroundScan(&g_vadc);
}
/* Function to initialize the VADC module with default parameters */
void initVADCModule(void)
{
IfxVadc_Adc_Config adcConf; /* Define a configuration structure */
IfxVadc_Adc_initModuleConfig(&adcConf, &MODULE_VADC); /* Fill it with default values */
IfxVadc_Adc_initModule(&g_vadc, &adcConf); /* Apply the configuration */
}
/* 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 4 */
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 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. */
}
}
3.串口通讯的实现:
相对于51单片机,STM32单片机的串口初始化来说,AURIX development studio初始化有点费劲。既然已经包含了stdio.h文件,但是不能直接printf("{plot: %d}",AN0_result)。输出数值一直是0;后来发先是缺失了部分头文件导致的。
串口初始化代码:
#define SERIAL_BAUDRATE0 115200
#define SERIAL_PIN_RX0 IfxAsclin0_RXA_P14_1_IN
#define SERIAL_PIN_TX0 IfxAsclin0_TX_P14_0_OUT
#define INTPRIO_ASCLIN0_TX 19 /* Priority of the ISR */
#define ASC_TX_BUFFER_SIZE 64
/* Initialize an instance of IfxAsclin_Asc_Config with default values */
IfxAsclin_Asc_Config ascConfig;
IfxAsclin_Asc_initModuleConfig(&ascConfig, SERIAL_PIN_TX0.module);
/* Set the desired baud rate */
ascConfig.baudrate.baudrate = SERIAL_BAUDRATE0;
/* ISR priorities and interrupt target */
ascConfig.interrupt.txPriority = INTPRIO_ASCLIN0_TX;
ascConfig.interrupt.typeOfService = IfxCpu_Irq_getTos(IfxCpu_getCoreIndex());
/* FIFO configuration */
ascConfig.txBuffer = &g_ascTxBuffer;
ascConfig.txBufferSize = ASC_TX_BUFFER_SIZE;
/* Port pins configuration */
const IfxAsclin_Asc_Pins pins =
{
NULL_PTR, IfxPort_InputMode_pullUp, /* CTS pin not used */
&SERIAL_PIN_RX0, IfxPort_InputMode_pullUp, /* RX pin not used */
NULL_PTR, IfxPort_OutputMode_pushPull, /* RTS pin not used */
&SERIAL_PIN_TX0, IfxPort_OutputMode_pushPull, /* TX pin */
IfxPort_PadDriver_cmosAutomotiveSpeed1
};
ascConfig.pins = &pins;
/* Initialize module with above parameters */
IfxAsclin_Asc_initModule(&g_asc0, &ascConfig);
/* Initialize the Standard Interface */
IfxAsclin_Asc_stdIfDPipeInit(&g_ascStandardInterface, &g_asc0);
/* Initialize the Console */
Ifx_Console_init(&g_ascStandardInterface);
三、功能展示:
下图为调整电位器位置后,呼吸闪烁频率变慢效果。简单介绍一下右上角的纸飞机串口助手,按照串口助手的命令格式输出数据可以将变化曲线打印出来,值得一提的是他的通讯速率可以支持到1Mhz,非常稳定。
四、心得体会
1.熟悉了英飞凌单片机的官方调试软件AURIX development studio;
2.了解了串口打印的使用方法;
3.多核芯片就是方便,轻松解决时序问题。