用STM32CubeMx配置定时器

发布者:SereneNature7最新更新时间:2024-04-18 来源: elecfans关键字:STM32CubeMx  配置  定时器 手机看文章 扫描二维码
随时随地手机看文章

1.NEC协议

红外遥控是一种比较常用的通讯方式,目前红外遥控的编码方式中,应用比较广泛的是NEC协议。

NEC协议的特点如下:

1)载波频率为 38KHz

2)8位地址和 8位指令长度

3)地址和命令2次传输(确保可靠性)

4)PWM 脉冲位置调制,以发射红外载波的占空比代表“0”和“1” 其逻辑1与逻辑0的表示如图所示:

c6375f78-ad47-11ed-bfe3-dac502259ad0.png

可以看到,逻辑1的位时间为2.25ms,脉冲时间560us;逻辑0的位时间为1.12ms,脉冲时间560us。

一个完整的NEC数据包如下:

c65f5bd6-ad47-11ed-bfe3-dac502259ad0.png

首次发送的是9ms高电平+4.5ms低电平,为引导码。

接下来是8bit的地址码+8bit地址码的反码+8bit命令码+8bit命令码的反码。

以上是一个正常的数据包,但可能存在一种情况:当长按某个键时,发送的是以110ms为周期的重复码,如下图:

c67cf09c-ad47-11ed-bfe3-dac502259ad0.png

重复码由9ms高电平和2.25ms的低电平以及560us的高电平组成。

2.解码程序


在上面的图中可以看到,逻辑1和逻辑0的位时间是不同的,占空比也不同。

所以我们可以根据位时间的长短来解码,也可以根据占空比的不同(1/2或1/4)来解码,或者二者同时作为解码条件。这

里我们介绍根据位时间来解码。 需要注意的是,很多红外一体接收头为了提高接受灵敏度。

输入高电平,其输出的是相反的低电平。

下图为示波器实际捕获的一组数据:

c69fcd6a-ad47-11ed-bfe3-dac502259ad0.png

可以看到,空闲时为高电平,引导码为9ms低电平+4.5ms高电平。根据位时间解码的话,我们就不必关系高低电平各自的时间,只需关系总时间就行,即:引导码为13.5ms,逻辑1为2.25ms,逻辑0为1.12ms。 首先用STM32CubeMx配置定时器。

系统时钟等的配置这里不在赘述,参考其它教程。

这里使用TIM3的Channel1作为捕获通道配置如下:

c6c2bce4-ad47-11ed-bfe3-dac502259ad0.png

1)定时器时钟为内部时钟

2)Channel1配置为输入捕获模式

3)分频系数为63,因为系统时钟为64M,这样定时器实际时钟为64/(63+1)=1M,主要是为了程序中方便计算。

4)捕获方式为下降沿捕获

5)最后别忘了打开定时器的中断

c7009f00-ad47-11ed-bfe3-dac502259ad0.png

最后生成代码。


在生成的TIM3中断函数中,屏蔽生成的中断处理还是,添加自己的解码程序如下:


uint32_t TIM3_Over_Cnt = 0;//tim3溢出次数

uint32_t TIM3_Sum_Cnt = 0;//两次下降沿之间的时间间隔

uint32_t cnt0 = 0;

uint8_t IR_Data[60];



void TIM3_IRQHandler(void)

