更改

跳转至: 导航搜索

NBDK-L4:基础实验教程

添加1,046字节2019年1月24日 (四) 15:11
STM32L476 定时器捕获简介
==== 遥控器协议说明 ====
NEC 协议,其特征如下:遥控器使用的协议,被称为NEC码,NEC的编码方式如下所示,这个部分大家需要理解清楚,方便后续代码的阅读。
1、 8 位地址和 8 位指令长度;NEC码高低电平位定义如下:
2、地址和命令 一个逻辑 0 的传输需要 1.125ms(560us 脉冲+560us 低电平),一个逻辑 1 传输需要 2 次传输(确保可靠性).25ms(560us脉冲+1680us 低电平)。[[文件:NBDK-INTER-NEC1.jpg|边框|居中|无框|625x625像素]]
3、 PWM 脉冲位置调制,以发射红外载波的占空比代表“0”和“1”;NEC数据格式为:
4、载波频率为 38Khz;引导码、用户地址码、用户地址反码、数据码、数据反码。
5、位时间为 1引导码由一个 9ms 的低电平和一个 4.125ms 或 2.25ms; 5ms 的高电平组成,用户地址码、用户地址反码、数据码、数据反码均是8 位数据格式。  
NEC 码的位定义: 一个脉冲对应 560us 的连续载波,一个逻辑 1 传输需要 2.25ms(560us脉冲+1680us 低电平),一个逻辑 0 的传输需要 1.125ms(560us 脉冲+560us 低电平)。 NEC 遥控指令的数据格式为: 同步码头、地址码、地址反码、控制码、控制反码。同步码由一个 9ms 的低电平和一个 4.5ms 的高电平组成,地址码、地址反码、控制码、控制反码均是8 位数据格式。按照低位在前,高位在后的顺序发送。采用反码是为了增加传输的可靠性(可用于校验)。  当按键被持续按下时,每隔108ms重新发送一次此数据,所以我们可以利用计时超过108ms的方式,来计算按键持续按下的次数(代码中是判断的110ms)。
[[文件:NBDK-INTER-NEC.jpg|边框|居中|无框|720x720像素]]
从图 26.1.1 中可以看到,其地址码为 0,控制码为 168。可以看到在 100ms 之后,我们还收到了几个脉冲,这是 NEC 码规定的连发码(由 9ms 低电平+2.5m 高电平+0.56ms 低电平
 
+97.94ms 高电平组成),如果在一帧数据发送完毕之后,按键仍然没有放开,则发射重复码,
 
即连发码,可以通过统计连发码的次数来标记按键按下的长短/次数。 
''<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数据的接收。
我们判断接收到引导码,如果是接收到引导码之后,第一次进入此函数,那么我们使能记录遥控器按键值的标志位,也就是代表接收到了一次NEC数据(不管数据对错)。 如果进入的次数少于11次,则继续增加计数,当计数值等于11时(也就是从接收到引导码已经过去至少110ms时),我们认为一次NEC的数据获取已经完成,此时清除周期回调的计数值,并且删除引导码标志位(下次再进到这个函数时,只有新的引导码数据到来,才会进行新的数据处理)。<syntaxhighlight lang="c++" line="1" start="122">
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; // 按键值
510
个编辑

本PDF由谷雨文档中心自动生成,点击下方链接阅读最新内容。

取自“http://doc.iotxx.com/特殊:移动版差异/1381

导航菜单