秒表时钟计时器的设计(Timer)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

你的程序不复杂也比较符合规范还是很好看懂的 咱们说说哈 01 行你的备注不对吧 该备注应该是 03 行的吧 07 行---0D 行 是初始化定时器的内容 应该移出 while(1)在上电执行一次即可 不 要在 while(1)里面一直执行 07 行---0D 行里面的一些内容矛盾 比如说 07 行的备注写的是用定时器 1 定 1ms 08 行把定时器 1 搞成了方式 2 那么方式 2 的时候最大定时时间为 256 微秒(12M 晶体)无 法定 1ms 阿于 07 行矛盾 09 行和 0A 行得一起看 你已经把定时器初始化成方式 2 了注释也写了自动从装但是你把 2 个初始化成 2 个数 溢出后将会装入其中一个的值 导致 2 个相同了 与上面几行矛盾 0B 行没啥问题 就是写错位置了 和上面的几行一起倒出 while(1)就行 0c 和 od 行就不知道为啥了看你的程序和 TI,RI 没有关系啊 要删除的
1
1C 1D 1E 1FΒιβλιοθήκη Baidu20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38
{ time2=0x30; time3++; display_char(7,0,time3); display_char(9,0,time2); if(time3>0x39) { time3=0x30; time4++; display_char(6,0,time4); display_char(7,0,time3); if(time4>0x39) { time4=0x30; time3=0x30; time2=0x30; time1=0x30; display_char(6,0,time4); display_char(7,0,time3); display_char(9,0,time2); display_char(10,0,time1); } } } } } } if(key==1) {ledkey=1; TR1=0;} } //检测到按键松开,关闭计时器
5
RW=1; E=1; _nop_(); Busy=Lcd_Bus&0x80; E=0; return Busy; } //---------------------------------------------------------/************************************************ ** 函数功能:** 写数据到液晶 ** ** 带入参数:** 数据 ** ** 带出参数:** 无 ** ** 其他备注:** 写一个字节 ** ** 作 者:** Unifax ** ** 时 间:** 2009.4.3 ** ************************************************/ void Lcd_WriteData(unsigned char Data) { while(Test_Busy()); RS=1; RW=0; E=0; _nop_(); _nop_(); Lcd_Bus=Data; E=1; _nop_(); _nop_(); E=0; } //---------------------------------------------------------/************************************************ ** 函数功能:** 写命令到液晶 ** ** 带入参数:** 命令 ** ** 带出参数:** 无 ** ** 其他备注:** 写一个字节 ** ** 作 者:** Unifax ** ** 时 间:** 2009.4.3 ** ************************************************/ void Lcd_WriteCmd(unsigned char Cmd) { while(Test_Busy()); RS=0;
2
0F 行批注写错 定时器那样初始化不可能定 1ms 的 10 行没有问题采取的是查询的方法是可以的 但实时性稍微不如中断的好 看自己的爱好写 了 再一下的分析中假设上面的毛病都已经更正了然后再分析新的问题哈 12 行没问题 到了 1ms 加一个数字 13 行是啥意思再加一次 难道是希望 2,4,6,8 这样的走表? 14 行看你写的应该是一个液晶显示函数 在 0 行的第 10 个位置显示 刚刚处理过的 time1 是 吧!但是你没有把这个数字加工成 ASC 应该在之前有 time1=0X30;之类的语句 15 行----19 行没问题 1a 行我又不明白你为啥又显示 time1 了 一定要和我说下你的想法 1b------1f 行也没问题 20 行和 1a 行一样 我感觉多余 21 行-----25 行没问题 26 行和 1a 行一样 27-----2c 行没问题 就是溢出清 0 嘛 2d-30 为啥又显示一次呢?又不是数码管 不需要老扫描的吧 37 行自然没问题 但是希望你后面的东西再低下写 要养成好的编程代码习惯 调了你这么多的毛病 不知道你看烦了没有 以下是我给你改好的程序(编译运行过的,按你的图保证没有问题)就是按照上面说的改的 /**************************程序说明*********************************** *程序说明:完成按键记时功能精确到 1ms *硬件环境: MCU:AT89S52 晶体:12Mhz 其他:LCM1602 *编译环境: Keil V3 *编程作者: Unifax *完成时间: 2009.4.13 ************************************************************************/ //-------------------------预处理区---------------------------------#include<reg52.h> #include<intrins.h> #define Lcd_Bus P2//宏定义 LCD 的数据接口 //----------------------全局变量定义区-------------------------------
分析了你的要求大体是这个样子的 1 程序开始的时候在液晶上显示 0000 2 当按住按键的时候毫秒位开始按照每毫秒加 1 其他的进位就行啦 开灯 3 当松手的时候显示按了多长时间 显示并不清除 关灯 4 当再次按键的时候接着跑表 开灯 5 当按下 REST 键的时候 屏幕清除 我就拿以上的理解说你的程序 要是理解不对的话 告诉我咱们再讨论 看完你的电路图 提点小小建议 P0 口在使用上需要加上拉电阻的否则工作不稳定的 一定要注意这点 以下是你的程序红色的 为了方便说事我在每行标了号码 我的程序: 01 while(1) //检测是否有键按下 02 { 03 if(key==0) 04 { 05 ledkey=0; 06 07 //用单片机的 T1 定时器定时 1ms 08 TMOD=0x20; //设定时器 T1 工作于方式 2 自动重装,作波特率发生器 09 TH1=0xDB; //fosc=12MHZ, 定时 t ms 时, 定时器的初值 X=65536-12*t*1000/12 0A TL1=0xF0; // 0B TR1=1;//启动定时器 0C RI=0; 0D TI=0; 0E 0F //检测定时器 T1 是否溢出,溢出,则毫秒低位 time1 加 1,满 9 则进位 10 if(TF1==1) 11 { 12 time1++; 13 time1++; 14 display_char(10,0,time1); 15 if(time1>0x39) 16 { 17 time1=0x30; 18 time2++; 19 display_char(9,0,time2); 1A display_char(10,0,time1); 1B if(time2>0x39)
sbit RS=P0^0; sbit RW=P0^1; sbit E=P0^2; sbit K1=P1^4;//键盘 sbit LED=P1^0;//灯
3
//------------------------函数说明区--------------------------------void Sys_Init(void);//系统初始化函数 void T1_Init(void);//T1 初始化函数 void Lcd_WriteData(unsigned char Data);//LCD 测忙函数 void Lcd_WriteData(unsigned char Data); void Lcd_WriteCmd(unsigned char Cmd); void Lcd_Init(void); //========================主函数入口================================= void main(void) { unsigned char Time_3,Time_2,Time_1,Time_0; unsigned int Time; Sys_Init();//系统初始化函数 while(1)//主要任务循环体 { if(!K1)//按住键 { if(TR1)//已经启动定时器 { if(TF1)//到了 1ms { Time++;//时间增 1 TF1=0;//清楚标志 if(Time>9999)//如果超出 4 位显示范围 { Time=0;//清除 } Time_3=Time/1000;//提取最高位 也就是秒位 Time_2=(Time%1000)/100;//提取百 ms 位 Time_1=(Time%100)/10;//提取十 ms 位 Time_0=Time%10;//提取 ms 位 Lcd_WriteData(Time_3+0x30);//显示秒位 Lcd_WriteData(Time_2+0x30);//显示百豪秒位 Lcd_WriteData(Time_1+0x30);//显示十豪秒位 Lcd_WriteData(Time_0+0x30);//显示豪秒位 Lcd_WriteCmd(0x80);//把光标移回开始 } } else//定时器还没有启动 { TR1=1;//启动定时器 LED=0;//开灯 }
4
} else//松手 { TR1=0;//关掉定时器 LED=1;//关掉灯 } } } //=================================================================== //--------------------------函数区----------------------------------void Sys_Init(void)//系统初始化函数 { unsigned char i; Lcd_Init();//液晶初始化函数 T1_Init();//T1 初始化函数 for(i=0;i<4;i++)//首先显示 4 个 0 { Lcd_WriteData('0'); } Lcd_WriteCmd(0x80);//把光标移回开始 0 } //-------------------------------------------------------------------void T1_Init(void)//T1 初始化函数 { TMOD=0X10;//使用定时器 1 的工作方式 1 最大定时可达 65ms TH1=0XFC; TL1=0X18;//设定定时 1ms } //------------------------------------------------------------------/************************************************ ** 函数功能:** 测试液晶忙标志 ** ** 带入参数:** 无 ** ** 带出参数:** 忙标志位 ** ** 其他备注:** 忙为 1,空闲为 0 ** ** 作 者:** Unifax ** ** 时 间:** 2009.4.3 ** ************************************************/ unsigned char Test_Busy(void) { unsigned char Busy; Lcd_Bus=0xff; RS=0;
相关文档
最新文档