本帖最后由 Alden 于 2024-10-23 15:19 编辑
#申请原创# #技术资源#
APM32F003输入封装只有20pin,看起来是功能很简单的芯片,但外设功能都很全面。比如定时器模块,输入输出、计数、编码器接口模式等,都是支持的。
接下来就在SDK的基础上测试了下定时器的多通道输入捕获。
首先需要对定时器进行初始化,我测试开了TIM2的三个通道同时作输入捕获功能。
void TMR2_Init(void)
{
TMR2_ICConfig_T icConfig;
GPIO_Config_T gpio_struct;
gpio_struct.pin = GPIO_PIN_5;
gpio_struct.speed = GPIO_SPEED_10MHz;
gpio_struct.mode = GPIO_MODE_IN_FLOATING;
gpio_struct.intEn = GPIO_EINT_DISABLE;
GPIO_Config(GPIOC, &gpio_struct);
gpio_struct.pin = GPIO_PIN_2|GPIO_PIN_3;
gpio_struct.speed = GPIO_SPEED_10MHz;
gpio_struct.mode = GPIO_MODE_IN_FLOATING;
gpio_struct.intEn = GPIO_EINT_DISABLE;
GPIO_Config(GPIOD, &gpio_struct);
/* Set counter = 0XFF, divider = 4 */
// TMR2_ConfigTimerBase(47, 500);
/* Set Input Capture Channel */
icConfig.channel = TMR2_CHANNEL_1;
/* Set Input Capture filter */
icConfig.filter = 0;
/* Set Input Capture divider */
icConfig.div = TMR2_IC_DIV_1;
/* Set Input Capture polarity */
icConfig.polarity = TMR2_IC_POLARITY_FALLING;
/* Set Input Capture selection */
icConfig.selection = TMR2_IC_SELECT_DIRECTTI;
TMR2_ConfigInputCapture(&icConfig);
icConfig.channel = TMR2_CHANNEL_2;
/* Set Input Capture filter */
icConfig.filter = 0;
/* Set Input Capture divider */
icConfig.div = TMR2_IC_DIV_1;
/* Set Input Capture polarity */
icConfig.polarity = TMR2_IC_POLARITY_FALLING;
/* Set Input Capture selection */
icConfig.selection = TMR2_IC_SELECT_DIRECTTI;
TMR2_ConfigInputCapture(&icConfig);
icConfig.channel = TMR2_CHANNEL_3;
/* Set Input Capture filter */
icConfig.filter = 0;
/* Set Input Capture divider */
icConfig.div = TMR2_IC_DIV_1;
/* Set Input Capture polarity */
icConfig.polarity = TMR2_IC_POLARITY_FALLING;
/* Set Input Capture selection */
icConfig.selection = TMR2_IC_SELECT_DIRECTTI;
TMR2_ConfigInputCapture(&icConfig);
TMR2_EnableInterrupt(TMR2_INT_UPDATE|TMR2_INT_CH1CC|TMR2_INT_CH2CC|TMR2_INT_CH3CC);
NVIC_EnableIRQRequest(TMR2_UO_IRQn, 0x0f);
NVIC_EnableIRQRequest(TMR2_CC_IRQn, 0x0f);
/* Enable TMR2 */
TMR2_Enable();
}
然后是在定时器 中断服务函数中进行处理。
void TMR2_CC_IRQHandler(void)
{
TMR2_CC_Isr();
}
void TMR2_UO_IRQHandler(void)
{
TMR2_UO_Isr();
}
void TMR2_UO_Isr(void)
{
if(TMR2_ReadStatusFlag(TMR2_FLAG_UPDATE) == SET)
{
overflowCNT_CH1++;
overflowCNT_CH2++;
overflowCNT_CH3++;
TMR2_ClearStatusFlag(TMR2_FLAG_UPDATE);
}
}
void TMR2_CC_Isr(void)
{
if(TMR2_ReadStatusFlag(TMR2_FLAG_CH1CC) == SET)
{
/* Read capture value */
icValue_CH1[icOffset_CH1] = TMR2_ReadCompareCapture(TMR2_CHANNEL_1);
if(icOffset_CH1 == 0)
{
overflowCNT_CH1 = 0;
icOffset_CH1++;
TMR2_ClearStatusFlag(TMR2_FLAG_UPDATE);
}
else
{
/* calculate the LIRC clock frequency */
freqLIRC_CH1 = (clockFreqTMR2) / (icValue_CH1[1] + overflowCNT_CH1 * 65536 - icValue_CH1[0]);
icOffset_CH1 = 0;
}
/* Clear Channel3 Input Capture flag */
TMR2_ClearStatusFlag(TMR2_FLAG_CH2CC);
}
if(TMR2_ReadStatusFlag(TMR2_FLAG_CH2CC) == SET)
{
/* Read capture value */
icValue_CH2[icOffset_CH2] = TMR2_ReadCompareCapture(TMR2_CHANNEL_2);
if(icOffset_CH2 == 0)
{
overflowCNT_CH2 = 0;
icOffset_CH2++;
TMR2_ClearStatusFlag(TMR2_FLAG_UPDATE);
}
else
{
/* calculate the LIRC clock frequency */
freqLIRC_CH2 = (clockFreqTMR2) / (icValue_CH2[1] + overflowCNT_CH2 * 65536 - icValue_CH2[0]);
icOffset_CH2 = 0;
}
/* Clear Channel3 Input Capture flag */
TMR2_ClearStatusFlag(TMR2_FLAG_CH2CC);
}
if(TMR2_ReadStatusFlag(TMR2_FLAG_CH3CC) == SET)
{
/* Read capture value */
icValue_CH3[icOffset_CH3] = TMR2_ReadCompareCapture(TMR2_CHANNEL_3);
if(icOffset_CH3 == 0)
{
overflowCNT_CH3 = 0;
icOffset_CH3++;
TMR2_ClearStatusFlag(TMR2_FLAG_UPDATE);
}
else
{
/* calculate the LIRC clock frequency */
freqLIRC_CH3 = (clockFreqTMR2) / (icValue_CH3[1] + overflowCNT_CH3 * 65536 - icValue_CH3[0]);
icOffset_CH3 = 0;
}
/* Clear Channel3 Input Capture flag */
TMR2_ClearStatusFlag(TMR2_FLAG_CH3CC);
}
}
用TMR2_INT_UPDATE来进行计数,TMR2_INT_CHxCC中断来触发输入的电平变化。计算电平变化间计数是多少。
int main(void)
{
APM_MINI_LEDInit(LED2);
APM_MINI_LEDInit(LED3);
APM_DelayInit(APM_DELAY_MS);
APM_MINI_PBInit(BUTTON_KEY1, BUTTON_MODE_GPIO);
USART_Init();
AFConfig();
TMR2_Init();
/* TMR1 clock = Master clock */
clockFreqTMR2 = RCM_GetMasterClockFreq();
while(1)
{
printf("freqLIRC_CH1=%d freqLIRC_CH2=%d freqLIRC_CH3=%d\r\n", freqLIRC_CH1,freqLIRC_CH2,freqLIRC_CH3);
/* if LIRC clock frequency in [1k ~ 150k]hz */
if((freqLIRC_CH1< 150000) && (freqLIRC_CH1 > 1000))
{
APM_MINI_LEDOn(LED2);
}
else
{
APM_MINI_LEDToggle(LED2);
}
APM_Delay(500);
}
}
然后就能在main中打印结果。
APM32F00x_SDK_V1.4 -INpwm.zip
(8.37 MB)
|