510
个编辑
更改
→STM32L476 定时器捕获简介
==== 遥控器协议说明 ====
[[文件:NBDK-INTER-NEC.jpg|边框|居中|无框|720x720像素]]
''<span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span>''
=== 硬件设计 ===
HAL_NVIC_EnableIRQ(TIM3_IRQn); // 使能TIM3中断
}
</syntaxhighlight>定时器周期中断,自动装载值装满一次,进入一次此回调(本工程是10ms进入一次)。定时器周期中断回调函数,TIM3的自动装载值装满一次,进入一次此回调(本工程配置的参数是10ms进入一次)。 我们判断是否已经接收到引导码(根据引导码标志位判断),一旦接收到引导码,我们认为已经开始了一次NEC数据的接收。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
}
}
</syntaxhighlight>处理TIM3 CH1(PC6引脚)捕获的数据,这边要记得初始化中我们使能了上升沿下降沿都捕获数据。 当有边沿捕获到来,我们判断此时PC6引脚的电平。 如果此时是高电平,则代表刚刚的是上升沿,此时我们使能上升沿标志位,并且清空定时器计数值。 如果此时是低电平,且上升沿标识位被置位,则我们根据获取到的计数值(也就是上一次高电平的持续时间)来判断本段PWM波代表的含义。<syntaxhighlight lang="c++" line="1" start="155">
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(irStatus & IR_STATUS_Rising) // 存在上升沿标记,我们比较定时器计数值
{
if(tim3Val > 260 && tim3Val < 860) // 560us代表低电平,范围560us±300us高电平持续560us代表bit 0,范围560us±300us
{
irRecData <<= 1; // 左移一位
irRecData |= 0; // bit位赋值0
}
else if(tim3Val > 1380 && tim3Val < 1980) // 1680us代表高电平,范围1680us±300us高电平持续1680us代表bit 1,范围1680us±300us
{
irRecData <<= 1; // 左移一位
irRecData |= 1; // bit位赋值1
}
else if(tim3Val > 2200 && tim3Val < 2800) // 2500us代表本次按键结束,范围2500us±300us高电平持续2500us代表本次按键结束,范围2500us±300us
{
irCnt++; // 按键次数新增1
tim3Cnt = 0; // 清除计数值
}
else if(tim3Val > 4200 && tim3Val < 4800) // 4500us代表新的按键,范围4500us±300us高电平持续4500us代表新的按键,范围4500us±300us
{
irStatus |= IR_STATUS_BootCode; // 标记引导码
}
}
</syntaxhighlight>轮询当前的按键信息。如果按键值标识存在,则代表有按键被按下,接着判断地址码以及数据数据正确,并将最终的按键数据添加到irinfo中留给应用层调用。<syntaxhighlight lang="c++" line="1" start="206">
irInfo_t IRBNT_POLL(void)
{
if(irStatus & IR_STATUS_BtnInfo) // 如果获取到按键值
{
bcode = irRecData >> 24; // 引导码地址码 dcode = (irRecData >> 16) & 0xff; // 引导码反编码地址码反编码
if((bcode == (uint8_t)~dcode) && bcode == REMOTE_DEVICE_ID) // 判断引导码是否正确判断地址码是否正确
{
bvalue = irRecData >> 8; // 按键值