版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、以数码管显示程序为例讲讲单片机系统编程的一些方法和思想前后台程序结构,由主循环加中断构成,主循环程序称为“后台程序”或“背景程序”;各个中断程序称为“前台程序”,依靠中断内的前台程序来实现事件响应与信息收集。后台程序多个处理任务顺序依次执行,从宏观上看,这些任务将是同时执行的。前后台程序结构可以实现多任务同时执行,本质是快速地依次循环执行各个任务。编写前后台多任务程序最重要的原则是任何一个任务都不能阻塞CPU。每个函数都应尽可能快地执行完毕,将CPU让给后续的函数。利用单片机数码管显示程序作为例子,使用RAM缓冲区。前台的定时中断扫描程序需要不断循环扫描刷新数码管,而后台任务可能随时需要改变显
2、示内容。用一个数组作为显示缓冲,消除两种操作之间的时间关联性。对于前台程序,在定时中断内只负责将显示缓冲中的内容依次显示到LED上,后台程序可以随时更改显示缓存数据,从而改变实际显示内容。显示缓冲在这里充当了前台程序与后台程序之间的数据传递渠道,消除了前后台之间的直接关联性。事实上,在这种结构下前台的刷新操作对于后台程序来说是不可见的,因此缓冲区也是一种很好的硬件隔离层。我针对这个“前后台程序结构”的思想,再结合程序封装和程序分层的思想,参考了传统的数码管动态扫描程序,花了一天一夜写出了这个数码管显示模块子程序。这个子程序已经封装成一个函数,提供4个参数输入,可以选择不同的工作模式。此函数要求
3、8位数码管的段码数据线和位码数据线分时复用,共用单片机的某8位IO口,这里接P0口,所以需要上拉电阻。此程序对硬件的要求是:用两片地址/数据锁存器分别锁存数码管的段码和位码,共用单片机8位IO口,动态扫描方式。所以说这种方法占用的硬件资源很少,适合用于较大的单片机系统中。程序的宏定义很简洁,只需要宏定义数据口,定义锁存器使能端,8位显示缓存区和段码表(段码表是共阳极的,只要在调用的时候取反就可以了)。用在不同的电路时,只需要改写数据端口的宏定义和锁存器使能端。这样的程序具有可移植性,封闭性,层次性,对以后的模块程序复用和系统程序构建有很大的益处。封装好的函数为: LED_DisplayNumb
4、er(int Number,unsigned char Flat,unsigned char DecimalPoint,unsigned char SegBuffClear);。以后在需要数码管显示功能的系统中,只要定义了相关端口,就可以在主程序循环中调用数码管显示函数了。只需要传入参数int Number,设置模式unsigned char Flat,设置小数点unsigned char DecimalPoint,设置清屏unsigned char SegBuffClear,就可以随意显示数据了。格式为(传入参数,【0为纯数字,1为温度值,2为按键输入】,1为有小数点,1为清屏)。主程序中模
5、拟了正负数、小数点、温度值、按键值和清屏的条件下的程序,并给出了运行的仿真效果图。数码管显示函数的内部结构已经全部呈现出来,并加上了详细的注释,帮助读者更方便地理解程序。本程序主要目的不是仅仅为了实现单片机的数码管动态显示功能,其最重要的意义在于对模块程序或功能函数封装和调用的编程思想,以及系统程序中“前后台程序结构”,“非阻塞型结构”和RAM缓冲区的编程方法。如果你是个初学者,或者你觉得这样的函数太复杂,没必要,可你接触了系统程序的编程时,你就会发现用教科书上的传统思想来编程会非常吃力不讨好。把程序封装成函数,把程序结构分出层次和“前后”,把程序写成“非阻塞型”,使用RAM缓冲区,这是系统程
6、序中优良的编程方法,尤其在庞大的超低功耗的电路系统中。终于写完了,包括程序和文章,感觉就是:“累并快乐着!”周末烦事多,天气不好,心情更不好。无心看书,更无意学习,于是就化郁闷为力量,一鼓作气写出了这些东西。不仅不开心的时间过得特别快,睡眠也好了,胃口也不错,当然心情也转好啦!_写程序的同时,大地震发生了,在这里向灾区的同胞们默默祝福,祈祷!#include<reg52.h> /包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#define SEG_PORT P0sbit LATCH1=P36;/定义锁存使能端口 段锁存sbit LATCH2=P37;/ 位锁存uns
7、igned char DispBuff8; /显示数据缓存unsigned char code LED_Tab=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x98,0x7f,0x9c,0xc6,0xbf;/ 显示段码值【0123456789 . 摄氏度符号 C 负号】(共阳极)/函数声明void LED_Display_Scan();void LED_DisplayNumber(int Number,unsigned char Flat,unsigned char DecimalPoint,unsigned char SegBuffClear);
8、void Init_Timer0(void);void DelayMs(unsigned char t);void DelayUs2x(unsigned char t);/*- 主函数,示范程序-*/main() int i; i=-13525;/-3276832767Init_Timer0();/定时器0初始化 while(1) LED_DisplayNumber(i,1,1,0);/传入要显示的参数并产生相应的段码/(传入参数,【0为纯数字,1为温度,2为按键输入】,1为有小数点,1为清屏)DelayMs(60000);DelayMs(60000);/*DelayMs(60000);/这里
9、模拟按键输入模式,只要设置好模式,把这里的屏蔽去掉DelayMs(60000);DelayMs(60000);LED_DisplayNumber(5,2,0,0);DelayMs(60000);DelayMs(60000);DelayMs(60000);DelayMs(60000);LED_DisplayNumber(3,2,0,0);DelayMs(60000);DelayMs(60000);DelayMs(60000);DelayMs(60000);*/i+=100; /*Name: LED_Display_Scan()*Function:动态数码管扫描刷新程序*Inlet Paramet
10、ers: None*Export parameters: None*Description:前台程序,被定时中断调用,定时取出显示缓存的数据并刷新数码管*/void LED_Display_Scan()static unsigned char COM;/定义位选静态变量LATCH1=0; /先置零锁存时序LATCH2=0;COM+;if(COM>7) COM=0;SEG_PORT=0x00; /先段码清零以消隐LATCH1=1;LATCH1=0;switch(COM)case 0: SEG_PORT=DispBuff0;/段码数据口输出显示缓存数据 LATCH1=1;LATCH1=0;/
11、段锁存SEG_PORT=(0x80);/段码数据口输出位选,取反为共阴极LATCH2=1;LATCH2=0;/位锁存 break;case 1: SEG_PORT=DispBuff1;LATCH1=1;LATCH1=0;/段锁存SEG_PORT=(0x40);LATCH2=1;LATCH2=0;/位锁存 break;case 2: SEG_PORT=DispBuff2;LATCH1=1;LATCH1=0;/段锁存SEG_PORT=(0x20);LATCH2=1;LATCH2=0;/位锁存 break;case 3: SEG_PORT=DispBuff3;LATCH1=1;LATCH1=0;/段
12、锁存SEG_PORT=(0x10);LATCH2=1;LATCH2=0;/位锁存 break;case 4: SEG_PORT=DispBuff4;LATCH1=1;LATCH1=0;/段锁存SEG_PORT=(0x08);LATCH2=1;LATCH2=0;/位锁存 break;case 5: SEG_PORT=DispBuff5;LATCH1=1;LATCH1=0;/段锁存SEG_PORT=(0x04);LATCH2=1;LATCH2=0;/位锁存 break;case 6: SEG_PORT=DispBuff6;LATCH1=1;LATCH1=0;/段锁存SEG_PORT=(0x02);
13、LATCH2=1;LATCH2=0;/位锁存 break;case 7: SEG_PORT=DispBuff7;LATCH1=1;LATCH1=0;/段锁存SEG_PORT=(0x01);LATCH2=1;LATCH2=0;/位锁存 break;/*Name:LED_DisplayNumber(int Number,unsigned char Flat,unsigned char DecimalPoint,unsigned char SegBuffClear)*Function:动态数码管显示程序*Inlet Parameters:(Number,Flat,DecimalPoint,SegBu
14、ffClear)(传入有符号参数,模式,小数点,清屏)*Export parameters: None*Description:后台程序,负责接收传入的参数并解析处理,再写入显示缓存,等待定时调用扫描程序把缓存中的显示数据取走并显示Flat,为0时代表输入纯数字;为1时代表输入温度值;为2时代表按键输入参数输入范围:-3276832767;温度范围-327327摄氏度*/void LED_DisplayNumber(int Number,unsigned char Flat,unsigned char DecimalPoint,unsigned char SegBuffClear)char D
15、igit,DigitSeg,Negtive;char SegBuff8;char i,Bits;unsigned int j,temp;static char k=8;if(SegBuffClear)/段码缓存清零for(i=0;i<8;i+)SegBuffi=0;else if(Flat=2)/按键输入模式,键值逐个输入if(k=8)for(i=0;i<8;i+)SegBuffi=0;k-;DigitSeg=LED_TabNumber;SegBuffk=DigitSeg;if(k=0) k=8;elsefor(i=0;i<8;i+)/每次运行此程序先把段码缓存清零SegBu
16、ffi=0;if(Number<0) /检测输入参数是否为负Negtive=1; /负号标志位置位j=(-1)*(Number); /将有符号整型转为无符号整型temp=j;elseNegtive=0;j=Number;temp=j;while(j!=0)/检测输入参数的位数 j/=10;Bits+;/位数加一 for(i=2;i<8;i+)/把传入的参数按位分解,逐个取段码并传入段码缓存Digit=temp%10;temp/=10;if(Digit=0)&&(Bits=0) continue;/这里可以保证传入参数之外的空余缓存为零,即不显示 if(Decimal
17、Point=1)&&(i=4)/默认小数点后两位 DigitSeg=(LED_TabDigit&0x7f);/倒数第三位数有小数点SegBuffi=DigitSeg;Bits-;continue;DigitSeg=LED_TabDigit;SegBuffi=DigitSeg;Bits-;if(Flat=1) /输入的是温度值,增加摄氏温度符号DigitSeg=LED_Tab11;SegBuff1=DigitSeg;DigitSeg=LED_Tab12;SegBuff0=DigitSeg;if(Negtive) /添加负号DigitSeg=LED_Tab13;SegBuf
18、f7=DigitSeg;/_DINT();DispBuff0=SegBuff0;/把段码缓存的段码数据传入显示缓存,以备定时扫描调用DispBuff1=SegBuff1;DispBuff2=SegBuff2;DispBuff3=SegBuff3;DispBuff4=SegBuff4;DispBuff5=SegBuff5;DispBuff6=SegBuff6;DispBuff7=SegBuff7;/_EINT();/*- 定时器初始化子程序-*/void Init_Timer0(void) TMOD |= 0x01; /使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响 /TH0=0x00; /给定初值 /TL0=0x00; EA=1; /总中断打开 ET0=1; /定时器中断打开 TR0=1; /定时器开关打开/*- 定时器中断子程序-*/void Timer0_isr(void) interrupt 1 TH0=(65536-6000)/256; /重新赋值 6ms,这里按实际需要调整定时扫描间隔 TL0=(65536-6000)%256; LED_Display_Scan(); / 定时调用数码管扫描/*- uS延时函数,含有输入参数 unsigned char t,无返回值 unsi
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 与味道有关的课程设计
- 小学生数学学习兴趣的激发与培养
- 2023年其它核材料及相关特殊材料项目筹资方案
- 支教课程设计认识自我
- 青岛酒店管理职业技术学院《保险经济学》2023-2024学年第一学期期末试卷
- 托班青蛙课程设计
- 青岛工学院《餐饮运营与管理》2023-2024学年第一学期期末试卷
- 归园田居其一课程设计
- 兔子绘画创意课程设计
- 投资融资课程设计总结
- 【基于抖音短视频的营销策略分析文献综述2800字(论文)】
- 2021-2022学年度西城区五年级上册英语期末考试试题
- 《组织行为学》(本)形考任务1-4
- 广东省广州市白云区2022-2023学年九年级上学期期末语文试题
- 剧本-进入黑夜的漫长旅程
- DB43-T 958.3-2023 实验用小型猪 第3部分:配合饲料
- 化肥购销合同范本正规范本(通用版)
- 健康管理专业职业生涯规划书
- 外墙岩棉板施工方案
- 吊装葫芦施工方案
- 自动化设备调试规范
评论
0/150
提交评论