[合泰杯HT32讨论区] 合泰单片机工程之定时器中断

[复制链接]
1230|12
 楼主| kzlzqi 发表于 2023-2-26 16:42 | 显示全部楼层 |阅读模式
2022年4月21日更新
首先在这里跟各位网友们说声对不起,真的不好意思鸽了各位网友们那么久,PWM的实验是有完成的,但是那段时间在忙比赛也就没有更新,后面比赛忙完了人也开摆了哈哈,我想把PWM 的例程给放上来,你们跟着前面的定时器的基础,应该是能理解这份代码的(不是我不想更一篇,主要是已经挺久没搞合泰,已经忘了七七八八了,如果周末有时间的话,我会写一份的,就算给这个系列一个完结吧),后面会更新其他类型的博客,欢迎广大网友们关注!!!
链接:https://pan.baidu.com/s/1–h0iN11xW7FB8QRbl43ug
提取码:1111
–来自百度网盘超级会员V1的分享

前言
这一篇记录的是我在定时器这一部分的理解,用的芯片是HT66F2390,开发工具是HT-3000及开发手册。预计实现的功能为精准定时1秒闪烁一次LED灯。为下一篇的PWM打一下基础。有错误的地方欢迎指正。首先什么是定时器呢?按照我个人的理解,单片机的定时器不是也叫计数器吗?所以单片机每隔一定的时间间隔就计数一次,等计数到我们设定的目标值时候,单片机的执行中断,执行我们设定的程序,比如最简单的点灯程序。(单片机都是从零开始计数,直到我们设定的那个初值)

提示:以下是本篇文章正文内容,下面案例可供参考

一、定时器功能配置?1.定时器初始化函数time2_Init(void)
  1. void time2_Init(void)    //定时器2初始化
  2. {
  3.         _stm2c0=0;                 //计数频率为8MHz/4=2MHz  即计数一次为0.5us
  4.         _stm2c1=0b11000001;                  //定时器2功能选择寄存器,选择为定时/计数器模式

  5.         _stm2al=0x20;               //初值为20000,计数时间为10ms
  6.         _stm2ah=0x4e;
  7.        
  8.         _stm2ae=1;                 //STM2 比较器 A 匹配中断控制位使能
  9.         _st2on=1;                   //开启定时器
  10.         _mf4e=1;                    //多功能中断使能
  11.         _emi=1;                    //开启总中断       
  12. }



 楼主| kzlzqi 发表于 2023-2-26 16:44 | 显示全部楼层
我们先来一句一句的分析代码,第一和第二条语句涉及到定时器部分两个最重要的寄存器。

STM2C0寄存器,如下图,这里是设置寄存器8个位都是0,重点看一下Bit6~4(选择STM2计数时钟位),我选择的是000,也就是系统时钟/4,系统时钟一开始设置的8MHz,故这是2MHz,也就是0.5us,即计数一次消耗的时间为0.5us。
 楼主| kzlzqi 发表于 2023-2-26 16:45 | 显示全部楼层
 楼主| kzlzqi 发表于 2023-2-26 16:50 | 显示全部楼层
STM2C1寄存器,如下图,这是定时器的功能选择寄存器,有我们用的普通的定时功能,也有PWM输出、输入捕捉等,都是在这里设置的。要重点看一下这一部分。

 楼主| kzlzqi 发表于 2023-2-26 16:51 | 显示全部楼层
[color=rgba(0, 0, 0, 0.75)]来看一下第0位,这里我设置为1。也就是与比较器A进行匹配。这里都关联到待会的设初值,也就是我们的目标值的写入寄存器的选择。

 楼主| kzlzqi 发表于 2023-2-26 16:52 | 显示全部楼层
第三第四条语句是我们的初值设置,这里我设置的是20000,也就是计数器计数到20000时中断溢出。消耗的时间为0.5us*20000=10ms。
 楼主| kzlzqi 发表于 2023-2-26 16:52 | 显示全部楼层
初值装在哪里?看下面的两个寄存器,初值就是装在这里,我们来看2000的十六进制数为0x4e20,也就是高8位为0x4e,低8位为0x20,。写入下面两个寄存器中即可,STM2AL写低8位,STM2AH写高8位。我们可以注意到,图片上有画框框的地方,这个就是比较器A,也是就这个两个寄存器是专门来设置比较器A的初值的(个人理解,错误指出哈)。

 楼主| kzlzqi 发表于 2023-2-26 16:54 | 显示全部楼层
剩下的语句就是开启一些相关的中断了,这里重点要解释的就是多功能中断使能那里,我们怎么知道定时器是在那个多功能中断上的,相应的中断向量(中断程序的入口)是多少?这里就要看一下中断的那一篇的那张图了,我就直接放出来了,你们可以在技术手册中断的那一篇找。下图可以看出我们应该怎么配置中断的,比如说STM2AF就是中断标志位,STM2AE是中断使能位,MF4F是多功能中断标志位,MF4E是多功能中断使能位,EMI为总中断。(好像F的都是标志位,E的都是使能位),同样可以找到中断的地址为0x38。
 楼主| kzlzqi 发表于 2023-2-26 16:54 | 显示全部楼层
 楼主| kzlzqi 发表于 2023-2-27 01:35 | 显示全部楼层
中断函数配置DEFINE_ISR(time2,0x38)
  1.         _emi=0;                    //关闭总中断
  2.         time2_count++;
  3.         if(time2_count==100)
  4.         {
  5.                 time2_count=0;
  6.                 LED1=!LED1;           //LED1状态取反
  7.         }
  8.         _stm2af=0;            //清除定时器中断标志位
  9.         _emi=1;                    //开启总中断
 楼主| kzlzqi 发表于 2023-2-27 01:36 | 显示全部楼层
time2_count这个变量我一开始在程序的开头定义了,并在头文件那里声明用extern声明为全局变量。进入一次中断time2_count就+1,10ms进入一次,到100就是1秒,然后再清零,LED1再取反。
 楼主| kzlzqi 发表于 2023-2-27 01:36 | 显示全部楼层
主函数main
主函数没有什么东西,就是一些函数的初始化,和关闭看门狗而已
 楼主| kzlzqi 发表于 2023-2-27 01:36 | 显示全部楼层
  1. #include "HT66F2390.h"
  2. #include "delay.h"
  3. #include "uart.h"
  4. #include "LED.h"
  5. #include "time.h"

  6. void main()
  7. {
  8.         int t=0;    //用于计时
  9.         LED_Init();   //LED初始化
  10.         time2_Init();   //定时器2初始化
  11.         _wdtc=0b10101011;   //关闭看门狗
  12.         while(1)
  13.         {
  14.                 delay_ms(10);
  15.                 t++;
  16.                 if(t==100)
  17.                 {
  18.                         t=0;
  19.                         LED2=!LED2;    //系统状态指示灯
  20.                 }                       
  21.         }
  22. }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

127

主题

996

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部