{

  /* USER CODE BEGIN TIM3_IRQn 0 */



  /* USER CODE END TIM3_IRQn 0 */

//  HAL_TIM_IRQHandler(&htim3);

  /* USER CODE BEGIN TIM3_IRQn 1 */

    if(__HAL_TIM_GET_FLAG(&htim3, TIM_FLAG_UPDATE))      //定时器溢出中断

    {

        __HAL_TIM_CLEAR_FLAG(&htim3, TIM_FLAG_UPDATE);    //清除中断标记

        TIM3_Over_Cnt++;

    }

    cnt0 = __HAL_TIM_GET_COUNTER(&htim3);

    TIM3_Sum_Cnt = (TIM3_Over_Cnt << 16) + cnt0;//获取计数器的值

    __HAL_TIM_SetCounter(&htim3,0);//清零重新计数

    TIM3_Over_Cnt = 0;//清零重新计数



    if (__HAL_TIM_GET_FLAG(&htim3, TIM_FLAG_CC1) != RESET)//TIM3CH1捕获中断

    {

       if(StartRevFlag == 1)//接收到引导码,开始解码

       {

         if(TIM3_Sum_Cnt > 36000)//大于36ms认为是结束

         {

           RevComplete = 1;//解码完成

           IR_Tick = 0;

         }

         else if(RevComplete == 0)

         {

           if(TIM3_Sum_Cnt > 1000 && TIM3_Sum_Cnt < 1300)//1ms~1.3ms认为是低电平

            IR_Data[IR_Idx] = 0;

           else  if(TIM3_Sum_Cnt > 2100 && TIM3_Sum_Cnt < 2400)//2.1ms~2.4ms认为是高电平

            IR_Data[IR_Idx] = 1;

           else //接收错误,重新开始

             StartRevFlag = 0;

           IR_Idx++;

           if(IR_Idx > 59)

             IR_Idx = 59;

        }



       }

       else

       {

         if(TIM3_Sum_Cnt > 13000 && TIM3_Sum_Cnt < 14000)//13~14ms引导码

         {

           StartRevFlag = 1;

         }

         IR_Tick = 0;

         RevComplete = 0;//解码完成标志置零

         IR_Idx = 0;//有效解码位

         TIM3_Over_Cnt = 0;

         TIM3_Sum_Cnt = 0;//定时器计数清零

       }

        __HAL_TIM_CLEAR_IT(&htim3, TIM_IT_CC1);

    }



  /* USER CODE END TIM3_IRQn 1 */

}

解码程序根据每次捕获下降沿之间的间隔判断是引导码还是逻辑1或逻辑0。


接收到引导码之后,再开始将解码的数据保存下来。


最后通过也是时长来判断解码结束。


这里没有判断重复码,有兴趣的小伙伴可以自己加上。


中断函数中,只是将每一位解码并保存,最后还需要在主程序中组合成字节并判断处理。

void IR_Rev()

{

  uint8_t num = IR_Idx / 8;

  uint8_t IRValue[8];



  if(RevComplete == 1 && StartRevFlag == 1 && IR_Tick > 20)

  {

    if(num > 7)

      num = 7;



    for(uint8_t j=0;j>1;

        if(IR_Data[j*8+i])

          IRValue[j] |= 0x80;

      }

    }

    if(IRValue[0] == 0x00 && IRValue[1] == 0xFF)//地址码正确

    {

switch(IRValue[2])//判断数据码

      {

        case 0x46:

          KeyValue = S_key_Menu;

          break;

        case 0x43:

          KeyValue = S_key_Set;

          break;

        case 0x40:

          KeyValue = S_key_Rst;

          break;

        case 0x15:

          KeyValue = S_key_Down;

          break;

        case 0x09:

          KeyValue = S_key_Up;

break;

      }

    }

    StartRevFlag = 0;

    RevComplete = 0;

    IR_Tick = 0;

  }

}


关键字:STM32CubeMx  配置  定时器 引用地址:用STM32CubeMx配置定时器

上一篇:STM32入门学习笔记之电容触摸实验(下)
下一篇:【STM32】并、串行通信的区别 串行通信的分类

推荐阅读最新更新时间:2024-11-18 14:22

