单片机串口连接两个74LS164驱动两个LED数码管
- 格式:doc
- 大小:407.50 KB
- 文档页数:9
单片机应用系统开发利用串口驱动数码管显示专业:信息对抗技术学号:1411050121姓名:吴志飞1.系统设计要求设晶振频率为12MHZ,将拨码开关数据串行输入到74LS164,并行输出到2个LED数码管进行相应的数码显示。
2.系统设计分析:单片机的最小系统+74LS164接口芯片+两个7段共阴极LED数码管。
串口工作于方式0,为移位寄存器方式,波特率为固定的fosc/12,不需要定时计数器T1做波特率发生器。
拨码开关的的高低4位分别控制一个数码管,数码管要显示的数据可以用查表法。
两个数码管并连接在74LS164的输出端,通过选通位来控制哪一个数码管亮。
74LS164是8位边沿触发式移位寄存器,串行输入,并行输出。
数据通过俩个输入端A或B之一串行输入,任一输入端可以作为高电平使能端来控制另一输入端的数据输入。
俩个输入端或者连接在一起,或者把不用的一端接高电平,一定不要悬空。
时钟CP 每次有低变高时,数据右移一位输入到Q0。
Q0是两个数据输入端的逻辑与。
3.系统原理图设计:图1.1 74LS164接口芯片系统所需原件为单片机AT89C51,瓷片电容CAP30pf,晶振CRYSTAL12MHZ,电解电容CAP-ELEC,电阻RES,拨码开关DIPSW_8,共阴极数码管7SEG-COM-CAT-GRN俩个,74LS164接口芯片一个以及开关SWITCH。
原理图如1.2所示。
图1.2 利用串口数据驱动数码管进行相应数码显示4.系统流程图设计:串口寄存器设置初始化P0、P1口开始把P1口给累加器A5.系统源程序设计:汇编源程序:ORG 0030HSTART:MOV SCON,#00H //串口工作于方式0:移位寄存器方式MOV P1,#00HREAD: MOV P0,#0FFHMOV A,P1MOV B,P1ANL A,#0F0HCJNE A,B,LOW4/////////////////////////HIG4: MOV DPTR,#TABLESWAP AXH: MOVC A,@A+DPTRMOV SBUF,ACLR P0.0LCALL DELAYMOV A,P1CJNE A,SBUF,READAJMP READ///////////////////////////LOW4: MOV A,P1ANL A,#0FHCJNE A,B,LOOP3MOV DPTR,#TABLEXL: MOVC A,@A+DPTRMOV SBUF,ACLR P0.1LCALL DELAYMOV A,P1CJNE A,SBUF,READAJMP READLOOP3:NOPTABLE:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H ////////延时子程序//////////////DELAY:MOV R7,#20DELAY1:MOV R6,#40DELAY2:MOV R5,#248DJNZ R5,$DJNZ R6,DELAY2DJNZ R7,DELAY1RETENDC语言源程序:#include<reg51.h>#define uint unsigned int#define uchar unsigned charvoid delay();sbit p01=P0^1;sbit p00=P0^0;uchar codetab[]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F,0X77,0X7C,0X39,0X5E,0X79,0X71}; //共阴uchar a;void main(void){SCON=0X00;while(1){a=P1&0X0F; //低四位SBUF=tab[a];while(TI==0);TI=0;p00=1;p01=0;delay();a=P1&0XF0 ; //高四位a>>=4;SBUF=tab[a];while(TI==0);TI=0;p01=1;p00=0;delay();}}void delay() //延时子程序{uint c,d;for(c=0;c<400;c++)for(d=0;d<400;d++){;}}6.在keil中进行调试:(1)创建“数码管”项目,选择单片机型号为AT89C51,汇编源程序,保存为“数码管.ASM”或“数码管.C”。
实验二 74LS164串进并出实验及165并串转换实验一、实验目的1、了解74LS164芯片的工作原理,以及与单片机的接口方法。
2、掌握单片机串行口的工作原理以及编程方法。
3、了解74LS165芯片的工作原理。
4、掌握74LS165芯片在单片机系统中的应用及编程。
二、实验内容1、用74LS164芯片扩展并行输出口,本实验中我们用74LS164扩展两个8位输出口的接口显示电路,两位数码管循环显示00~99之间的数字。
2、利用实验系统上的74LS165芯片,编程实现8位数据并行输入,串行口串行接收,并将接收的数据存放在CPU 内部存储区50H~59H 中,共10个数据。
(并行输入数据由P1口来送入)三、编程指南1、74LS164串进并出实验。
(1)本实验中MCS-51单片机串行口工作在方式0(移位寄存器方式,用于并行I/0口扩展)的发送状态时,串行数据由P3.0(RXD)送出,移位时钟由P3.1(TXD )送出。
在移位时钟的作用下,串行口发送缓冲器的数据一位一位地移入74LS164中。
需要指出的是,由于741S164无并行输出控制端,因而在串行输入过程中,其输出端的状态会不断变化,故在某些应用场合,在74LS164的输出端应加接输出三态门控制,以便保证串行输入结束后再输出数据。
(2)74LS164引脚功能图管脚说明:SIA 、SIB --- Serial inputsQ0 through Q7 ---- Data outputs CLK ---- CLOCKCLR ---- Clear input功能表:2、165并串转换实验。
(1)74LS165芯片引脚图管脚说明:D0 through D7 --Parallel inputs SI -- Serial inputQ7,/Q7 -- Data outputsCLK -- ClockCKIN -- Clock inhibitS/L -- (高有效)Shift/Parallel-loadCLRSIA SIB CLK Q0 Q1 Q2 Q3 Q4 Q5 Q6 0 X X X 0 0 0 0 0 0 0 1 1 1 ↑ 1 Q0 Q1 Q2 Q3 Q4 Q5 Q6 1 0 X ↑ 0 Q0 Q1 Q2 Q3 Q4 Q5 Q6 1 X 0 ↑ 0 Q0 Q1 Q2 Q3 Q4 Q5 Q6control(低有效)(2)编程说明74LS165是8位并行置入移位寄存器。
用两个74HC164驱动两个四位的数码管~~(一个简易电子钟)几天前我发一了帖寻求用两74HC164做动态扫描数码管~~~ 今天我折腾了一天终于把它难弄出来了~~~~~~其电路图是在一本书上找到的~~由于还没学会用protel 99画图,,所以就只有将就一下了我的程序如下:#include<at89x51.h>sbit DAT=P1^1;sbit CLK=P1^2;unsigned char code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//显示0~9unsigned char code ff[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x77};//位选;unsigned char a,b,c,d,e,f,ch,hour,minite,second;//开启计时void loading(){TMOD=0x22;TR0=1;ET0=1;EA=1;}以下是显示程序,共八个,因为有八个数码管;void sendbyte(unsigned char byte){unsigned char num,c;num=tab[byte];for(c=0;c<8;c++){CLK=0;DAT=num&0x80;CLK=1;num<<=1;}num=0xfe;for(c=0;c<8;c++){CLK=0;DAT=num;CLK=1;num<<=1;}}void sendbyte_1(unsigned char byte) {unsigned char num,c;num=tab[byte];for(c=0;c<8;c++){CLK=0;DAT=num&0x80;CLK=1;num<<=1;}num=0xfd;for(c=0;c<8;c++){CLK=0;DAT=num&0x80;CLK=1;num<<=1;}}void sendbyte_2(unsigned char byte) {unsigned char num,c;num=tab[byte];for(c=0;c<8;c++){CLK=0;DAT=num&0x80;CLK=1;num<<=1;}num=0xfb;for(c=0;c<8;c++){CLK=0;DAT=num&0x80;CLK=1;num<<=1;}}void sendbyte_3(unsigned char byte) {unsigned char num,c;num=tab[byte];for(c=0;c<8;c++){CLK=0;DAT=num&0x80;num<<=1;}num=0xf7;for(c=0;c<8;c++){CLK=0;DAT=num&0x80;CLK=1;num<<=1;}}void sendbyte_4(unsigned char byte) {unsigned char num,c;num=tab[byte];for(c=0;c<8;c++){CLK=0;DAT=num&0x80;CLK=1;num<<=1;}num=0xef;for(c=0;c<8;c++){CLK=0;DAT=num&0x80;CLK=1;}}void sendbyte_5(unsigned char byte) {unsigned char num,c;num=tab[byte];for(c=0;c<8;c++){CLK=0;DAT=num&0x80;CLK=1;num<<=1;}num=0xdf;for(c=0;c<8;c++){CLK=0;DAT=num&0x80;CLK=1;num<<=1;}}void sendbyte_6(unsigned char byte) {unsigned char num,c;num=tab[byte];for(c=0;c<8;c++){CLK=0;DAT=num&0x80;CLK=1;num<<=1;}num=0xbf;for(c=0;c<8;c++){CLK=0;DAT=num&0x80;CLK=1;num<<=1;}}void sendbyte_7(unsigned char byte) {unsigned char num,c;num=tab[byte];for(c=0;c<8;c++){CLK=0;DAT=num&0x80;CLK=1;num<<=1;}num=0x7f;for(c=0;c<8;c++){CLK=0;DAT=num&0x80;CLK=1;num<<=1;}}//延时~~void delay(){unsigned int j;for(j=0;j<250;j++);}main(){loading();while(1){a=hour/10; b=hour%10;c=minite/10;d=minite%10;e=second/10;f=second%10;ch=10;sendbyte(f);delay();sendbyte_1(e);delay();sendbyte_2(ch);delay();sendbyte_3(d);delay();sendbyte_4(c);delay();sendbyte_5(ch);delay();sendbyte_6(b);delay();sendbyte_7(a);delay();}}void time(void) interrupt 1 {unsigned int tt;tt++;if(tt==3600){tt=0;second++;if(second==60){second=0;minite++;if(minite==60){minite=0;hour++;if(hour==24)hour=0;}}}}此程序还有很多不足~希望单片机高手们来给我看一下~~~提一些好的建议吧~~。
单片机应用设计课题:串口连接两个74LS164驱动2个LED数码管显示班级学号: 14110501xx 姓名: xx1设计要求1.1 设计内容设晶体为12MHz,将拨码开关数据串行输入到74LS164,并行输出到2个LED 数码管进行相应的数码显示。
设计包括:系统设计分析、系统原理图设计、程序流程图设计、源程序设计、系统调试与仿真及调试结果分析、对本课程学习的感想与收获、对老师的意见与建议、期望成绩等。
1.2 学习目的该作业具有较强的实用性,许多同学已经认识到自己完全有能力设计一个实用的单片机应用系统,对单片机设计由感兴趣已经变为爱好了,为后面的实际应用系统设计奠定了较好的基础。
2 系统设计分析2.1 单片机最小系统+串口+74LS164+LED数码管单片机的最小系统是单片机能够工作的最小硬件组合,对于8051系列单片机,其电路的最小系统大致相同,主要包括电源、晶体振荡电路、复位电路等。
2.1.1 串口数据通信方式包括并行通信和串行通信两种。
并行通信就是多条数据线上同时传送,其优点:速度快,只适于近距离通信。
串行通信就是数据以为以为的顺序传送,其优点:线路简单,成本低,适合远距离通信。
串行通信方式包括:异步串行通信和同步串行通信。
异步方式,数据传送不连续,时间间隔任意。
同步方式,发送与接收同步。
数据传送方式:单工、半双工、全双工、多工。
常见的串行通讯有:RS-232、RS-485、CAN总线等。
串行口控制寄存器包括:串行口控制寄存器SCON(控制工作方式)、电源控制寄存器PCON(控制波特率)。
SM0、SM1选择工作方式,SM2用于多机通信,REN允许接收控制位,TB8/RB8发送/接收数据D8位,TI/RI为发送/接收中断标志位。
2.1.2 74LS164串行口工作于方式0,发送数据时,是把串行端口设置成“串入并出的”输出口。
将它设置为“串入并出”输出口时,需外接1片“串入并出”同步移位芯片74LS164或CD4094,本次设计,用74LS164。
我也是研究了好几天才开发明白的所以废话不多少,直接上硬货一,代码部分:(1)相关寄存器配置:串行口控制寄存器SCON串行口控制寄存器SCON的格式D7 D6 D5 D4 D3 D2 D1 D0SCON SM0 SM1 SM2 REN TB8 RB8 TI RI 98H 位地址9FH 9EH 9DH 9CH 9BH 9AH 99H 98HSM0、SM1——串行口的4种工作方式选择位SM0 SM1 方式功能0 0 0 同步移位寄存器方式0 1 1 8位异步收发,波特率由定时器控制1 02 9位异步收发,波特率为时钟频率的1/64或者1/32 1 13 9位异步收发,波特率由定时器控制寄存器的十六进制操作控制:复习一下例子:SCOM = 0x020X02的0代表在高八位,2的位置代表在低八按照8421 8421顺序操控scon SM0 SM1 SM2 REN TB8 RB8 TI RI8 4 2 1 8 4 2 1还不懂的画再来一个例子明白了就跳过往下:例如问配置REN置1,发送8位时间置1,接收标志位置1怎么配置答:0x1A好接着往下:(1)代码原创:#include <reg52.h>#include <intrins.h>unsigned char count;sbit ST_CP = P3^5; //P3^5 串行锁存寄存器时钟RCK,上升沿有效void main(){SCON = 0x00;//工作方式0while(1){for(count=0;count<8;count++){SBUF = 0x55;while(!TI)TI = 0;//左移一位将高位补给低位,如果二进制数为01010101 那么_crol_(1) 为10101010}ST_CP = 1;_nop_();_nop_();ST_CP = 0;for(count=30000;count>0;count--);//串口通信太快了,延时一下方便看示波器时序}}(1)代码解析51单片机通过直接操控SBUF寄存器会自动启动发送8位数据,期间TXD作为时钟线,每发送一位都会置1一次时钟线TXD,因此74HC595的SCK引脚只需连接51芯片的TXD引脚即可,51单片机会自动拉高拉低发送.二,protues仿真部分:(1),74HC595引脚功能:9 脚:串行数据出口引脚。
下面是74ls164 驱动共阳数码管的演示程序,电路请看附件#i nclude<reg51.h>#define uint unsigned int#define uchar unsigned charsbit DAT=P1^1; //模拟串口数据发送端sbit CLK=P1^2;//模拟时钟控制端uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};//0-9,-,全灭(共阳字段表)void sendbyte(uchar byte){uchar num,c;num=tab[byte];for(c=0;c<8;c++){CLK=0;DAT=num&0x80; //(0x80即十进制的128, 二进制的10000000 按位发送)CLK=1;num<<=1;}}void delay_50ms(unsigned int t) //50MS演示程序{unsigned int j;for(;t>0;t--)for(j=6245;j>0;j--){;}}main(){unsigned char h;while(1){for(h=0;h<10;h++){delay_50ms(1);sendbyte(h);delay_50ms(10);}h=0;}}下面这段是74ls164 驱动共阴数码管的程序源码#i nclude<reg51.h>#define uint unsigned int#define uchar unsigned charsbit DAT=P1^1;sbit CLK=P1^2;uchar code tab[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xff,0xf6};//0-9,-,全灭void sendbyte(uchar byte){uchar num,c;num=tab[byte];for(c=0;c<8;c++){CLK=0;DAT=num&0x01;CLK=1;num>>=1;}}void delay_50ms(unsigned int t){unsigned int j;for(;t>0;t--)for(j=6245;j>0;j--){;}}main(){unsigned char h;while(1){for(h=0;h<10;h++){delay_50ms(1);sendbyte(h);delay_50ms(10);}h=0;}}0人 | 分享到:阅读(305)| 评论(0)| 引用(0) |举报。
多位LDE数码管段位在线确认及段码数组的编写方法当我们拿到一块成品的多位LED数码管显示电路板,或将买到的多位LED数码管安装到电路板上后,首先需要做的工作就是为LED编制段码表,因为,只有编好段码表后才能对其进行编程控制,也就是我们在数码管驱动应用程序中见到段码数组,本文将就前文提到的两位数码管、经由串行输入/并行输出芯片74LS164控制显示的电路,进行段位编码,与有兴趣的朋友共享,或许有朋友会说,现在LED数码管的应用,多是由单片机的一个输出端口的8位I/O端控制8个段,用另一个输出端控制数码管位,很少用到164了,其实不然,商品板多为164或595控制,即使自己设计时,考虑到单片机控制端口的多少,是否够用等因素,这种串口控制的芯片也是不错的选择,况且,即使是单片机端口直接控制也是要根据实际接线顺序进行编码的,此时只要更改一下程序中的输出语句即可;闲言少叙,书归正传;以AT89S51单片机为例,首先,连接好线路,164的数据输入端DAT连接单片机的RXD端,164的外部时钟端CLK连接单片机的TXD端,两个共阳极与+5V电源端连接;至于164的8个输出端经限流电阻与数码管连接的电路图在本空间相册中能够找到,仿制一下很容易的,不同之处在于,这种共数据端多公共极的模块,不论多少位数码就用一片164就可以了,在此就不多说了。
编程如下:#include<at89x51.h>main(){while(1){SBUF=0x80 ;while(!TI);TI=0;}}接下来画一张11行10列的草图,而后编译并下载上面这段程序,在电路连接正确时,必有一段被点亮(或未被点亮),此时在表格左侧第一行的第二个位置开始填入被点亮段的代号,(代号的定义见上篇文章附图)而后,将程序中的0x80依次更换为0x40;0x20;0x10;0x08;0x04;0x02;0x01并逐次编译下载,结果填入表内,最终得到全部段码代号的排列顺序,据此根据74LS164输出共阳极控制“0亮”、“1灭”的原则,得出各数字字符编码,见以下附图:到此,这个两位LED数码模块就可以编程应用了。
74HC164应用实例:驱动数码管两例(电路图和源程序)————————————————————————————————作者:————————————————————————————————日期:4HC164应用实例:驱动数码管两例(电路图和源程序) 文章编号:100816210758 文章分类: 电路 > 电子元件 点击:... 关键词: 74HC164文章来源:百合电子工作室收集整理 摘要: 74HC164应用实例:驱动数码管的两个实例分别提供了汇编源程序和C 源程序...实例174HC164是串行输入,并行输出接口器件,可用在单向的并行输出/并行地址锁存等. 74HC164因为价格便宜,容易使用特别适合使用在在需要用到数码管显示IO 口又比较紧张的电子产品中,下面浅谈使用方法:1. 首先先了解他的引脚功能和逻辑图,如下图:图1 引脚名称和用途图2 真值表通过真值表我们可以了解到,A,B两个输入端是互锁的,CLK上升沿时数据移入移位寄存器中,CLEAR为清零用的,接低电平时所有端口都输出低电平,了解了真值表之后开始运用了,先给出如下原理图:图3 原理图图中,采用义隆的EM78P153作为控制芯片,P50作为CLK时钟信号,注意平时数据不传输时,时钟信号是不发送的应一直保持低电平或者高电平,数据需要传输的时候才输出时钟信号^_^ ,继续P51作为移位数据输出端,接到74HC164的B端,A端接高电平,当然也可以AB端短路,然后连接到DATA移位数据端,P52作为数码管的选通信号(也可以叫消隐^_^), 作用是使数据传输过程暂时关闭显示,以免显示出不需要的数据,原因是应为164不带锁存功能,数据传输过程是一位一位的向高位移位输出的,所以要等数据全部移入后才打开始点亮数码管.注意了哦,通过查看164的规格书发现,164输出高电平电流比输出低电平电流要小,亦称灌电流大,扇出电流弱,所以适合选用共阳数码管,如图,本人偷懒没有画出那个数码管的8字该介绍的介绍的差不多了,废话少说,该开始干活了,任务是: 显示0-9 每秒+1 ,到9后又返回0,一直循环显示,根据任务得到如下流程图:1. 显示部分:将需要显示的数值送入A ==>查表求得显示段码==>将段码逐位移入164==>8位移完后点亮数码管==>延时==>返回第一步执行2. 中断部分:进入中断==>保存现场(以备调查取证,送你入狱^_^)==>重置TCC==>够1秒钟将需要显示的数据+1,并重置,不够就退出;根据以上要求就开始写代码调试了,要注意一点,数据移位时一定要记得高位在前哦,否则显示错误别怪我没有说清楚,我当年实验时就因为这个数据移位方向反了排查了半天,甚至以为是时钟频率不对,又以为时许不对.....搞了半天,NND后来重看DATASHEET才发现,原来是低级错误啊,呜呼哀哉.......,希望你不要重蹈我覆辙,哎哟!! 谁! 谁! 谁扔砖头上来? 啥? 你扔的? 我废话太多.........,那俺少来两句,继续上菜, 咦好像没啥可说的了,上源程序吧1.;中断部分:2.3.;;;;;;;;;;中断;;;;;;;;4.INTPUT:5.MOV TEMPA, A;6.MOV A,@130;7.MOV TCC,A;255-130=1258.CLR RF;9.;;;;;此处填写250Us处理程序10. BS WKREG,T500US11.;;;;;;;;;;;;;;;;;;;;;;;;;12. DJZ R1MS13.JMP INTEXT;14.MOV A,@415.MOV R1MS,A;重置16. BS WKREG,T1MS17.;;;;;;;此处填写1ms处理程序18.19.;;;;;;;;;;;;;;;;;;;;;;;;;;20. DJZ R20MS21.JMP INTEXT;22.MOV A,@2023.MOV R20MS,A;重置24.;;;此处填写1秒处理程序25. BS WKREG,T20MS26.;;;;;;;;;;;;;;27. DJZ R1S28.JMP INTEXT;29.MOV A,@5030.MOV R1S,A;31.;;;;;;;;;32.INC NUMBER33.MOV A,NUMBER34. SUB A,@1035. JBS SR,236.JMP INTEXT37.MOV A,@038.MOV NUMBER,A39.40.41. INTEXT:42.MOV A,TEMPA;43.RETI;;;;;;;;;;;;;;;;;;;;;44.45.46.47.48.49.;显示部分:50.51.;==============TXDATA==============52.TXDATA:53. BS P5,CC154.MOV A,@855.MOV DATALOP,A;56.TXLOP:57. BC WKREG,T500US58. BS P5,CLK;clk=高59.NOP;60.NOP61. JBS DATA_BUF,762.JMP $+363. BS P5,DATA;64.JMP $+265. BC P5,DATA66.DD1MS: JBS WKREG,T500US67.JMP $-168. BC P5,CLK69. BC WKREG,T500US70. JBS WKREG,T500US71.JMP $-1;72.RLC DATA_BUF73. DJZ DATALOP74.JMP TXLOP75.;;;;;;;;;;76. BC WKREG,T500US77. BS P5,CLK;clk=高78. BC WKREG,T500US79. JBS WKREG,T500US80.JMP $-1;81. BC P5,CLK82.;;;;;;;;83. BC P5,CC184.85.RET;;;;;;;86.87.;数据查表88.;===============DSPTBL============89.DSPTBL: ADD PC,A90. RETL @0B01000000;091. RETL @0B01111001;192. RETL @0B00100100;293. RETL @0B00110000;394. RETL @0B00011001;495. RETL @0B00010010;596. RETL @0B00000010;697. RETL @0B01111000;798. RETL @0B00000000;899. RETL @0B00010000;9100.101.102.;循环体部分;103.104.;;;;;;;;;;主程序;;;;;;;;;;;105.MLOOP:106.MOV A,NUMBER107.CALL DSPTBL108.MOV DATA_BUF,A109.CALL TXDATA110. BC WKREG,T1MS111. JBS WKREG,T1MS112.JMP $-1113.NOP;114.115.JMP MLOOP;;;;;;;;;;;;;;;;;;;;实例2在实际应用中驱动数码管常用的方式分动态扫描和静态驱动。
单片机应用设计课题:串口连接两个74LS164驱动2个LED数码管显示班级学号: 14110501xx 姓名: xx1设计要求1.1 设计内容设晶体为12MHz,将拨码开关数据串行输入到74LS164,并行输出到2个LED 数码管进行相应的数码显示。
设计包括:系统设计分析、系统原理图设计、程序流程图设计、源程序设计、系统调试与仿真及调试结果分析、对本课程学习的感想与收获、对老师的意见与建议、期望成绩等。
1.2 学习目的该作业具有较强的实用性,许多同学已经认识到自己完全有能力设计一个实用的单片机应用系统,对单片机设计由感兴趣已经变为爱好了,为后面的实际应用系统设计奠定了较好的基础。
2 系统设计分析2.1 单片机最小系统+串口+74LS164+LED数码管单片机的最小系统是单片机能够工作的最小硬件组合,对于8051系列单片机,其电路的最小系统大致相同,主要包括电源、晶体振荡电路、复位电路等。
2.1.1 串口数据通信方式包括并行通信和串行通信两种。
并行通信就是多条数据线上同时传送,其优点:速度快,只适于近距离通信。
串行通信就是数据以为以为的顺序传送,其优点:线路简单,成本低,适合远距离通信。
串行通信方式包括:异步串行通信和同步串行通信。
异步方式,数据传送不连续,时间间隔任意。
同步方式,发送与接收同步。
数据传送方式:单工、半双工、全双工、多工。
常见的串行通讯有:RS-232、RS-485、CAN总线等。
串行口控制寄存器包括:串行口控制寄存器SCON(控制工作方式)、电源控制寄存器PCON(控制波特率)。
SM0、SM1选择工作方式,SM2用于多机通信,REN允许接收控制位,TB8/RB8发送/接收数据D8位,TI/RI为发送/接收中断标志位。
2.1.2 74LS164串行口工作于方式0,发送数据时,是把串行端口设置成“串入并出的”输出口。
将它设置为“串入并出”输出口时,需外接1片“串入并出”同步移位芯片74LS164或CD4094,本次设计,用74LS164。
74LS164是8位边沿触发式移位寄存器,具有DIP、SO14等多种封装形式。
其DIP封装形式如右图所示。
数据通过A或B之一串行输入,任一输入端可以用作高电平使能端控制另一输入端的数据输入,两个输入端或者连接在一起,或者把不用的输入端接高电平,一定不要悬空。
时钟CP每次由低变高(边沿触发)时,数据右移一位输入到Q0。
Q0是两个数据输入端A和B的逻辑与。
输入的数据在Q0输出,并依次右移在其它输出端口输出。
2.1.3 LED数码管LED数码管是单片机应用系统中常用的输出设备,其特点结构简单,价格便宜。
单片机系统常用7段LED数码管,由8个发光二极管构成。
LED数码管分为共阳极和共阴极两种。
共阳极LED数码管,就是8个LED阳极连接在一起再接高电平。
共阴极LED数码管,就是8个LED阴极连接在一起再接地。
通过相应的LED显示,呈现出对应的数字、符号。
2.2 ‘串入并出’驱动LED数码管显示本次设计,对拨码开关进行拨动,从而将信息传递给单片机,再由单片机通过串口工作在方式0将数据串行输出给74LS164,由74LS164并行输出给LED数码管,进行相应的显示。
实际操作中,拨码开关低四位控制一个74LS164驱动一个LED数码管,而拨码开关高四位控制另一个74LS164驱动另一个LED数码管,使两个LED数码管独立显示。
本次设计涉及到,串口工作方式。
串口工作于方式0时,其功能为8位移位寄存器,相当于I/0口的扩展,再连接74LS164芯片既可实现“串入并出”的功能。
使用查表法,将拨码开关的2进制数和LED代码建立一一对应关系,其中用到了一些编程小技巧。
设计中,又遇到另外一个问题,74LS164级联问题,我在网上搜寻了一些问题的答案,再看了书上对74LS164的介绍,于是得到了算是一些结论吧。
将74LS164最后一个输出端,连在另外一个74LS164的A、B之一的数据输入端,就构成了级联。
在程序中每一次循环向串口缓存器发送两次8位数据,即可实现两个LED数码管独立显示(0~F)。
3 系统原理图设计3.1 元器件及其型号系统所需元器件包括:AT89C51、瓷片电容CAP30pF、晶振CRYSTAL、电阻RES、电解电容22uF、共阳数码管7SEG-COM-AN-GRN、拨码开关DIPSW_8、74LS164-IEC、总线。
系统设计原理图如图3.1所示。
图3.1 系统设计原理图4 系统程序流程图设计4.1 系统程序设计流程图如下图所示5 系统源程序设计5.1 程序设计思路本次设计,我一共有三个思路:1.在74LS164的输出口并接两个数码管,然后分别将两个共阳数码管的共阳端随意接两个I/O口,通过I/O口控制某个数码管对应低四位或高四位拨码开关,进行相关显示(0~F)。
2.用两个74LS164分别接两个共阳数码管,通过控制每个74LS164的A、B输入端,从而进行相关显示(0~F),和思路1相似。
3.用两个74LS164级联的方式,实现两个共阳数码管分别对应低四位或高四位拨码开关,独立显示,比思路1、2复杂,也是我最满意并采用的思路。
5.2 源程序代码(思路3)5.2.1 汇编语言程序:ORG 0030H ;起始地址MAIN:MOV SCON,#00H ;设置串口工作方式为方式0MOV DPTR,#TABLE ;将表TABLE的首地址传给DPTRMOV 30H,#00H ;30H~7FH数据缓存区相当于变量的地址READ: MOV A,P1CJNE A,30H,SEND ;查询拨码开关是否有变化JMP READSEND:MOV 30H,ACPL A ;取反,变为16进制数据MOV R0,AANL A,#00FH ;取拨码开关低四位MOVC A,@A+DPTR ;查表赋值MOV SBUF,AWAIT1: JBC TI,X1 ;判断是否发送完毕AJMP WAIT1X1: MOV A,R0ANL A,#0F0H ;取拨码开关高四位SWAP A ;高低四位互换,建立对应关系MOVC A,@A+DPTR ;查表赋值MOV SBUF,AWAIT2: JBC TI,READ ;判断是否发送完毕AJMP WAIT2TABLE:DB 0C0H,0F9H,0A4H,0B0H,99H,92H ;LED代码(0~F)DB 82H,0F8H,80H,90H,88H,83HDB 0C6H,0A1H,86H,8EH,1BHEND5.2.2 C 语言程序:#include"reg51.h"#define uint unsigned int#define uchar unsigned charconst uchar tab[]={0xC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0x80,0X90,0X88, 0X83,0XC6,0XA1,0x86,0X8E}; //LED代码(0~F)void main(void){uchar i=0; //变量初始化uchar j=0;uchar m=0;uchar k=0;SCON=0X00; //设置串口工作方式为方式0SBUF=0XC0;while(TI==0);TI=0;while(1){while(P1==i); //查询拨码开关是否有变化i=P1;j=~i;m=j&0xf0; //取拨码开关高四位k=j&0x0f; //取拨码开关低四位m=m>>4; //高四位移到低四位建立对应关系SBUF=tab[k]; //查表赋值while(TI==0); //判断是否发送完毕TI=0;SBUF=tab[m]; //查表赋值while(TI==0); //判断是否发送完毕TI=0;}}6 仿真及调试结果分析6.1 仿真及调试结果系统仿真结果图如图6.1所示。
图6.1 系统仿真结果图6.2结果分析及调试过程这次作业是第四次设计了,基本已经熟悉设计过程,而且也锻炼了自己的编程能力。
这次设计3个思路,有3个C语言程序,一个汇编程序,从构思到调试成功,大概用了4个小时,并没有什么难度。
用前两个方案时,调试成功后,发现有缺陷(不能同时独立显示)。
于是,最终采用思路3,又用到一些编程小技巧,使程序较为精简,即可满足要求,两个LED独立显示(0~F)。
编程过程,十进制数与十六进制的兼容性也体现了出来,起初为了建立一一对应关系,还用了下switch语句,使之一一对应。
然而,后来想起了兼容性,就把程序大大缩短,变得精简。
另外,当LED数码管共阳端接的电阻为100欧时,LED无法显示“8”,而调下电阻后,就可以正常显示了。
明白,负载电阻大小会影响LED(亮度)显示。
本次设计,拨码开关接低电平,当开关闭合,使对应P1口置零,然后编程时,只需对P0口取反即可。
出于好奇,我又试了相反的接法,拨码开关接高电平,初始化P1口为0,当开关闭合,使对应P1口置1,于是编程就不需要对P0口取反,(C语言)也就省去了一个变量,虽然现实结果和第一种接发一样,但是,一些元器件出现了“黄色电平”,也就代表短路或者电平冲突。
所以,为了安全起见,还是采用了第一种解法。