当前位置: 首页 > news >正文

(基于江协科技)51单片机入门:5.定时器

目录

定时器

中断系统

按键控制LED流水灯模式

可位寻址 和 不可位寻地址

利用定时器计时2秒闪烁一次LED代码:

利用STC - ISP获取定时器

1.流水灯主函数文件代码:

2.闹钟主函数文件代码:


定时器

                定时器是外设模块,当程序执行后,时间计算的 Delay 可以完全替代,且定时器不占单片机的计算空间

                定时器具有 4 种模式

                最常用的是 模式1:16位定时器 / 计数器

                计数器中有 TL0 和 TH0 用于计数,内存为2个字节(65535为最大值) 

                TL0 和 TH0 的加 有时钟给与的脉冲决定,一个脉冲 计算器+1

                直到计算器到达最大值 65535 就会溢出,从新计算

                溢出后计算器会向 TF0 申请中段

脉冲由SYSclk导致

                SYSclk:系统时钟,即金振周期,金振频率看开发板上金振上打印的,有12MHz 有11.0592MHz的

                SYSclk 被 MCU in 12T mode 作用 进行12分频

                12M 变为 1M (1秒(s) = 1000 毫秒(ms) = 1,000,000 微秒(μs))

                所以 1 微妙进行一次计数

                11.0592 MHz / 12 = 921.6 kHz

                1 微妙进行 0.921.6次计数

                如果给 1 链接 T0pin 作用:计数器

                如果给 0 链接SYSclk 作用:定时器

中断系统

                作用:提醒程序

中断系统是为使CPU具有对外紧急事件的实时处理能力而设置的

                中断系统就是打断你现在干的事情,让你先干其他事情,再会来干现在的事情

                例如:你突然尿急,中断现在干的事情,先去上厕所,再回来干事情

                中断你正在干的事情的原因就是中断源,尿急就是中断源

但中断源具有多个

                会按优先级进行,最先相应优先级最高的中断请求

中段的资源和单片机的型号关联在一起,不同的型号可能会有不同的中段资源,例如中断源的个数不同,中断源优先级的个数不同

                STC89C52有8个中断源:

                                外部中断0,定时器0中断,外部中断1,定时器1中断,串口中断,外部中断2,定时器2中断,外部中断3

                 4个中断优先级

                定时器模式寄存器为 TMOD 类似以前的P2,作用控制定时器达到我们想要的模式

按键控制LED流水灯模式

        可位寻址 和 不可位寻地址

                可位寻址:能单独赋值(一个bit位) P2_0

                不可位寻址:只能整体赋值(一个字节) P2

计数器只有溢出才发出中断申请

                所以想要定时器1毫秒提醒一次,就从溢出向前减去1毫秒内计数器的次数

                65535 - 1000(12MHz1毫秒计数的次数) = 64535

                我们上面讲计算器的最大值为 65535 是讲计时器看为了一个整体

                但实际上它是单独的两个储存

                一个储存有 256

                两个存储便是 256 * 256

                按排位先后将高位内容存入  TL0 中

                低位内容存入 TH0中

结合上文1毫秒提醒一次:

                给整体赋值为64535  

                单个:

                                TL0 = 64535 / 256;(一个储存的最大值)

                                TH0 =64535 % 256;

利用定时器计时2秒闪烁一次LED代码:

#include <REGX52.H>void Timer0_Init()	
{TMOD = 0x01;TF0 = 0;TR0 = 1;TH0 = 64535/256;TL0 =64535%256;ET0= 1;EA = 1;PT0 = 0;
}int main()
{Timer0_Init();  // 定时器模式初始化while(1){}return 0;
}
int c = 0;           // 设置为全局变量,放中断函数内部会导致,一直创建再销毁,永远到不了2
void Timer0_Routine() interrupt 1
{TH0 = 64535/256; // 由于每次中断,计数器会重新开始计算TL0 =64535%256;	 // 为了保持中断为1毫秒一次,中断中再次赋值为64535c++;if(c>1000){c = 0;P2_0=~P2_0;}
}

由于 TMOD 寄存器为不可位寻址 且 寄存器上控制着2个定时器

                直接给它赋值为 0x01 会影响到第 1 定时器 

                所以我们换一种写法,只控制计时器 0 二不干扰定时器 1               

                TMOD = 0x01  更改为 TMOD = TMOD & 0xF0;

                                                    TMOD = TMOD | 0x01;

                                作用:TMOD 低4位清零 高4位保持不变 

                                           将TMOD 最低位置1 高4位保持不变

利用STC - ISP获取定时器

定时器的初始化也可以利用STC - ISP 软件获取初始化的函数

                有4个注意点:

                1.89C52没有16位自动重载

                2.定时器时钟12T是选择        .

                3.在想选择6T时要在软件左侧勾选(12T够用了)

                 4.将配置好的第一句删除,因为89C52没有第一节的寄存器

                后续加上 ET0 = 1;(单独开关)

                EA =1;(总开关)

                PT0 = 0;(对这个中断选择优先级)

cror 和 crol 函数:

                两函数的头文件都是 <intring.h>

                cror:左移函数 

                crol:右移函数

实现独立按键控制流水灯的思路:

                利用 key(独立函数) 的返回值对中断函数的左右移操作进行判断

#include <REGX52.H>
#include "key.h"
#include "intrins.h"void Timer0_Init()	
{TMOD = 0x01;TF0 = 0;TR0 = 1;TH0 = 64535/256;TL0 =64535%256;ET0= 1;EA = 1;PT0 = 0;
}unsigned char move = 1;         // 流水灯左右移动决定变量,初始化为1(左移)int main()
{unsigned char key_ret = 0;  // 流水灯外围if语句的保护变量,用于暂存key的返回值P2 = 0xFE; 			¯Timer0_Init();  while(1){key_ret = key();        // 不直接让move 变量接收,保护move变量的值if(key_ret)             {if(key_ret == 1){move = 1;}if(key_ret == 2){move = 2;}}}return 0;
}
void Timer0_Routine() interrupt 1
{static int c = 0;TH0 = 64535/256; TL0 =64535%256;	 c++;if(c>500){c = 0;if(move==1){P2 =_cror_(P2,1);}if(move==2){P2 =_crol_(P2,1);}}
}

定时器函数的分装(11.0592MHz)

                头文件

#ifndef __TIME_H_
#define __TIME_H_
void Timer(void);
#endif

                 源文件

#include <REGX52.H>void Timer(void)		
{TMOD &= 0xF0;		TMOD |= 0x01;		TL0 = 0x66;		TH0 = 0xFC;		TF0 = 0;		TR0 = 1;ET0 = 1;EA = 1;PT0 = 0;
}

1.流水灯主函数文件代码:

#include <REGX52.H>
#include "key.h"
#include "intrins.h"
#include "time.h"unsigned char move = 1;  // 流水灯方向决定值int main()
{unsigned char key_ret = 0;P2 = 0xFE; 			// 流水灯初始化Timer0_Init();  // 初始化定时器模式while(1){key_ret = key();if(key_ret){if(key_ret == 1){move = 1;}if(key_ret == 2){move = 2;}}}return 0;
}
void Timer0_Routine() interrupt 1
{static int c = 0;TH0 = 64535/256; // 由于每次中断 计算器会从新开始计算TL0 =64535%256;	 // 为了保持间隔为1毫秒 在中断中再次赋值为64535c++;if(c>500){c = 0;if(move==1){P2 =_cror_(P2,1);}if(move==2){P2 =_crol_(P2,1);}}
}

2.闹钟主函数文件代码:

#include <REGX52.H>
#include "LCD1602.H"
#include "time.h"unsigned char S,M,H = 0;  // 秒 分钟 小时  
int main()
{LCD_Init();Timer();LCD_ShowString(1,1,"colck");LCD_ShowString(2,1,"  :  :");while(1){LCD_ShowNum(2,1,H,2);LCD_ShowNum(2,4,M,2);LCD_ShowNum(2,7,S,2);}return 0;
}void Timer0() interrupt 1
{static int i = 0 ;TL0 = 0x66;		TH0 = 0xFC;i++;if(i>1000){i = 0 ;S++;if(S>=60){S = 0;M++;if(M>=60){M = 0;H++;if(H>=24)H = 0;}}}
}

http://www.dtcms.com/a/419501.html

相关文章:

  • 怎么制作个人门户网站东莞常平中转场
  • 强化学习原理(四)
  • 做网站 毕业设计长沙企业网页设计哪家专业
  • 菊风可视化回溯解决方案,为金融业务合规打造全流程“可回溯”能力
  • 蜜度AI审校从技术到服务全面突破 为出版内容校对注入新活力
  • 单一索引,覆盖索引,联合索引
  • BentoML推出llm-optimizer开源框架:让LLM性能调优变简单?
  • Cherry Studio实战使用
  • Python 类型提示:Literal 类型
  • 仿造别人的网站侵权吗做网站被抓
  • 做中文网站的公司海安网站设计公司
  • 浏览器获取到网页的流程
  • 解析网站怎么做wordpress 小程序 插件
  • SQL 性能优化:为什么少用函数在 WHERE 条件中?
  • 迁西网站开发上海网络技术有限公司
  • 如何利用服务器做网站沈阳建设工程信息网中项网
  • 推广网站的方法有哪些建设网站账务处理
  • [Windows] 3D软件 Blender 5.0 alpha版
  • 计算机视觉(opencv)——基于 dlib 轮廓绘制
  • 帕累托概念Pareto
  • 海外云服务器压力测试,如何评估服务器性能与稳定性
  • python建设网站常州网站建设智博
  • 电子商务网站软件建设核心山西网站建设推荐
  • 氧气分析中心
  • 量子计算学习笔记(2)
  • wordpress降级商城网站前期seo应该怎么做
  • Nacos与Feign的工作作用以原理
  • RAG全栈技术——文档切分
  • vue2中element ui组件库,el-table实现滚动条只想出现在滚动区域,左右两侧固定列的下方不让出现滚动条
  • golang基础语法(六)Map