打印
[合泰杯HT32讨论区]

合泰单片机工程之定时器中断

[复制链接]
656|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)
void time2_Init(void)    //定时器2初始化
{
        _stm2c0=0;                 //计数频率为8MHz/4=2MHz  即计数一次为0.5us
        _stm2c1=0b11000001;                  //定时器2功能选择寄存器,选择为定时/计数器模式

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



使用特权

评论回复

相关帖子

沙发
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输出、输入捕捉等,都是在这里设置的。要重点看一下这一部分。

使用特权

评论回复
5
kzlzqi|  楼主 | 2023-2-26 16:51 | 只看该作者
[color=rgba(0, 0, 0, 0.75)]来看一下第0位,这里我设置为1。也就是与比较器A进行匹配。这里都关联到待会的设初值,也就是我们的目标值的写入寄存器的选择。

使用特权

评论回复
6
kzlzqi|  楼主 | 2023-2-26 16:52 | 只看该作者
第三第四条语句是我们的初值设置,这里我设置的是20000,也就是计数器计数到20000时中断溢出。消耗的时间为0.5us*20000=10ms。

使用特权

评论回复
7
kzlzqi|  楼主 | 2023-2-26 16:52 | 只看该作者
初值装在哪里?看下面的两个寄存器,初值就是装在这里,我们来看2000的十六进制数为0x4e20,也就是高8位为0x4e,低8位为0x20,。写入下面两个寄存器中即可,STM2AL写低8位,STM2AH写高8位。我们可以注意到,图片上有画框框的地方,这个就是比较器A,也是就这个两个寄存器是专门来设置比较器A的初值的(个人理解,错误指出哈)。

使用特权

评论回复
8
kzlzqi|  楼主 | 2023-2-26 16:54 | 只看该作者
剩下的语句就是开启一些相关的中断了,这里重点要解释的就是多功能中断使能那里,我们怎么知道定时器是在那个多功能中断上的,相应的中断向量(中断程序的入口)是多少?这里就要看一下中断的那一篇的那张图了,我就直接放出来了,你们可以在技术手册中断的那一篇找。下图可以看出我们应该怎么配置中断的,比如说STM2AF就是中断标志位,STM2AE是中断使能位,MF4F是多功能中断标志位,MF4E是多功能中断使能位,EMI为总中断。(好像F的都是标志位,E的都是使能位),同样可以找到中断的地址为0x38。

使用特权

评论回复
9
kzlzqi|  楼主 | 2023-2-26 16:54 | 只看该作者

使用特权

评论回复
10
kzlzqi|  楼主 | 2023-2-27 01:35 | 只看该作者
中断函数配置DEFINE_ISR(time2,0x38)
        _emi=0;                    //关闭总中断
        time2_count++;
        if(time2_count==100)
        {
                time2_count=0;
                LED1=!LED1;           //LED1状态取反
        }
        _stm2af=0;            //清除定时器中断标志位
        _emi=1;                    //开启总中断

使用特权

评论回复
11
kzlzqi|  楼主 | 2023-2-27 01:36 | 只看该作者
time2_count这个变量我一开始在程序的开头定义了,并在头文件那里声明用extern声明为全局变量。进入一次中断time2_count就+1,10ms进入一次,到100就是1秒,然后再清零,LED1再取反。

使用特权

评论回复
12
kzlzqi|  楼主 | 2023-2-27 01:36 | 只看该作者
主函数main
主函数没有什么东西,就是一些函数的初始化,和关闭看门狗而已

使用特权

评论回复
13
kzlzqi|  楼主 | 2023-2-27 01:36 | 只看该作者
#include "HT66F2390.h"
#include "delay.h"
#include "uart.h"
#include "LED.h"
#include "time.h"

void main()
{
        int t=0;    //用于计时
        LED_Init();   //LED初始化
        time2_Init();   //定时器2初始化
        _wdtc=0b10101011;   //关闭看门狗
        while(1)
        {
                delay_ms(10);
                t++;
                if(t==100)
                {
                        t=0;
                        LED2=!LED2;    //系统状态指示灯
                }                       
        }
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

101

主题

797

帖子

2

粉丝