电动汽车充电桩检定装置方案配置
随着《NBT10901-2021电动汽车充电设备现场检验技术规范》、《NBT-10613-2021电动汽车充换电站电能质量测试评价技术规范》、《NBT 33008.1~33008.2-2018电动汽车充电设备检测试验规范》、《JJG1148-2022电动汽车交流充电桩检定规程》《JJG1149-2022电动汽车非车载充电机检定规程》等标准的发布,充电设施的现场检测越来越受重视,部分省份已经率先展开充电桩的检测工作,包含安全、性能、电能质量、效率、互联互通等方面的检测。 针对以上充电桩检测现状,推出了针对现场检测的XL-942S非车载充电桩现场综合测试仪及XL-943S交流充电桩现场综合测试仪。仪器内置了车辆接口模拟器,现场校验
[嵌入式]
电动汽车充电桩检定装置方案<font color='red'>配置</font>
stm32 定时器 通用定时器
STM32F10xxx 2个基本定时器(TIM6、TIM7) 4个通用定时器(TIM2、 TIM3、 TIM4和TIM5) 2个高级定时器(TIM1、TIM8) 每个定时器都是完全独立的,没有互相共享任何资源。它们可以一起同步操作 TIMx主要功能 16位向上、向下、向上/向下自动装载计数器 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536之间的任意 数值 4个独立通道: ─ 输入捕获 ─ 输出比较 ─ PWM生成(边缘或中间对齐模式) ─ 单脉冲模式输出 使用外部信号控制定时器和定时器互连的同步电路 如下事件发生时产生中断/DMA: ─ 更新:计数器
[单片机]
STM32F03定时器基础知识基本简介
一、思维导图 三、定时器基本简介 (一)定时器分类 STM32F103微控制器的定时器分为 系统定时器(SysTick) 、 “看门狗”定时器(WatchDog) 、 基本定时器 、 通用定时器 、高级定时器和 实时时钟(RTC) 等。 系统定时器(SysTick) :是一个集成在Cortex-M3内核当中的定时器,Cortex-M3内核附带SysTick的主要目的是 给实时操作系统(RTOS)提供时间基准(时钟节拍 ),SysTick是不允许被用户直接使用的。 “看门狗”定时器(WatchDog) :“看门狗”定时器连接到STM32微控制器芯片的复位电路, 在定时器溢出时会触发复位操作 。 实时时钟RTC :是一个带独
[单片机]
STM32F03<font color='red'>定时器</font>基础知识基本简介
stm32f407如何配置外部中断
这几天又重新学了stm32f4,遇到了一个外部配置的实验,实验内容仅作简单的外部中断,读者只要搞懂其中的原理,稍微复杂的中断就能很好解决。 实验内容:按键KEY0按下,触发外部中断,中断函数点亮LED0 现将实验笔记做一个分享。 外部中断需要如下几步(此处我们以正点原子探索者开发板为例) 1)初始化LED灯,按键的GPIO 2)配置NVIC 3)将按键 GPIO 连接到 EXTI 源输入 4)配置按键 EXTI 中断/事件线 5) 编写 EXTI 中断服务函数 正点原子KEY0对应IO口为PE4,LED0对应IO口为PF9. 1)初始化LED灯,按键的GPIO RCC_AHB1PeriphClockCmd(RCC_AHB1
[单片机]
STM32CubeMX按键输入
1、新建工程 2、选择目标芯片 3、设置按键和LED引脚 4、配置时钟树 5、配置引脚功能 6、配置生成的代码和选择编译工具 7、打开生成的工程,编译 8、添加下面的代码 /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if(!HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin)){ //读取KEY按键引脚,低电平表示按下 HAL_GPIO_TogglePin(LE
[单片机]
<font color='red'>STM32CubeMX</font>按键输入
ATmega8 定时器/计时器振荡器
对于拥有定时器/ 振荡器引脚(TOSC1 和TOSC2) 的AVR 微处理器,晶体可以直接与这 两个引脚连接,无需外部电容。此振荡器针对32.768 kHz 的钟表晶体作了优化。不建议 在TOSC1 引脚输入振荡信号。
[单片机]
配置20MP镜头 三星GALAXY S7跑分曝光
    此前传出三星GALAXY S7或将回归双处理器平台的模式,正在测试新款Exynos处理器和骁龙820处理器的消息。而现在,这样的说法似乎得到了某种程度的证实。根据安兔兔在微博上发布的信息显示,一款名为Lucky的三星新机正在进行测试,装载的是骁龙820处理器,并且性能表现突出。同时来自国外网站SamMobile独家披露的消息则声称,确认这次曝光的Lucky便是GALAXY S7,并且还会搭载全新2000万像素摄像头。 骁龙版跑分曝光   根据安兔兔在官方微博上披露的信息,一款代号为“Lucky”的三星神秘新机正在进行测试。目前安兔兔后台能够识别到的数据为搭载有四核心处理器(型号 还未识别),但由于所配GPU型号为Adre
[手机便携]
Ubuntu下Jlink的配置
安装环境:Win7 + VirsualBox + Ubuntu 12.04(32bit)+ ok6410 一,下载Jlink for linux 1,网址:http://www.segger.com/jlink-software.html,下载对应的版本,我这里下载的是JLink_Linux_V480_i386.tgz 二,安装Jlink 1,解压JLink_Linux_V480_i386.tgz tar zxvf JLink_Linux_V480_i386.tgz 2,进入JLink_Linux_V480_i386目录,查看README.txt,这里最新版本的配置和老版本可能不同,直接按照README上介绍的来。
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved