单片机数码管C51程序
C51单片机数码管
引言概述:在嵌入式系统中,C51单片机是一种常用的微控制器,其广泛应用于各种数字显示设备中。
本文将深入探讨C51单片机数码管的二进制数码显示原理及应用,以及其与其他单元的连接方式和驱动方法。
正文内容:一、C51单片机数码管的工作原理1.二进制数码显示的基本原理2.C51单片机与数码管的连接方式3.C51单片机的引脚功能与数码管的位选和段选控制二、C51单片机数码管的编程方法1.C语言编程实现数码管的静态显示a.初始化数码管的引脚b.编写静态显示函数以及显示位数的控制c.数字转换和位选控制方法的实现2.C语言编程实现数码管的动态显示a.初始化数码管的引脚b.编写动态显示函数以及显示位数和刷新频率的控制c.使用定时器中断实现动态显示的驱动方法三、C51单片机数码管的扩展和复用1.使用74HC595芯片扩展数码管的显示位数a.74HC595芯片的功能和引脚配置b.C51单片机与74HC595的连接方式c.编程实现数码管的扩展方法2.同时驱动多个数码管的方法a.使用位选和段选控制进行扫描显示b.C51单片机与多个数码管的连接方式c.编程实现多个数码管的驱动方法四、C51单片机数码管的应用案例1.实现时钟的数码管显示功能a.数字时钟的硬件设计b.C51单片机编写时钟程序c.数码管显示时钟的驱动方法2.实现计数器的数码管显示功能a.计数器的硬件设计b.C51单片机编写计数器程序c.数码管显示计数器数值的驱动方法五、C51单片机数码管的注意事项和优化方法1.数码管亮度控制的方法2.误差校正和灵敏度调节3.多个数码管时序同步和抗干扰处理4.优化显示算法和降低功耗的方法总结:本文详细介绍了C51单片机数码管的设计原理、连接方法、驱动方式以及应用案例。
通过对每个大点的详细阐述,读者可以了解如何编写C语言程序来实现数码管的静态和动态显示,如何扩展和复用数码管,以及数码管的注意事项和优化方法。
希望本文对初学者和嵌入式开发爱好者提供了一些有用的指导和参考。
51单片机数码管显示程序设计
练习3主程序参考:
ORG 0000H LJMP START ORG 000BH LJMP T0SERV ;T0中断入口 ORG 0030H START: MOV SP,#50H ;初始化堆栈 LCALL INIT ;初始化 MOV DISBUF,#0 MOV DISBUF+1,#1 MOV DISBUF+2,#2 MOV DISBUF+3,#3 MOV DISBUF+4,#4 MOV DISBUF+5,#0 MOV FLASH,#11000000B MOV R0,#0 LOOP: MOV DISBUF+5,R0 LCALL DELAY INC R0 CJNE R0,#10,LOOP MOV R0,#0 AJMP LOOP
恢复现场
返回
动态显示参考程序1:定义变量
;--------------------------------------------------------;动态显示程序 ;--------------------------------------------------------;全局变量定义 FLAG EQU 20H ;标志位 DISSEG EQU P0 ;显示段驱动 DISBIT EQU P2 ;显示位驱动P2.7-P2.2 DISBUF EQU 21H ;显示缓冲区首地址21H-26H DISBITBUF EQU 27H ;当前显示位计数器0-5 FLASH EQU 28H ;闪烁控制xxxxxx00,将x=1闪烁,=0不闪 ;小数点的处理: ;若显示‘3’,缓冲区放‘3’,若显示‘3.’,缓冲区放‘3+80H’, 最高位为1 S_PULSE EQU FLAG.0 ;秒脉冲 CNT_2D5MS EQU 2FH ;2.5MS计数器 CNT_10MS1 EQU 30H ;10MS计数器 CN_0D5S EQU 31H ;0.5秒计数器 ;----------------------------------------------------------
51单片机(四位数码管的显示)程序
51单片机(四位数码管的显示)程序基于单片机V1或V2实验系统,编写一个程序,实现以下功能:1)首先在数码管上显示“P_ _ _”4个字符;2)等待按键,如按了任何一个键,则将这4个字符清除,改为显示“0000”4个字符(为数字的0)。
最佳答案下面这个程序是4x4距阵键盘,LED数码管显示,一共可以到0-F显示,你可以稍微改一下就可以实现你的功能了,如还有问题请发信息,希望能帮上你!#include<at89x52.h>unsigned char codeDig[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1 ,0x86,0x8e}; //gongyang数码管0-F 代码unsigned char k; //设置全局变量k 为键盘的键值/************************************键盘延时函数****************************/void key_delay(void) //延时函数{int t;for(t=0;t<500;t++);}/************************************键盘扫描函数******************************/void keyscan(void) //键盘扫描函数{unsigned char a;P2 = 0xf0; //键盘初始化if(P2!=0xf0) //有键按下?{key_delay(); //延时if(P2!=0xf0) //确认真的有键按下?{P2 = 0xfe; //使行线P2.4为低电平,其余行为高电平key_delay();a = P2; //a作为缓存switch (a) //开始执行行列扫描{case 0xee:k=15;break;case 0xde:k=11;break;case 0xbe:k=7;break;case 0x7e:k=3;break;default:P2 = 0xfd; //使行线P2.5为低电平,其余行为高电平a = P2;switch (a){case 0xed:k=14;break;case 0xdd:k=10;break;case 0xbd:k=6;break;case 0x7d:k=2;break;default:P2 = 0xfb; //使行线P2.6为低电平,其余行为高电平a = P2;switch (a){case 0xeb:k=13;break;case 0xdb:k=9;break;case 0xbb:k=5;break;case 0x7b:k=1;break;default:P2 = 0xf7; //使行线P2.7为低电平,其余行为高电平a = P2;switch (a){case 0xe7:k=12;break;case 0xd7:k=8;break;case 0xb7:k=4;break;case 0x77:k=0;break;default:break;}}}break;}}}}/****************************** ***主函数*************************************/ void main(void){while(1){keyscan(); //调用键盘扫描函数switch(k) //查找按键对应的数码管显示代码{case 0:P0=Dig[0];break;case 1:P0=Dig[1];break;case 2:P0=Dig[2];break;case 3:P0=Dig[3];break;case 4:P0=Dig[4];break;case 5:P0=Dig[5];break;case 6:P0=Dig[6];break;case 7:P0=Dig[7];break;case 8:P0=Dig[8];break;case 9:P0=Dig[9];break;case 10:P0=Dig[10];break;case 11:P0=Dig[11];break;case 12:P0=Dig[12];break;case 13:P0=Dig[13];break;case 14:P0=Dig[14];break;case 15:P0=Dig[15];break;default:break; //退出}}}/**********************************end***************************************/。
c51单片机驱动三位8段数码管显示0.00-9.99,c语言程序
unsigned char temp[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}
unsigned char table[3];
unsigned iபைடு நூலகம்t num;
void display(unsigned int num)
TH0 = 0xfc;
TL0 = 0x18;
j++;
if(i < 3)
{
P2 = 0xf8;
P1 = 0x00;
P2 = ~(1 << i);
P1 = table1[i];
i++;
}
else
i = 0;
if(j >= 1000)
{
num++;
if(num > 999)
num = 0;
j = 0;
}
用的是共阴极数码管,定时器延时,不会出现数码管抖动现象
定时器自动加,会从0.00-9.99自动显示,9.99以后又清0.00
追问
我是从ADC0908中传出的8位数字量到单片机上,用单片来动态显示到数码管上的,不知道是不是要标定一下?(传感器输出1-5v,量程是0-10米经AD转换后给单片机用数码管显示0-10米,且在1米和8米处要求报警)
是不是该用单片机不断地循环查询?
回答
不知道这个有没的AD转换中断,如果有可以在每次转换成功以后查下,没有的话,估计要不断查询
TL0 = 0x18;
ET0 = 1;
51单片机数码管电子时钟C程序
//**单片机stc89c52,8位共阴数码管 12M晶振**////*******P0位选,P2段选*******//#include "reg52.h"#define uchar unsigned char#define uint unsigned intuchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x40,0xff};uchar n;uchar hh,mm,ss;uchar nhh,nmm,nss;uint year;uchar day,mon,week;uchar hhs,hhg,mms,mmg,sss,ssg;uchar days,dayg,mons,mong;uchar nhhs,nhhg,nmms,nmmg,nsss,nssg;uchar set1=1,set2=1;sbit dula=P3^3;sbit fm=P3^2;sbit k1=P3^4;sbit k2=P3^5;sbit k3=P3^6;sbit k4=P3^7;uchar table1[]={31,31,29,31,30,31,30,31,31,30,31,30,31}; //闰年uchar table2[]={31,31,28,31,30,31,30,31,31,30,31,30,31}; //非闰年void jishi();void baoshi();void alarm();void set_time();void set_alarm();void set_mdw();void key_change();void key_set();void delay(int m) //延时程序,延时m*0.5ms{uint i;uint j;for (i=0;i<m;i++){for(j=0;j<500;j++){}}}void timer0() interrupt 1 {TMOD=0x01;TH0=0x3c;TL0=0xb1;n++;jishi();}main(){TMOD=0x01;TH0=0x3c;TL0=0xb1;TR0=1;EA=1;ET0=1;hh=12;mm=00;ss=00;nhh=7;nmm=30;nss=0;year=2012;mon=01;day=01;week=7; while(1){hhs=hh/10%10;//时分秒hhg=hh%10;mms=mm/10%10;mmg=mm%10;sss=ss/10%10;ssg=ss%10;nhhs=nhh/10%10;//闹钟nhhg=nhh%10;nmms=nmm/10%10;nmmg=nmm%10;nsss=nss/10%10;nssg=nss%10;days=day/10%10;//月日dayg=day%10;mons=mon/10%10;mong=mon%10;key_change(); //k1按键扫描key_set(); //k2按键扫描set_time(); //设置时间set_mdw(); //设置月日星期set_alarm(); //设置闹钟if(set1==1) //正常走时显示{dula=1;P2=tab[hhs];dula=0;P2=0xff;P0=0xef;delay(1);P0=0xff;//时十位dula=1;P2=tab[hhg]; dula=0;P2=0xff;P0=0xdf;delay(1); P0=0xff;//时个位dula=1;P2=tab[10];dula=0;P2=0xff; P0=0xbf;delay(1); P0=0xff;//"-" dula=1;P2=tab[mms];dula=0; P2=0xff;P0=0x7f;delay(1);P0=0xff; //分十位dula=1;P2=tab[mmg];dula=0;P2=0xff; P0=0xfe;delay(1); P0=0xff;//分个位dula=1;P2=tab[10]; dula=0;P2=0xff;P0=0xfd;delay(1); P0=0xff;//"-"dula=1;P2=tab[sss]; dula=0;P2=0xff;P0=0xfb;delay(1); P0=0xff;//秒十位dula=1;P2=tab[ssg]; dula=0;P2=0xff;P0=0xf7;delay(1);P0=0xff;//秒个位}if(set1==2) //设置时间{dula=1;P2=tab[hhs];dula=0;P2=0xff;P0=0xef;delay(1);P0=0xff;//时十位dula=1;P2=tab[hhg]; dula=0;P2=0xff;P0=0xdf;delay(1); P0=0xff;//时个位dula=1;P2=tab[10];dula=0;P2=0xff; P0=0xbf;delay(1); P0=0xff;//"-"dula=1;P2=tab[mms];dula=0; P2=0xff;P0=0x7f;delay(1);P0=0xff; //分十位dula=1;P2=tab[mmg];dula=0;P2=0xff; P0=0xfe;delay(1); P0=0xff;//分个位dula=1;P2=tab[10]; dula=0;P2=0xff;P0=0xfd;delay(1); P0=0xff;//"-"dula=1;P2=tab[sss]; dula=0;P2=0xff;P0=0xfb;delay(1); P0=0xff;//秒十位dula=1;P2=tab[ssg]; dula=0;P2=0xff;P0=0xf7;delay(1);P0=0xff;//秒个位}if(set1==3) //正常显示月日-星期{dula=1;P2=tab[mons];dula=0;P2=0xff;P0=0xef;delay(1);P0=0xff;//时十位dula=1;P2=tab[mong]; dula=0;P2=0xff;P0=0xdf;delay(1); P0=0xff;//时个位dula=1;P2=tab[10]; dula=0; P2=0xff; P0=0xbf;delay(1); P0=0xff;//"-" dula=1;P2=tab[days]; dula=0; P2=0xff;P0=0x7f;delay(1);P0=0xff;//分十位dula=1;P2=tab[dayg]; dula=0; P2=0xff; P0=0xfe;delay(1); P0=0xff;//分个位dula=1;P2=tab[10];dula=0;P2=0xff;P0=0xfd;delay(1); P0=0xff;//"-" dula=1;P2=tab[10]; dula=0;P2=0xff;P0=0xfb;delay(1); P0=0xff;//秒十位dula=1;P2=tab[week]; dula=0;P2=0xff;P0=0xf7;delay(1);P0=0xff;//秒个位}if(set1==4) //设置月日-星期{dula=1;P2=tab[mons];dula=0;P2=0xff;P0=0xef;delay(1);P0=0xff;//时十位dula=1;P2=tab[mong]; dula=0;P2=0xff;P0=0xdf;delay(1); P0=0xff;//时个位dula=1;P2=tab[10]; dula=0; P2=0xff; P0=0xbf;delay(1); P0=0xff;//"-" dula=1;P2=tab[days]; dula=0; P2=0xff;P0=0x7f;delay(1);P0=0xff;//分十位dula=1;P2=tab[dayg]; dula=0; P2=0xff; P0=0xfe;delay(1); P0=0xff;//分个位dula=1;P2=tab[10];dula=0;P2=0xff;P0=0xfd;delay(1); P0=0xff;//"-" dula=1;P2=tab[10]; dula=0;P2=0xff;P0=0xfb;delay(1); P0=0xff;//秒十位dula=1;P2=tab[week]; dula=0;P2=0xff;P0=0xf7;delay(1);P0=0xff;//秒个位}if(set1==5) //正常显示定时{dula=1;P2=tab[nhhs];dula=0;P2=0xff;P0=0xef;delay(1);P0=0xff;//时十位dula=1;P2=tab[nhhg]; dula=0;P2=0xff;P0=0xdf;delay(1); P0=0xff;//时个位dula=1;P2=tab[10];dula=0;P2=0xff; P0=0xbf;delay(1); P0=0xff;//"-" dula=1;P2=tab[nmms];dula=0; P2=0xff;P0=0x7f;delay(1);P0=0xff; //分十位dula=1;P2=tab[nmmg];dula=0;P2=0xff; P0=0xfe;delay(1); P0=0xff;//分个位dula=1;P2=tab[10]; dula=0;P2=0xff;P0=0xfd;delay(1); P0=0xff;//"-"dula=1;P2=tab[nsss]; dula=0;P2=0xff;P0=0xfb;delay(1); P0=0xff;//秒十位dula=1;P2=tab[nssg]; dula=0;P2=0xff;P0=0xf7;delay(1);P0=0xff;//秒个位}if(set1==6) //设置闹钟定时{dula=1;P2=tab[nhhs];dula=0;P2=0xff;P0=0xef;delay(1);P0=0xff;//时十位dula=1;P2=tab[nhhg]; dula=0;P2=0xff;P0=0xdf;delay(1); P0=0xff;//时个位dula=1;P2=tab[10];dula=0;P2=0xff; P0=0xbf;delay(1); P0=0xff;//"-" dula=1;P2=tab[nmms];dula=0; P2=0xff;P0=0x7f;delay(1);P0=0xff; //分十位dula=1;P2=tab[nmmg];dula=0;P2=0xff; P0=0xfe;delay(1); P0=0xff;//分个位dula=1;P2=tab[10]; dula=0;P2=0xff;P0=0xfd;delay(1); P0=0xff;//"-"dula=1;P2=tab[nsss]; dula=0;P2=0xff;P0=0xfb;delay(1); P0=0xff;//秒十位dula=1;P2=tab[nssg]; dula=0;P2=0xff;P0=0xf7;delay(1);P0=0xff;//秒个位}baoshi(); //整点报时alarm(); //闹钟}}void jishi() //计时函数{if(n==20){n=0;ss++;if(ss==60){ss=0;mm++;if(mm==60){mm=0;hh++;if(hh==24){hh=0;day++;week++;if(week==8){week=0;}if(year%4==0&&year%100!=0||year%400==0) //闰年{if(day==table1[mon]+1){day=0;mon++;if(mon==13){mon=0;year++;}}}else //非闰年{if(day==table2[mon]+1){day=0;mon++;if(mon==13){mon=0;year++;}}}}}}}}uchar incone(uchar n) //加1函数{ if(k3==0){delay(20);if(k3==0){n++;while(!k3);}}return(n);}uchar decone(uchar m) //减1函数{ if(k4==0){delay(20);if(k4==0){m--;while(!k4);if(m<0){m=0;}}}return(m);}void key_change() //k1按键扫描{ if(k1==0){delay(20);if(k1==0){set1++;while(!k1);if(set1==7){set1=1;}}}}void key_set() //k2按键扫描{ if(k2==0){delay(20);if(k2==0){set2++;while(!k2);if(set2==4){set2=1;}}}}void baoshi() //整点报时函数{ if(mm==00&&ss==00){fm=0;}if(ss==1){fm=1;}}void alarm() //闹钟函数{uchar x;if(nhh==0){goto end;}if(hh==nhh&&mm==nmm&&ss==nss) { for(x=0;x<6;x++){fm=0;delay(30); fm=1;delay(20); fm=0;delay(30); fm=1;delay(20); fm=0;delay(30); fm=1;delay(20); fm=0;delay(30); fm=1;delay(180);}}end:;}void set_time() //设置时间函数{ if(set1==2){if(set2==1){hh=incone(hh);if(hh==24){hh=0;}if(hh==-1){hh=23;}hh=decone(hh);}if(set2==2){mm=incone(mm); if(mm==60) {mm=0;}if(mm==-1) {mm=59;}mm=decone(mm); }if(set2==3) {ss=incone(ss); if(ss==60) {ss=0;}if(ss==-1) {ss=59;}ss=decone(ss); }}}void set_mdw() //设置月日星期函数{ if(set1==4){if(set2==1){mon=incone(mon);if(mon==13){mon=1;}mon=decone(mon);if(mon==0){mon=12;}}if(set2==2){day=incone(day);if(day==32){day=1;}day=decone(day); if(day==0){day=31;}}if(set2==3){week=incone(week); if(week==8) {week=1;}week=decone(week); if(week==0) {week=7;}}}}void set_alarm() //设置闹钟函数{ if(set1==6){if(set2==1){nhh=incone(nhh);if(nhh==24){nhh=0;}if(nhh==-1){nhh=23;}nhh=decone(nhh);}if(set2==2){nmm=incone(nmm);if(nmm==60){nmm=0;}nmm=decone(nmm); if(nmm==-1) {nmm=59;}}if(set2==3){nss=incone(nss); if(nss==60) {nss=0;}nss=decone(nss); if(nss==-1) {nss=59;}}}}。
51单片机数码管显示及矩阵键盘扫描程序
51单片机数码管显示及矩阵键盘扫描程序硬件实验十一八段数码管实验一、实验任务1、在静态数码管上轮流显示数字0-9。
2、在两个4位数码管上动态显示数字0-9二、流程图及程序静态显示:流程图:程序代码:#include#define uchar unsigned chucharcodevalue[10]={0xC0,0xF9,0xA4,0xB0,0X99,0x92,0x82,0xF8,0 x80,0x90};//0 -9数码管显示段码void delay(char x) //延时子程序{uchar i;for(i=0;i<200;i++);}main() //主函数{int i;while(1){for(i=0;i<10;i++) //显示0-9{P0=codevalue[i];delay(500); //延时1秒}}}动态显示:#include#includetab1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6D,0x7D,0x07,0x7f,0x6f}; //数码管显示数字字段unsigned char tab2[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//片选字段unsigned char i,k,j,x;void delay(x); //声明延时子函数void main() //主函数{while(1){for(i=0;i<8;i++) //显示0-7{ P1=tab1[i];P0=tab2[i];delay(5); //延时}P1=tab1[8]; P0=tab2[0]; delay(5); //显示8-9P1=tab1[9]; P0=tab2[1]; delay(5);}}void delay(x) //延时函数定义{do{for(j=0;j<250;j++)for(k=0;k<250;k++);}}硬件实验十二矩阵键盘扫描显示一、实验任务1、把矩阵键盘上的按键输入的键码在静态数码管上显示出来。
c51常用程序大全
2.独立按键:51开发板独立键和矩阵键盘不能同时用,会有冲突
sbit s2=P3^4;
while(1) { if(s2==0) led=0; else led=1; }
//通过大循环不断扫描按键状态(方法一)
if(s2==0)
//消抖动 (方法二)
{
delay_ms(20);
if(s2==0)
{
while(!s2); //等待按键释放
//0000 0011 设置定时器0为工作方式3
TH0= 256-250 ; //6 以1s装初值,12M溢出4000次,11.0592溢出3686次 TL0= 256-250 ; //6 EA=1; //开总中断 ET0=1; //定时器/计数器0 中断允许位 ET1=1; //开定时器1中断 TR0=1; //启动定时器0 TR1=1; //启动定时器0的高8位计数器 while(1) //程序停止在这里等待中断发生
delay_ms(20);//延时30ms scan1=P3; if((scan1&0xf0)!=0xf0)//二次判键是否按下 {
P3=0x0f;//线翻转法 delay_ms(1);//延时 scan2=P3;//读P3口的状态 keycode=scan1|scan2; //组合成键编码 while(P3!=0x0f); //等待按键释放 for(j=0;j<=15;j++)
作用:对于延时很短的,要求在us级的,采用“_nop_”函数,这个函数相当汇编NOP指令,延时几微
秒。 NOP指令为单周期指令(即为12个时钟周期),1/12 us可由晶振频率算出延时时间,对于12M晶振, 延时1uS;对于11.0592M,则n个NOP指令为单周期为1.08155 us * n 对于延时比较长的,要求在大于10us,采用C51中的循环语句来实现
51单片机数码管显示实验报告
51单片机数码管显示实验实验内容:1)编写程序让8只数码管初始显示0,每隔大约1s加1显示(可以用延时函数实现),到数码管显示9后,再从0开始显示,如此循环反复。
2)C语言程序#include<reg52.h>#define uint unsigned intvoid display();void num();int i;unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83, 0xc6,0xa1,0x86,0x8e}; //共阳极数码管0-F编码表void delayms(uint);void main(){while(1){num();display();}}void display(){P2=0xff;//消隐P0连接段选,P1节位选P1=0x00;//8个数码管同时显示P2=table[i];//数码管显示数码0 delayms(1000);//延时5ms}void num(){if(i<9)i++;elsei=0;}void delayms(uint x){uint i,j;for(i=0;i<x;i++)for(j=0;j<110;j++);}3)汇编语言:ORG 0000HLJMP MAINORG 0100H;P2连接段选,P1节位选MAIN: MOV P1,#00H ;所有的数码管都显示MOV R2,#00H ;从0开始显示LOOP: MOV A,R2 ;为下面的基址加变址寄存器寻址方式做准备MOV DPTR,#TAB1 ;把数组的首地址赋给DPTRMOVC A,@A+DPTR ;取数组中的数字MOV P2,A ;把取得的值送给P0口显示ACALL DELAY ;延时一会INC R2 ;为取下一个数加一CJNE R2,#10,LOOP ;只要数小于10就继续循环显示MOV R2,#00H ;如果加到10后重新从0开始LJMP LOOP ;进入循环函数;****************************************** TAB1: DB 0C0H,0F9H,0A4H,0B0H,99H; 数组DB 92H,82H,0F8H,80H,90HRET;****************************************** DELAY: MOV R3,#3 ;延时函数DE1: MOV R4,#0FFHDE2: MOV R5,#0FFHDJNZ R5,$DJNZ R4,DE2DJNZ R3,DE1RET;*************************************************END(3)编写程序学习数码管的动态显示,让8只数码管从从左往右显示1、2、3……8。
《单片机Proteus仿真C51参考程序实验》
1 2 3 4 5 6 7 8
P1.0 P1.1 P1.2 P1.3 P1.4 P1.5 P1.6 P1.7
AT89C51 CLOCK=12MHz
P0.0/AD0 P0.1/AD1 P0.2/AD2 P0.3/AD3 P0.4/AD4 P0.5/AD5 P0.6/AD6 P0.7/AD7
P2.0/A8 P2.1/A9 P2.2/A10 P2.3/A11 P2.4/A12 P2.5/A13 P2.6/A14 P2.7/A15
2.在 Keil 环境下建立源程序并保存为.C 文件,生成.HEX 文件;
参考程序如下:
#include<reg51.h> #include<intrins.h> #define uchar unsigned char #define uint unsigned int
void delay_ms(uint x) {
uchar t;while(x--)for(t=0;t<120;t++); }
班级:
学号:
姓名
void main() {
uchar i,j=0x01; while(1) {
P2=j; j=_crol_(j,1); delay_ms(100); } } 将以上程序补充完整,流水时间间隔为 100ms。 3.将.HEX 文件导入仿真图,运行并观察结果;
2.在 Keil 环境下建立源程序并保存为.C 文件,生成.HEX 文件;
参考程序如下:
#include<reg51.h>
班级:
学号:
姓名
#include<intrins.h> #define uchar unsigned char #define uint unsigned int void delay_ms(uint x) {
单片机C51程序设计实验报告书(word文档良心出品)
实验一并行输入输出口的使用一、实验目的:学会设计proteus 7仿真电路,学习P1口的使用方法和延时子程序的编写用Keil uVision 3编程实现发光二极管的流水点亮。
二、实验原理:P1口为8位准双向I/O口,它的每一位都可以分别定义为输入线或输出线(作为输入时,口锁存器必须置1)。
P1口作为输出,接8个发光二极管D1~D8经限流电阻分别接至8个引脚。
本实验仿真电路图、流程图如下:三、实验代码:#include<reg51.h>#include<intrins.h> //移位库函数包含于此头文件中void delay(unsigned int d) //定义延时子函数{ while(--d>0);}void main(){ unsigned char i,sel;while(1){ sel=0xfe;for(i=0;i<=8;i++){ P1=sel; //显示变量赋给P1口delay(50000); //延时sel=_crol_(sel,1); //改变显示变量}}}四、实验结论:用while语句实现发光二极管循环流水点亮,从上到下一次点亮。
实验二C51分支程序设计一、实验目的:学习多分支选择结构和switch语句,了解循环的嵌套。
二、实验原理:do while 循环先执行后判断是否循环,switch括号中的表达式的值与某case后的常量表达式的值相同时,就执行它后面的语句,遇到break语句则退出switch语句。
本实验仿真电路图、流程图如下:(仿真电路图)(流程图)三、实验代码:#include <reg51.h>void main(){ char a;do{ P1=0xff;a=P1;a=a&0x03;switch(a){ case 0:P2=0x0e;break;case 1:P2=0x0d;break;case 2:P2=0x0b;break;case 3:P2=0x07;break;}}while(1);}四、实验结论:多分支选择的switch/case语句,可直接处理并行多分支选择问题,从匹配表达式的括号开始执行,不再进行判断。
51单片机控制流水灯和数码管【精选】
流水灯的操作
2013.03.22
• 点亮第一个灯; • 让第一个灯闪烁; • 从第一个灯依次点亮至最后一个灯;Fra bibliotek动态显示
动态显示的特点是将所有位数码管的段选线并 联在一起,由位选线控制是哪一位数码管有效。选 亮数码管采用动态扫描显示。所谓动态扫描显示即 轮流向各位数码管送出字形码和相应的位选,利用 发光管的余辉和人眼视觉暂留作用,使人的感觉好 像各位数码管同时都在显示。动态显示的亮度比静 态显示要差一些,所以在选择限流电阻时应略小于 静态显示电路中的。
C语言中的<<和>>
• 每执行一次<<操作,被操作数高位数丢失, 低位补零;
C语言中的<<和>>
• 每执行一次<<操作,被操作数低位数丢失, 高位补零;
任务
• 第一次一个管亮流动一次,第二次两个管 亮流动,依次到8个管亮,然后重复整个过 程。
• 先奇数亮再偶数亮,循环三次;一个灯上 下循环三次;两个分别从两边往中间流动 三次;再从中间往两边流动三次;8个全部 闪烁3次;关闭发光管,程序停止。
• 用8个发光管演示出8位二进制数累加过程。
呼吸灯的操作
• 灯光在微电脑控制之下完成由亮到暗的逐 渐变化,感觉像是在呼吸。
• 实现灯不同亮度的两种方法: 1 调节灯的保护电阻, 2 使用PWM。
数码管的操作
• 数码管的介绍 • 数码管的操作
g f GNDa b a
a
b
51单片机数码管循环显示0~9程序说明
数码管循环显示0~9程序说明功能说明:用一位数码管循环显示数字0~9,数字间隔时间为0.2秒。
一、电路图数码管循环显示0~9电路图二、所用电子元器件A T89C51:单片机;7SEG—COM—AN—GRN:带公共端共阳七段绿色数码管;CAP、CAP—ELEC:电容、电解电容;CRYSTAL:晶振。
三、程序汇编语言编写的数码管循环显示0~9源程序代码如下:START:MOV DPTR,#TABLEMOV R0,#00HLOOP: MOV A,R0MOVC A,@A+DPTRMOV P0,AACALL DLY1SINC R0CJNE R0,#10,LOOPJMP STARTDLY1S:MOV R5,#10HD1: MOV R6,#100HD2: MOV R7,#100HDJNZ R7,$DJNZ R6,D2DJNZ R5,D1RETTABLE:DB 0C0H,0F9H,0A4H,0B0HDB 99H, 92H, 82H, 0F8HDB 80H, 90H, 88H, 83HDB 0C6H,0A1H,86H, 8EHENDProtetus 安装说明使用说明1.先安装Setup71.exe,提示选择Setup Type时默认选择即可;若提示No LICENCE 选择安装文件中"crack"-->MAXIM_LICENCE.lxk,打开安装。
2.安装完成后将crack-->文件夹BIN 和文件夹MODELS 下的文件复制到安装目录相应的文件夹内覆盖。
3.安装proteus.7.x-patch,选择patch,提示can not find the file. search the file,选择yes即可;然后选择bin文件中的ares.exe ;在选择models 中的avr.dll安装完毕退出即可。
注:***"Keil驱动"中的程序为Proteus与Keil联调的驱动。
51单片机数码管的程序代码
}
3.依次流水作业
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit line= P1^3; //点阵
sbit led= P1^2;
duan=1; P0=table[shi]; _nop_();
//显示十位
_nop_(); _nop_(); duan=0; P0=0xff; wei=1; P0=0xFb; wei=0; delay(3);
duan=1; P0=table[ge]; _nop_(); _nop_(); _nop_(); duan=0; P0=0xff; wei=1; P0=0xF7; wei=0; delay(3);
unsigned char code weisn[]=
{
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uint y,s,a,b;
void delay ( uint);
void main ()
{
P0=0X00;
line=0;//关闭点阵
P0=0xff; led=0;//关闭 led
5,DS18B20 温度计程序代码
#include "reg52.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
sbit ds=P1^4; //18B20 信号端口 sbit duan=P1^0; //数码管段码控制端
8位数码管显示电子时钟c51单片机程序之欧阳引擎创编
8位数码管显示电子时钟c51单片机程序欧阳引擎(2021.01.01)时间:2012-09-10 13:52:26 来源:作者:/*8位数码管显示时间格式 05—50—00 标示05点50分00秒S1 用于小时加1操作S2 用于小时减1操作S3 用于分钟加1操作S4 用于分钟减1操作*/#include<reg52.h>sbit KEY1=P3^0; //定义端口参数sbit KEY2=P3^1;sbit KEY3=P3^2;sbit KEY4=P3^3;sbit LED=P1^2; //定义指示灯参数code unsigned chartab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共阴极数码管0—9unsigned char StrTab[8]; //定义缓冲区unsigned char minute=19,hour=23,second; //定义并初始化为12:30:00void delay(unsigned int cnt){ while(--cnt);}/**************************************************** **************//* 显示处理函数*//***************************************************** *************/void Displaypro(void){StrTab[0]=tab[hour/10]; //显示小时StrTab[1]=tab[hour%10]; StrTab[2]=0x40; //显示"-"StrTab[3]=tab[minute/10]; //显示分钟StrTab[4]=tab[minute%10]; StrTab[5]=0x40; //显示"-" StrTab[6]=tab[second/10]; //显示秒StrTab[7]=tab[second%10];}main(){ TMOD |=0x01; //定时器0 10ms inM crystal用于计时 TH0=0xd8; //初值 TL0=0xf0; ET0=1;TR0=1;TMOD |=0x10; //定时器1用于动态扫描TH1=0xF8; //初值 TL1=0xf0; ET1=1; TR1=1;EA =1; Displaypro(); //调用显示处理函数while(1) { if(!KEY1) //按键1去抖以及动作 { delay(10000); if(!KEY1) { hour++;if(hour==24)hour=0; //正常时间小时加1 Displaypro(); } }if(!KEY2) //按键2去抖以及动作{ delay(10000); if(!KEY2){ hour--;if(hour==255)hour=23; //正常时间小时减1Displaypro(); } } if(!KEY3) //按键去抖以及动作 { delay(10000);if(!KEY3) { minute++;if(minute==60)minute=0; //分加1 Displaypro(); } } if(!KEY4)//按键去抖以及动作 { delay(10000); if(!KEY4) { minute--;if(minute==255)minute=59; //分减1 Displaypro(); } } }}/******************************************************************//* 定时器1中断*//******************************************************************/void time1_isr(void) interrupt 3 using 0 //定时器1用来动态扫描{ static unsigned char num; TH1=0xF8;//重入初值 TL1=0xf0;switch (num){ case 0:P2=0;P0=StrTab[num];break; //分别调用缓冲区的值进行扫描 case 1:P2=1;P0=StrTab[num];break; case 2:P2=2;P0=StrTab[num];break; case3:P2=3;P0=StrTab[num];break; case4:P2=4;P0=StrTab[num];break; case5:P2=5;P0=StrTab[num];break; case6:P2=6;P0=StrTab[num];break; case7:P2=7;P0=StrTab[num];break; default:break; }num++; //扫描8次,使用8个数码管 if(num==8)num=0;}/******************************************************************//* 定时器0中断*//******************************************************************/void tim(void) interrupt 1 using 1{ staticunsigned char count; //定义内部局部变量TH0=0xd8; //重新赋值 TL0=0xf0; count++;switch (count) { case 0: case 20:case 40: case 60: case 80:Displaypro();break;//隔一定时间调用显示处理 case 50:P1=~P1;break; //半秒 LED 闪烁 default:break; }if (count==100) { count=0;second++; //秒加1 if(second==60){ second=0; minute++; //分加1 if(minute==60) { minute=0; hour++; //时加1 if(hour==24) hour=0; } } } }基于单片机的LCD1602控制总线模式时间:2012-09-10 13:50:39 来源:作者:第一行显示"Welcome";第二行显示="Happy day";若要显示其他字符,请直接往数组 LCMLineOne[16]和LCMLineTwo[16]填充相应的代码。
C51单片机 温度计 C语言程序
disp_buff[0][4]=sec/10;
disp_buff[0][5]=sec%10;
//
disp_buff[1][0]=f;/*符号位*/
disp_buff[1][1]=TMP/1000;//百位
disp_buff[1][2]=TMP/100%10; /*十位*/
uchar KeyBuff;
code unsigned char Tab1[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x40,0x79,0x24,0x30,0x19,0x12,0x02,
0x78,0x00,0x10,0xbf,0xff,0xc6};
{
unsigned int i;
unsigned char j;
bit testb;
for (j=1;j<=8;j++)
ቤተ መጻሕፍቲ ባይዱ
testb = dat & 0x01;
TL0=(unsigned char)(65536-4000);
Count4ms=Count4ms+1;
if (Count4ms==250)
{
Count4ms=0;
SecFlag=1;
}
P2_buff=Tab[disp_cnt];
if (KeyDownFlg)
}
//check data
hour=CheckData(hour,24);
min=CheckData(min,60);
sec=CheckData(sec,60);
51单片机数码管电子时钟C程序
//**单片机stc89c52, 8位共阴数码管12M晶振//*******P0 位选,P2 段选❖******//#include 〃reg52・ h〃#define uchar unsigned char#define uint unsigned intuchar code tab[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x40, Oxff}; uchar n;uchar hh, mm, ss;uchar nhh, nmm, nss;uint year;uchar day, mon, week;uchar hhs, hhg, mms, mmg, sss, ssg;uchar days,dayg, mons, mong;uchar nhhs, nhhg, nmms, nmmg, nsss, nssg;uchar setl=l, set2=l;sbit dula=P3 3;sbit fm=P3 2;sbit kl二P3"4;sbit k2二P3"5;sbit k3二P3飞;sbit k4二P3"7;uchar tablel[] = {31, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 〃闰年uchar table2[] = {31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //非闰年void jishi ();void baoshi ();void alarm();void set_time();void set_alarm();void set_mdw();void key_change():void key_set ();void delay (int m) 〃延时程序,延时m*0. 5msuint i;uint j;for (i=0;i<m;i++){for(j=0;j<500;j++){}}}void timerO() interrupt 1 {TMOD二0x01;TH0=0x3c;TLO=Oxbl;n++;JishiO;}main()TMOD二0x01;TH0=0x3c;TLO二Oxbl;TRO二1;EA二1;ETO二1;hh=12;mm=00;ss=00;nhh二7;nmm=30;nss=0;year=2012;mon=01;day=01;week=7; while(1){hhs=hh/10%10; // 时分秒hhg=hh%10;mms=mm/10%10;mmg=mm%10;sss=ss/10%10;ssg=ss%10;nhhs=nhh/10%10; 〃闹钟nhhg=nhh%10; nmms=nmm/10%10;nmmg=nmm%10; nsss=nss/10%10;nssg=nss%10; days=day/10%10;//月Hday萨day%10; mons=mon/10%10;mong=mon%10;key_change () ; //kl 按键扫描key_set (); //k2 按键扫描set_time() ; //设置时间set.mdwO ; //设置月日星期set_alarm() ; //设置闹钟辻(setl-1) //正常走时显示dula=l: P2=tab [hhs] ; dula=O: P2=0xff; PO=Oxef; delay (1) ;P0二Oxff; //时十位dula二1;P2二tab[hhg]; dula=0;P2=0xff;PO=Oxdf;delay(1) ; PO二Oxff;//时个位dula=l;P2=tab[10]:dula=0;P2=0xff; PO=Oxbf;delay(1); PO二Oxffdula=l: P2=tab [mms] : dula=0: P2 二Oxff ;P0 二0x7f; delay (1) ;P0 二Oxff; //分十位dula=l; P2=tab [mmg] ; dula=0; P2=0xf f; P0=0xfe; delay (1) ; PO 二Oxff;//分个位dula=l;P2=tab[10]; dula=0:P2=0xff;PO=Oxfd:delay(1); PO二Oxffdula二1;P2二tab[sss]; dula=0;P2=0xff;PO=Oxfb:delay(1) ; PO二Oxff;//秒十位dula二1;P2二tablssg]; dula=0:P2=0xff;P0=0xf7; delay(1) ;P0二Oxff; //秒个位}辻(set 1=2) //设置时间dula=l; P2=tab [hhs] ; dula=0; P2=Oxff; PO=Oxef; delay (1) ;P0二Oxff; //时十位dula二1;P2二tablhhg]; dula=0:P2=0xff;PO=Oxdf;delay(1) ; PO二Oxff;//时个位dula=l:P2=tab[10]:dula=0;P2=0xff; PO=Oxbf;delay(1); PO二Oxffdula=l: P2=tab [mms] : dula=0: P2 二Oxff ;P0 二0x7f; delay (1) ;P0 二Oxff; //分十位dula=l; P2=tab [mmg] ; dula=0: P2=0xf f: P0=0xfe; delay (1) ; PO 二Oxff;//分个位dula=l;P2=tab[10]; dula=0:P2=0xff;PO=Oxfd:delay(1); PO二Oxffdula二1;P2二tab[sss]; dula=0;P2=0xff;PO=Oxfb:delay(1) ; PO二Oxff;//秒十位dula二1;P2二tablssg]; dula=0:P2=0xff;P0=0xf7; delay(1) ;P0二Oxff; //秒个位}辻(set 1-3) //正常显示月日-星期(肆匕诂S )M心T P 鏗\m x o u o 匕(DAPWZJXOUOddxouzdoudnp 二席*〕qpf Zd二 H d n p 创+忌、、d x o u o d - (I )A p w q J x o u o d d x o u z d o H £n p =s 〕q p f z d =%-n p 、、—、、、、QJXOUOd - (I)xp^p&Jxouod2Jxouzdo%w 〔OI 〕qeTzd=%-np 心T p g 'm x o u o d - u)APW*xouoddxouzd oUPTnp 二"App 〕qpfzd二%-np^+、、dxouocr(DAP^PQZXOUOmxouzdou d n p 二 SAPP 〕qpfzd 二%-np 、、—、、、、QJXOUOdJI) A32P cu q x o u o d 世o %I n p 二2〕q e F CN d 二%H T P 鏗\m x o u o 匕(DAPWZJXOUOddxouzdoudnp 二席*〕qpf Zd二 H d n p 创+忌、、d x o u o d - (I )A p w q J x o u o d d x o u z d o H £n p =s 〕q p f z d =%-n p 、、—、、、、心 J x o u o d - (I)xp^p&Jxouod2Jxouzdo%w 〔OI 〕qeTzd=%-np 心T p g 'm x o u o d - u)APW*xouoddxouzd oUPTnp 二"App 〕qpfzd 二%-np ^+0、、d x ouocr(DAP^PQZXOUOmxouzdoudnp二SAPP〕qpfzd二%-np 、、—、、、、QJXOUOd J I ) A32Pcu q x o u o d £0 世dula=l; P2=tab [nhhs]; dula=O; P2二Oxff; PO二Oxef; delay (1) ; PO二Oxff; 〃时十位dula=l;P2=tab[nhhg]; dula=0;P2=0xff;PO=Oxdf; delay (1) ; PO二Oxff;//时个位dula=l;P2=tab[10];dula=0;P2=0xff; PO=Oxbf;delay(1); PO二Oxff dula=l:P2=tab [nmms] : dula=0; P2=0xff ;P0=0x7f; delay (1) ;PO=Oxff; //分十位dula=l;P2=tab[nmmg] :dula=0;P2=0xff;PO=Oxfe; delay (1) ; PO=Oxff;//分个位dula=l;P2=tab[10]; dula=0:P2=0xff;PO=Oxfd:delay(1) ; PO二Oxffdula=l ;P2=tab[nsss] : dula=0;P2=0xff ;PO=Oxfb; delay (1) ; PO二Oxff;//秒十位dula=l;P2=tab[nssg] ; dula=0: P2=0xff; PO=Oxf7; delay (1) ;PO=Oxff; //秒个位} if(setl—6) //设置闹钟定时dula=l; P2=tab [nhhs] ; dula=0; P2二Oxff; PO二Oxef; delay (1) ; PO二Oxff; 〃时十位dula=l;P2=tab[nhhg]; dula=0;P2=0xff;PO=Oxdf; delay (1) ; PO二Oxff;//时个位dula=l;P2=tab[10];dula=0;P2=0xff; PO=Oxbf;delay(1); PO二Oxff dula=l:P2=tab [nmms] : dula=0; P2=0xff ;P0=0x7f; delay (1) ;PO=Oxff; //分十位dula=l;P2=tab[nmmg] :dula=0;P2=0xff;PO=Oxfe;delay(1) ; PO二Oxff;//分个位dula=l;P2=tab[10]; dula=0;P2=0xff;PO=Oxfd:delay(1); PO二Oxff dula=l;P2=tab[nsss]; dula二0;P2二Oxff;P0二Oxfb;delay(l) ; PO二Oxff;//秒十位dula=l;P2=tab[nssg] ; dula=0: P2=0xff; PO=Oxf7; delay (1) ;P0二Oxff; //秒个位}baoshi () : //整点报时alarm () ; //闹钟}}void JishiO 〃计时函数辻(n二二20){n=0;ss++;辻(ss=60){ss二0;mm++;if(mm二二60){mm^O;hh++;辻(hh=24){hh二0;day++;week++;if(week==8){week二0;}if (year%4==0&&year%100! =0 year%400==0) //闰年if(day=二tablel[mon]+l){day=0;mon++;if(mon==13){mon二0;year++;}}else //非闰年{辻(day—table2 [mon]+l){day=0;mon++;辻(mon—13){mon二0;year++;}}}}}}}}uchar incone (uchar n) //加 1 函数{辻(k3=0){delay(20);if(k3==0){n++;while(!k3);}}return(n);}uchar decone(uchar m) //减 1 函数{ if (k4==0){delay(20);if(k4==0)辻(m<0){m 二0;}}}}void key_change() //kl 按键扫描{ if(kl==0){delay(20);if(kl==0){setl++;while(!kl);if(setl==7){setl二1;}}void key_set() //k2 按键扫描{if(k2==0){delay(20);{set2++;while(!k2);辻(set2=4){set2=l;}}}}void baoshi () //整点报时函数{ fm=O;}if(ss==l){fm=l;}}void alarm() //闹钟函数{uchar x;if(nhh==0){goto end;}if(hh==nhh&&mm二二nmm&&ss==nss)fm=O; delay(30); fm=l; delay(20); fm=0; delay(30); fm=l; delay(20); fm=0; delay(30); fm=l; delay(20); fm=0; delay(30); fm=l; delay (180);end:;}void set_time() //设置时间函数{辻(setl==2){辻(set2==l){hh=incone(hh);if(hh==24){hh=0;}if(hh==-l){hh二23;}hh二decone(hh);}mm=incone(mm); if(mm==60) {mm 二0;}if(mm==-l) {mm=59;}mm=decone(mm); }辻(set2=3){ss=incone(ss);辻(ss=60){ss=O;}if (ss—-1){ss=59;}ss二decone (ss);}void set_mdw() //设置月日星期函数{ 辻(setl==4) {辻(set2==l){mon=incone(mon);if(mon二二13){mon=l;}mon=decone(mon);if(mon==0){mon二12;}}if(set2==2)day=incone(day);if(day==32){day=l;} day=decone(day);if (day—0){day=31;}}辻(set2=3){week=incone(week);if(week==8){week二1;}week二decone(week);if(week==0){week=7;}}}void set_alarm() //设置闹钟函数{ if(setl二二6){辻(set2=l){nhh二incone(nhh);辻(nhh二二24) {nhh二0;}辻(nhh—-1){nhh二23;}nhh二decone(nhh); }if(set2==2){nmm二incone(nmm); if (nmm—60) {nmm二0;}nmm二decone(nmm); if (nmm 二二 T){nmm=59;}}辻(set2二二3) {nss=incone (nss); if (nss=60){nss=0;}nss二decone(nss); if(nss==-l){nss二59;}}}。