| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> 郭天祥的10天学会51单片机_第三节 -> 正文阅读 |
|
[嵌入式]郭天祥的10天学会51单片机_第三节 |
单片机管脚,P3口有两个功能,上电默认情况下就使用P3口的普通IO口,当对单片机内部的某些寄存器设置时就启用P3口的第二个功能 P3^4和 P3^5可以作为计时器或定时器使用,给这两个口输入方波,进行计数 做一个频率计数器时,当是正弦波时加一个比较器变成方波,送给单片机的计数器端口,由程序来计数,当三角波通过积分变成方波,送给P3^4和 P3^5 XTAL1和XTAL2是外部晶振输入端 TX-1C型单片机实验板原理图中复位电路在右边晶振电路的下面,电容是通交隔直的,当S22按下,上边电路接通,10k和1k电阻分压,5V*10/11,接近5V,所以S22按下后复位;开始上电时也可以复位,通过电容充电,下边电路出现电流,RST接10K电阻会分到电压,上电结束,电容放电,将电通过10K电阻,10K电阻接地,将电流放掉 晶振在复位电路的上面,30P的电容指的是30PF,两个电容是帮助晶振起振;11.0592M的晶振用30P的电容,6M的晶振用20P的电容 20管脚是Vss接地 29管脚是PSEN,一般不用 30管脚是ALE/PROG,PROG编程时用,编程时给31 管脚Vpp端加12V电压才能写入程序;ALE可以输出1/6时钟周期的方波,检测单片机是否正常工作,就用示波器接ALE,看输出是否是1/6个晶振频率的方波 31管脚的EA,见书P11,选择内部存储器或外部存储器;一般EA接高电平,从内部存储器执行 见书P11的2.3.3,P0口是8位三态双向IO口,P1、P2和P3是8位准双向IO口;三态是高电平,低电平和高阻态;P0口没有上拉电阻,P1、P2和P3有上拉电阻;P1、P2和P3是8位准双向IO口,是在输入时要先写个1,然后才能输入,即准备一下才能输入 见书P16,P26,复位时,P0口、P1、P2和P3口是0xff,其它寄存器全部清零 LED、LCD显示器有两种显示结构:段显示(7段、米字型等)和点阵显示(5×8、8×8点阵等) 设计单片机时,一定要给P0口加上拉电阻,电阻值是10K,接法见课件PPT的LESSON3_数码管静态显示及定时器和中断应用的P11 数码管内部由8个发光二极管构成 单片机P26连接段锁存端(DULA),P27连接位锁存端(WELA),见电路设计图 快速复制的小技巧:一直按住SHIFT,按下HOME,然后按下DELETE,再按两次INSERT ? 晶振6MHz对应20pF,晶振12MHz对应30pF ?LED显示器分为“共阴极和共阳极两类,见上图,左端为共阴极,右端为共阳极 位选(WE)(程序中为wela):选中一位,单片机上共六个数码管,每一个数码管即一位 段选(程序中为dula):控制一个数码管哪几段亮 见上图共阴极a图,简单的说位选就是位选是右边的接地(第二个锁存器给相应的位WE赋给低电平),段选就是左边的八个管脚(第一个锁存器给相应的段DU赋给低电平) 本教程用共阴极,共阴极就是发光二极管的共阴极接在一起,共阴极的地端就是位选线(对应TX-1C型单片机实验板原理图中的WE),比如给共阴极高电平就不会让该数码管亮,即控制哪个数码管亮,也可以理解成控制哪个位的数码管亮;a到g和dp是段选线,即控制这个数码管的哪几段亮,来显示相应的数字 TX-1C型单片机实验板原理图中的六个数码管的管脚不必管,只要看要显示的数字和锁存器74HC573的位,因为要用单片机直接控制锁存器74HC573 让发光二极管全亮,就给八个二极管高电平,二极管的右边送低电平就可以 一个char型变量是8位,因为要写一个字需要8个位,一个int型的变量是16位 TX-1C型单片机实验板原理图中的六个LED就是数码管,LED图中的内部管脚标错了,外部管脚标的是对的,WE1是共阴极端,即段选端,六个数码管所有的段选都是连在一起的,位选是独立开的,通过位选控制某一个数码管亮,通过段选控制该数码管亮什么;见单片机左边的两个锁存器74HC573,第一个锁存器控制数码管的段选,第二个控制数码管的位选,锁存器的输入端是D0到D7,单片机左边紧靠的是10K的上拉电阻,因为P0口是8位三态双向IO口,无法进行低电平或高电平的操作,加个上拉电阻之后一上电就是高电平,然后单片机的P0口通过上拉电阻输入到锁存器;锁存端是高电平时,输入端和输出端是直通的,锁存端是低电平时,输入端和输出端是断开的,输出端保持原来的值,所以先给位选的锁存器的锁存端(WELA)高电平,并控制选择要亮的数码管,然后拉低锁存端,保持住选择的数码管,再把段选的锁存器(DULA)打开,将其锁存端拉高,输入要显示的段,再将锁存端拉低,保持住要显示 锁存器的锁存端一个下降沿将数据保持在锁存器的输出端 两个锁存器的锁存端DULA和WELA分别连接单片机的P2^6口和P2^7口, CSAD是锁存器的片选,高电平有效 共阴数码管码表:
见实验板原理图,LED数码管的管脚8连接WE,就是控制该数码管是否使用 看U2:WELA控制“位”, 想让第一个数码管亮,让WE1=0(共阴极的地端就是位选线,选择哪个数码管,对应位选应该赋给低电平),WE2到WE6和13、12口都为1,即十六进制的fe #include<reg52.h> sbit dula=P2^6; sbit wela=P2^7; void main() { ?????? wela=1;//位选锁存器打开 ?????? P0=0xfe;//第一个数码管亮, 如果要显示两个就P0=0xfc ?????? wela=0;//位选锁存器关闭,数据保持 ?????? dula=1;//段选锁存器打开 ?????? P0=0x06;//显示数字1,如果要显示0就,P0=0x3f ?????? dula=0;//段选锁存器关闭,数据保持 ?????? while(1); } 见课件PPT的LESSON3_数码管静态显示及定时器和中断应用,单片机内部的电流很弱,不足以点亮发光二极管,所以要加个上拉电阻用5V电压,才能点亮发光二极管 程序0到F的变化: #include<reg52.h> sbit dula=P2^6; sbit wela=P2^7; #define uint unsigned int #define uchar unsigned char uchar num;//用多大的变量就定义相应的类型 uchar code table[]={? ? ? ? ? ? ? 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void delay(uint z); void main() { ?????? while(1) ?????? { ????????????? wela=1; ????????????? P0=0xc0;//所有数码管全亮 ????????????? wela=0; ????????????? for(num=0;num<16;num++) ????????????? { ???????????????????? dula=1; ???????????????????? P0=table[num]; ???????????????????? dula=0; ???????????????????? delay(1000); ????????????? } ?????? } } void delay(uint z)//经测试得:z=1时是一毫秒 { ?????? uint x,y; ?????? for(x=z;x>0;x--) ????????????? for(y=110;y>0;y--); } 第一三五数码管亮: #include<reg52.h> sbit dula=P2^6; sbit wela=P2^7; #define uint unsigned int #define uchar unsigned char uchar num; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void delay(uint z); void main() { ?????? wela=1; ?????? P0=0xc0;//所有数码管全亮 ?????? wela=0; ?????? while(1) ?????? { ???????????????????? for(num=0;num<16;num++) ????????????? { ???????????????????? dula=1; ???????????????????? P0=table[num]; ???????????????????? dula=0; ???????????????????? delay(1000); ????????????? } ?????? } } void delay(uint z) { ?????? uint x,y; ?????? for(x=z;x>0;x--) ????????????? for(y=110;y>0;y--); } 中断:见书P54P55 单片机的核心就是中断,定时器,串口通信 P3.2口控制外部中断0,给低电平时进行中断0 置位表示置1 中断优先级: ? 中断序号:0,1,2,3,4,对应上表中的从高到低的顺序中断,外部中断0中断序号是0 中断响应条件: 中断源有中断请求;例如设定中断函数void exter0() interrupt 0 此中断源的中断允许位为1;例如开外部中断0,让IE0=1 CPU开中断(即EA=1)。 以上三条同时满足时,CPU才有可能响应中断。 寄存器的位数能被8整除的寄存器都可以直接进行位寻址,位寻址就是可以直接操作某一位 用杜邦线一端接地一端接P3.2口,即给P3.2口低电平,小灯亮,产生中断,数码管显示数字不变,拔掉杜邦线数码管数字变化: #include<reg52.h> sbit dula=P2^6; sbit wela=P2^7; sbit d1=P1^0; #define uint unsigned int #define uchar unsigned char uchar num; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void delay(uint z); void main() { ??? EA=1;//开总中断 ?????? IT0=0;//IT0=0为电平触发方式,IT0=1为跳沿触发方式 ?????? //IT0=1也可以设置为TCON=0x01; ?????? EX0=1;//开外部中断0,P3.2口有低电平时进行中断0,中断设置好就跳到中断函数处执//行中断函数 ?????? wela=1; ?????? P0=0xea;//所有数码管全亮 ?????? wela=0; ?????? while(1) ?????? { ???????????????????? for(num=0;num<16;num++) ????????????? { ???????????????????? d1=1; ???????????????????? dula=1; ???????????????????? P0=table[num]; ???????????????????? dula=0; ???????????????????? delay(1000); ????????????? } ?????? } } void delay(uint z) { ?????? uint x,y; ?????? for(x=z;x>0;x--) ????????????? for(y=110;y>0;y--); } IT0=0为电平触发方式,用杜邦线的两端连接地和P3.2口发光二极管一直亮,数码管一直不变,即一直在中断程序中,直到杜邦线断开;IT0=1为跳沿触发方式,用杜邦线连上,发光二极管亮一下就熄灭,即使杜邦线一直连着二极管也不亮,数码管继续变化,即中断一下跳变沿结束中断就结束,返回主程序 一般中断是设置成跳变沿触发方式,因为如果设置成电平触发方式容易忘记在程序中再给P2.3口高电平,回不去主程序,结束不了中断 void exter0() interrupt 0//interrupt表示中断服务程序, //interrupt后面的0表示中断序号,中断序号:0,1,2,3,4,中断序号是几就对应哪个中//断;中断函数不需要声明 { ?????? d1=0;????? } 由溢出时计数器的值减去计数初值才是加1计数器的计数值。 计数器就是连接P3.4口或P3.5口就自动计数 计数器来源于T0或T1引脚输入的外部脉冲源,定时器来源是由系统的时钟振荡器输出脉冲经12分频后送来(即每12个振荡周期即一个机器周期,计数器加1) TCON的低4位用于控制外部中断,已在前面介绍。TCON的高4位用于控制定时/计数器的启动和中断申请。其格式如下: ? 其中TF1和TF0是由单片机自动控制,这里不用管它,我们只需考虑TR1和TR0,这里我们只用TR0控制定时器T0,TR0置1时,T0开始工作,TR0置0时,T0停止工作 两个十六位定时器最大定时65ms(65536us约等于65ms) 设置为定时器模式时,加1计数器是对内部机器周期计数(1个机器周期等于12个振荡周期,即计数频率为晶振频率的1/12)。计数值N乘以机器周期Tcy就是定时时间t 。 初始化程序应完成如下工作:
思路:定时1s:进行20次中断,每次中断进行的时间是50ms并且对一个变量加1,进入一次中断就加1,一直加到20次,在主程序中进行判断,一旦到20让数码管变化一次 #include<reg52.h> sbit dula=P2^6; sbit wela=P2^7; sbit d1=P1^0; #define uint unsigned int #define uchar unsigned char uchar num,tt; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void main() { ?????? num=0; ?????? tt=0; ?????? TMOD=0x01;//设置定时器0为工作方式1,C/T=0为定时模式, GATE=0用软件控制 ?????? TH0=(65536-50000)/256; ?????? TL0=(65536-50000)%256; ??? EA=1;//开总中断 ?????? ET0=1;//开定时器0中断 ?????? TR0=1;//启动定时器0,定时器就开始工作,计数器就开始计数,50ms一到就进入中断 //程序中 ?????? wela=1; ?????? P0=0xea;//所有数码管全亮 ?????? wela=0; ?????? dula=1; ?????? P0=0x3f;//开始时要给数码管一个要显示的数字,否则会出现乱码 ?????? dula=0; ?????? while(1) ?????? { ????????????? if(tt==20) ????????????? { ????????????? ????? tt=0; ???????????????????? num++; ???????????????????? if(num==16) //因为num计数到16就找不到值了 ???????????????????? num=0; ???????????????????? dula=1; ???????????????????? P0=table[num]; ???????????????????? dula=0; ????????????? } ?????? } } void exter0() interrupt 1//定时器中断0中断序号为1 { ?????? TH0=(65536-50000)/256;//50000表示50毫秒,即经过50毫秒中断一次,TH0和TL0 //是设定的初值,从初值开始计数到65536就经过50毫秒 ?????? TL0=(65536-50000)%256;//因为当定时器计数值满再加1变成0才能从主程序进入中断//后,此时定时器的计数值为0,这里要重新装一次值,再进行计数,下一次50ms后才能再//次进入中断,否则定时器的计数值会从0开始,一直计数到65536才再次进入中断 ?????? tt++; } 课件作业: 利用定时/计数器T0从P1.0输出周期为1s的方波,让发光二极管以1HZ闪烁,设晶振频率为12MHz:重点就是让P1.0口正负正负不断变化 我的方法: #include<reg52.h> #define uchar unsigned char sbit D1=P1^0; uchar flag,tt; void main() { ????????????? tt=0; ????????????? //D1=1; ????????????? TMOD=0x01; ????????????? TH0=(65536-50000)/256; ????????????? TL0=(65536-50000)%256; ????????????? EA=1; ????????????? ET0=1; ?????? ?????? TR0=1; ?????? while(1) ?????? {???? ????????????? if(tt==10) ????????????? { ???????????????????? tt=0;???????????????????? ???????????????????? D1=~D1;?????????????? ????????????? } ?????? } } void inter0() interrupt 1 { ?????? TH0=(65536-50000)/256; ?????? TL0=(65536-50000)%256; ?????? tt++; } 课件的方法: #include<reg52.h>? //52单片机头文件 #define uchar unsigned char? //宏定义 sbit P1_0=P1^0; uchar tt; void main()?????????? ??? //主函数 { ?????? TMOD=0x01;//设置定时器0为工作方式1 ?????? TH0=(65536-50000)/256; ?????? TL0=(65536-50000)%256; ?????? EA=1;//开总中断 ?????? ET0=1;//开定时器0中断 ?????? TR0=1;//启动定时器0 ?????? while(1);//等待中断产生 ?????? } void timer0() interrupt 1 { ?????? TH0=(65536-50000)/256; ?????? TL0=(65536-50000)%256; ?????? tt++; ?????? if(tt==20)//直接在中断函数里进行方波程序 ?????? { ????????????? tt=0; ????????????? P1_0=~P1_0; ?????? } } 利用定时/计数器T1产生定时时钟,由P1口控制8个发光二极管,使8个指示灯依次一个一个闪动,闪动频率为10次/秒(8个灯依次亮一遍为一个周期),循环: 我的方法: #include<reg52.h> #include <intrins.h> #define uint unsigned int #define uchar unsigned char uint num,tt; void main() { ?????? uchar a; ?????? TMOD=0x10; ?????? TH0=(65536-50000)/256; ?????? TL0=(65536-50000)%256; ?????? EA=1; ?????? ET1=1; ?????? TR1=1; ?????? a=0xfe; ?????? while(1) ?????? { ????????????? if(tt==2) ????????????? { ???????????????????? tt=0; ???????????????????? P1=a; ????????????? ?????? a=_crol_(a,1); ????????????? } ?????? } } void inter1() interrupt 3 { ?????? TH0=(65536-50000)/256; ?????? TL0=(65536-50000)%256; ?????? tt++; } 课件的方法: #include<reg52.h>? //52单片机头文件 #include <intrins.h> //包含有左右循环移位子函数的库 #define uint unsigned int??? //宏定义 #define uchar unsigned char? //宏定义 sbit P1_0=P1^0; uchar tt,a; void main()?????????? ??? //主函数 { ?????? TMOD=0x01;//设置定时器0为工作方式1 ?????? TH0=(65536-50000)/256; ?????? TL0=(65536-50000)%256; ?????? EA=1;//开总中断 ?????? ET0=1;//开定时器0中断 ?????? TR0=1;//启动定时器0 ?????? a=0xfe; ?????? while(1);//等待中断产生 ?????? } void timer0() interrupt 1 { ?????? TH0=(65536-50000)/256; ?????? TL0=(65536-50000)%256; ?????? tt++; ?????? if(tt==2) ?????? { ????????????? tt=0; ????????????? P1=a; ????????????? a=_crol_(a,1); ?????? } } 同时用两个定时器控制蜂鸣器发声,定时器0控制频率,定时器1控制同个频率持续的时间,间隔2s依次输出1,10,50,100,200,400,800,1k(hz)的方波: 我的方法:先做一下中断0控制一下蜂鸣器在300ms内以频率1响一下,再控制蜂鸣器以频率1和10响,再依次做下面的频率,思想是从简单到复杂,一步一步完成 在中断1中控制同个频率持续的时间,再用一个变量a来控制是以何种频率进行,为中断0做准备 #include<reg52.h> #define uint unsigned int #define uchar unsigned char sbit beep=P2^3; uint num,a,b; void main() { ?????? TMOD=0x11;//注意在中断0和中断1同时使用时要在TMOD中一起设置不要分开设置 ?????? TH1=(65536-50000)/256; ?????? TL1=(65536-50000)%256; ?????? EA=1; ?????? ET1=1; ?????? TR1=1; ?????? //TMOD=0x01; ?????? TH0=(65536-50000)/256; ?????? TL0=(65536-50000)%256; ?????? //EA=1; ?????? ET0=1; ?????? TR0=1; ?????? beep=0; ?????? while(1); } void inter1() interrupt 3 { ?????? TH1=(65536-50000)/256; ?????? TL1=(65536-50000)%256; ?????? num++; ?????? if(num==40) ?????? { ????????????? num=0; ????????????? a++; ????????????? if(a==8) ????????????? { ???????????????????? a=0; ????????????? } ?????? } } void inter0() interrupt 1 { ?????? if(a==0) ?????? { ????????????? TH0=(65536-50000)/256; ????????????? TL0=(65536-50000)%256; ????????????? b++; ????????????? if(b==20) ????????????? { ???????????????????? b=0; ???????????????????? beep=~beep; ????????????? } ?????? } ?????? if(a==1) ?????? { ????????????? TH0=(65536-50000)/256; ????????????? TL0=(65536-50000)%256; ????????????? beep=~beep; ????????????? b++; ????????????? if(b==2) ????????????? { ???????????????????? b=0; ???????????????????? beep=~beep; ????????????? } ?????? } ?????? if(a==2) ?????? { ????????????? TH0=(65536-20000)/256; ????????????? TL0=(65536-20000)%256; ????????????? beep=~beep; ?????? } ?????? if(a==3) ?????? { ????????????? TH0=(65536-10000)/256; ????????????? TL0=(65536-10000)%256; ????????????? beep=~beep; ?????? } ?????? if(a==4) ?????? { ????????????? TH0=(65536-5000)/256; ????????????? TL0=(65536-5000)%256; ????????????? beep=~beep; ?????? } ?????? if(a==5) ?????? { ????????????? TH0=(65536-2500)/256; ????????????? TL0=(65536-2500)%256; ????????????? beep=~beep; ?????? } ?????? if(a==6) ?????? { ????????????? TH0=(65536-1250)/256; ????????????? TL0=(65536-1250)%256; ????????????? beep=~beep; ?????? } ?????? if(a==7) ?????? { ????????????? TH0=(65536-1000)/256; ????????????? TL0=(65536-1000)%256; ????????????? beep=~beep; ?????? } ?????? b=0; } 课件的程序: #include<reg52.h>? //52单片机头文件 #include <intrins.h> //包含有左右循环移位子函数的库 #define uint unsigned int??? //宏定义 #define uchar unsigned char? //宏定义 sbit beep=P2^3; uchar tt; uint fre,flag; void main()?????????? ??? //主函数 { ?????? fre=50000; ?????? beep=0; ?????? TMOD=0x11;//设置定时器0,定时器1为工作方式1 ?????? TH0=(65536-fre)/256; ?????? TL0=(65536-fre)%256; ?????? TH1=(65536-50000)/256; ?????? TL1=(65536-50000)%256; ?????? EA=1;//开总中断 ?????? ET0=1;//开定时器0中断 ?????? ET1=1; ?????? TR1=1; ?????? TR0=1;//启动定时器0 ?????? while(1);//等待中断产生 ?????? } void timer0() interrupt 1 ??//定时器0中断 { ?????? TR0=0;??? //进中断后先把定时器0中断关闭,防止内部程序过多而造成中断丢失 ?????? TH0=(65536-fre)/256; ?????? TL0=(65536-fre)%256; ?????? tt++; ?????? if(flag<40)??? //以下几个if分别用来选取不同的频率,flag<40即第一个2s时间内 ????????????? if(tt==10) ???????????????????? { ??????????????????????????? tt=0; ??????????????????????????? fre=50000; ??????????????????????????? beep=~beep; ???????????????????? } ?????? if(flag>=40&&flag<80)//flag>=40&&flag<80即第二个2s时间内 ????????????? { ???????????????????? tt=0; ???????????????????? fre=50000; ???????????????????? beep=~beep;?? ????????????? } ?????? if(flag>=80&&flag<120) ????????????? { ???????????????????? tt=0; ???????????????????? fre=10000; ???????????????????? beep=~beep;?? ????????????? } ?????? if(flag>=120&&flag<160) ????????????? { ???????????????????? tt=0; ???????????????????? fre=5000; ???????????????????? beep=~beep;?? ????????????? } ?????? if(flag>=160&&flag<200) ????????????? { ???????????????????? tt=0; ???????????????????? fre=2500; ???????????????????? beep=~beep;?? ????????????? } ?????? if(flag>=200&&flag<240) ????????????? { ???????????????????? tt=0; ???????????????????? fre=1250; ???????????????????? beep=~beep;?? ????????????? } ?????? if(flag>=240&&flag<280) ????????????? { ???????????????????? tt=0; ???????????????????? fre=625; ???????????????????? beep=~beep;?? ????????????? } ?????? if(flag>=280&&flag<320) ????????????? { ???????????????????? tt=0; ???????????????????? fre=312; ???????????????????? beep=~beep;?? ????????????? } ?????? if(flag>=320&&flag<360) ????????????? { ???????????????????? tt=0; ???????????????????? fre=156; ???????????????????? beep=~beep;?? ????????????? } ?????? TR0=1; } void timer1() interrupt 3? //定时器1中断用来产生2秒时间定时 { ?????? TH1=(65536-50000)/256; ?????? TL1=(65536-50000)%256; ?????? flag++; ?????? if(flag==360) ?????? ? { ?????? ??? flag=0; ?????? ??? fre=50000;//因为到if(flag>=320&&flag<360)这步时fre回不到50000,所以这里还 //原一下fre ?????? ? } } 用定时器以间隔500MS在6位数码管上依次显示0、1、2、3….C、D、E、F,重复: 我的程序: #include<reg52.h> #define uint unsigned int #define uchar unsigned char sbit dula=P2^6; sbit wela=P2^7; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; uint num,a; void main() { ?????? num=0; ?????? a=0; ?????? wela=1; ?????? P0=0xc0; ?????? wela=0; ?????? TMOD=0x01; ?????? TH0=(65536-50000)/256; ?????? TL0=(65536-50000)%256; ?????? EA=1; ?????? ET0=1; ?????? TR0=1; ?????? dula=1; ?????? P0=0x3f; ?????? dula=0; ?????? while(1); } void inter0() interrupt 1 { ?????? TH0=(65536-50000)/256; ?????? TL0=(65536-50000)%256; ?????? num++; ?????? if(num==10) ?????? {???? ????????????? a++; ????????????? if(a==16) ????????????? { ???????????????????? a=0; ????????????? } ????????????? num=0; ????????????? dula=1; ????????????? P0=table[a]; ????????????? dula=0; ?????? } } 课件的程序: #include<reg52.h>? //52单片机头文件 #include <intrins.h> //包含有左右循环移位子函数的库 #define uint unsigned int??? //宏定义 #define uchar unsigned char? //宏定义 sbit dula=P2^6;?????? //数码管段选锁存端 sbit wela=P2^7;?????? 数码管位选锁存端 uchar num,tt; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void main() { ?????? num=0; ?????? tt=0; ?????? TMOD=0x01;//设置定时器0为工作方式1 ?????? TH0=(65536-50000)/256; ?????? TL0=(65536-50000)%256; ?????? EA=1;//开总中断 ?????? ET0=1;//开定时器0中断 ?????? TR0=1;//启动定时器0 ?????? dula=1; ?????? P0=0x3f;? //给段开始送显示0。 ?????? dula=0;//关闭段选锁存端,防止开始时出现乱码。 ?????? wela=1;//11101010 ?????? P0=0xc0; // 打开六个数码管位选 ?????? wela=0; ?????? while(1)//把数码管显示放到主程序里执行 ?????? { ????????????? if(tt==10)?? //每进入10次中断即为500ms,执行一次显示变化。 ????????????? ?? { ??????????????????????????? tt=0; ??????????????????????????? num++; ??????????????????????????? if(num==16) ??????????????????????????? num=0; ??????????????????????????? dula=1; ??????????????????????????? P0=table[num]; ??????????????????????????? dula=0;?? ???????????????????? } ?????? } } void exter0() interrupt 1??? // 定时器0中断 { ?????? TH0=(65536-50000)/256; ?????? TL0=(65536-50000)%256; ?????? tt++; } |
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 3:52:37- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |