74ls138三八译码器,A\B\C分别接P10\P11\P12,Y0~Y7分别接0~7号数码管(共阴极),输出格式是: 23-59-59,你只用6个数码管,就把中间的两个横杠去掉就行了,代码修改一下。P20~P27接数码管的八位
基于c8051f020单片机最小系统的实时时钟显示程序
c8051f020 FYD12864-0402B LCD显示,按键电子时钟//
#include <c8051f020h>
#include<lcdh>
#include <intrinsh>
#define uchar unsigned char
void lcd_ini();
void DISPInitial();
void ascii_change(void);
void delay();
void wri_add(uchar com);
void wri_dat(uchar com1);
void shan(void);
void disp();
void tkey(void);
void PORT_Init (void);
sbit cs=P1^7;
sbit sid=P1^6;
sbit sclk=P1^5;
bit flag=1;
uchar dat,count,f=1;//f测试哪个单元为当前闪烁状态
uchar data clock[3]={24,00,00};
uchar code clockname[10]={"北京时间:"};
uchar data num[6];
/主程序/
void main()
{
lcd_ini();
count=10;//机器周期为1us,每次定时50ms,此变量用来控制循环次数,在下面赋值为20,共定时1秒
TMOD=0x01;
TL0=0XB0;
TH0=0X3C;
EA=1;
ET0=1;
IT0=1;
EX0=1;
TR0=1;
while(1)
{
back:ascii_change();
disp();
delay();
if(flag==1)
goto back;
tkey();
shan();
delay();
}
}
/lcd初始化/
/void lcd_ini()
{
wri_add(0x30);
delay();
wri_add(0x0c);
delay();
wri_add(0x01);
delay();
wri_add(0x06);
delay();
}/
void PORT_Init (void)
{
XBR0 = 0x00; //不让他连上IO口
XBR1 = 0x14; //允许外部中断连在端口上
XBR2 = 0x40; // Enable crossbar and weak pull-ups
P0MDOUT |= 0x00; // enable TX0 as a push-pull output
// P1MDOUT |= 0x07; // enable P16 (LED) as push-pull output
P2MDOUT=0xfe; //为了驱动步进电机的控制线
//P3MDOUT = 0xFF;
P74OUT=0x00; //配置成漏极方式可以让LCD显示成功 ,我试了配置成推挽方式不能正常显示
}
/定时程序/
void timer1() interrupt 1 using 2
{
TL0=0XB0;
TH0=0X3C;
count--;
if(count==0)
{
count=10;
clock[2]++;//秒//
}
else
goto out;
if(clock[2]==60)
{
clock[2]=0;
clock[1]++;//分//
}
if(clock[1]==60)
{
clock[1]=0;
clock[0]++;
}
if(clock[0]==24)//时//
clock[0]=0;
out:_nop_();
}
/十位个位转换成ASCII码/
void ascii_change(void)
{
num[5]=clock[2]-(clock[2]/10)10+0x30;
num[4]=clock[2]/10+0x30;
num[3]=clock[1]-(clock[1]/10)10+0x30;
num[2]=clock[1]/10+0x30;
num[1]=clock[0]-(clock[0]/10)10+0x30;
num[0]=clock[0]/10+0x30;
}
/廷时程序/
void delay()
{
uchar i,j;
for (i=250;i>0;i--)
for (j=250;j>0;j--);
}
/Write address/
void wri_add(uchar com)
{
uchar i,j,k;
cs=0;
cs=1;
dat=0xf8;
for(i=1;i<=8;i++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
dat=com;
dat=dat&0xf0;
for(j=1;j<=8;j++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
dat=com;
dat=_cror_(dat,4);// 此为高低四位交换
dat=dat&0xf0;
for(k=1;k<=8;k++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
}
/Write data/
void wri_dat(uchar com1)
{
uchar i,j,k;
cs=0;
cs=1;
dat=0xfa;
for(i=1;i<=8;i++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
dat=com1;
dat=dat&0xf0;
for(j=1;j<=8;j++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
dat=com1;
dat=_cror_(dat,4);// 此为高低四位交换
dat=dat&0xf0;
for(k=1;k<=8;k++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
}
/display program/ //显示时间
void disp()
{
uchar i,k=0;
wri_add(0x80);
for (i=1;i<=9;i++)
wri_dat(clockname[i-1]);
wri_add(0x90);
for (i=1;i<=6;i++)
{
k++;
if(k==3||k==5)
wri_dat(clockname[8]);//时间之间的冒号。
wri_dat(num[i-1]);
}
}
/闪烁程序/
void shan(void)
{
uchar i,k=0;
wri_add(0x90);
if(f==1)
{
num[0]=' ';
num[1]=' ';
}
else
goto next;
for (i=1;i<=6;i++)
{
k++;
if(k==3||k==5)
wri_dat(clockname[8]);//时间之间的冒号。
wri_dat(num[i-1]);
}
goto return1;
next: if(f==2)
{
num[2]=' ';
num[3]=' ';
}
else
goto next1;
for (i=1;i<=6;i++)
{
k++;
if(k==3||k==5)
wri_dat(clockname[8]);//时间之间的冒号。
wri_dat(num[i-1]);
}
goto return1;
next1: if(f==3)
{
num[4]=' ';
num[5]=' ';
}
else
goto return1;
for (i=1;i<=6;i++)
{
k++;
if(k==3||k==5)
wri_dat(clockname[8]);//时间之间的冒号。
wri_dat(num[i-1]);
}
return1:_nop_();
}
/外部中断/
void intr0() interrupt 0 using 2
{
flag=~flag;//判断是否闪烁位//
TR0=~TR0; //闪关定时否则开定时
f=1;
}
/按键程序/
void tkey(void)
{
uchar judcekey;
judcekey=P1&0x0f;
if(judcekey==0x0f)
goto return2;
/移位键/
if (judcekey==0x0e)
f++;
if (f==4)
f=1;
/加一键/
if(judcekey==0x0d)
{clock[f-1]++;}
if (f==1)
{ if (clock[f-1]==24){
clock[f-1]=0;}
}
else{ if (clock[f-1]==60)
clock[f-1]=0;
}
/减一键/
if(judcekey==0x0b)
{clock[f-1]--;}
if (f==1)
{ if (clock[f-1]==0xff){
clock[f-1]=23;}
}
else
{ if (clock[f-1]==0xff)
clock[f-1]=59;
}
return2:_nop_();
}
//本程序已经调试成功并能够正确执行
电路原理图 图4201 3. 系统板上硬件连线 (1. 把“单片机系统”区域中的P10-P17端口用8芯排线连接到“动态数码显示”区域中的A-H端口上; (2. 把“单片机系统:区域中的P30-P37端口用8芯排线连接到“动态数码显示”区域中的S1-S8端口上; (3. 把“单片机系统”区域中的P00/AD0、P01/AD1、P02/AD2端口分别用导线连接到“独立式键盘”区域中的SP3、SP2、SP1端口上; 汇编源程序
SECOND EQU 30H
MINITE EQU 31H
HOUR EQU 32H
HOURK BIT P00
MINITEK BIT P01
SECONDK BIT P02
DISPBUF EQU 40H
DISPBIT EQU 48H
T2SCNTA EQU 49H
T2SCNTB EQU 4AH
TEMP EQU 4BH
ORG 00H
LJMP START
ORG 0BH
LJMP INT_T0
START: MOV SECOND,#00H
MOV MINITE,#00H
MOV HOUR,#12
MOV DISPBIT,#00H
MOV T2SCNTA,#00H
MOV T2SCNTB,#00H
MOV TEMP,#0FEH
LCALL DISP
MOV TMOD,#01H
MOV TH0,#(65536-2000) / 256
MOV TL0,#(65536-2000) MOD 256
SETB TR0
SETB ET0
SETB EA
WT: JB SECONDK,NK1
LCALL DELY10MS
JB SECONDK,NK1
INC SECOND
MOV A,SECOND
CJNE A,#60,NS60
MOV SECOND,#00H
NS60: LCALL DISP
JNB SECONDK,$
NK1: JB MINITEK,NK2
LCALL DELY10MS
JB MINITEK,NK2
INC MINITE
MOV A,MINITE
CJNE A,#60,NM60
MOV MINITE,#00H
NM60: LCALL DISP
JNB MINITEK,$
NK2: JB HOURK,NK3
LCALL DELY10MS
JB HOURK,NK3
INC HOUR
MOV A,HOUR
CJNE A,#24,NH24
MOV HOUR,#00H
NH24: LCALL DISP
JNB HOURK,$
NK3: LJMP WT
DELY10MS:
MOV R6,#10
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
RET
DISP:
MOV A,#DISPBUF
ADD A,#8
DEC A
MOV R1,A
MOV A,HOUR
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
MOV A,#10
MOV@R1,A
DEC R1
MOV A,MINITE
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
MOV A,#10
MOV@R1,A
DEC R1
MOV A,SECOND
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
RET
INT_T0:
MOV TH0,#(65536-2000) / 256
MOV TL0,#(65536-2000) MOD 256
MOV A,#DISPBUF
ADD A,DISPBIT
MOV R0,A
MOV A,@R0
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P1,A
MOV A,DISPBIT
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV P3,A
INC DISPBIT
MOV A,DISPBIT
CJNE A,#08H,KNA
MOV DISPBIT,#00H
KNA: INC T2SCNTA
MOV A,T2SCNTA
CJNE A,#100,DONE
MOV T2SCNTA,#00H
INC T2SCNTB
MOV A,T2SCNTB
CJNE A,#05H,DONE
MOV T2SCNTB,#00H
INC SECOND
MOV A,SECOND
CJNE A,#60,NEXT
MOV SECOND,#00H
INC MINITE
MOV A,MINITE
CJNE A,#60,NEXT
MOV MINITE,#00H
INC HOUR
MOV A,HOUR
CJNE A,#24,NEXT
MOV HOUR,#00H
NEXT: LCALL DISP
DONE: RETI
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H
TAB: DB 0FEH,0FDH,0FBH,0F7H,0EFH,0DFH,0BFH,07FH
END
/电子时钟源代码/
#include<graphicsh>
#include<stdioh>
#include<mathh>
#include<dosh>
#define PI 31415926 /定义常量/
#define UP 0x4800 /上移↑键:修改时间/
#define DOWN 0x5000 /下移↓键:修改时间/
#define ESC 0x11b /ESC键 : 退出系统/
#define TAB 0xf09 /TAB键 : 移动光标/
/函数声明/
int keyhandle(int,int); /键盘按键判断,并调用相关函数处理/
int timeupchange(int); /处理上移按键/
int timedownchange(int); /处理下移按键/
int digithour(double); /将double型的小时数转换成int型/
int digitmin(double); /将double型的分钟数转换成int型/
int digitsec(double); /将double型的秒钟数转换成int型/
void digitclock(int,int,int ); /在指定位置显示时钟或分钟或秒钟数/
void drawcursor(int); /绘制一个光标/
void clearcursor(int);/消除前一个光标/
void clockhandle(); /时钟处理/
double h,m,s; /全局变量:小时,分,秒/
double x,x1,x2,y,y1,y2; /全局变量:坐标值/
struct time t[1];/定义一个time结构类型的数组/
main()
{
int driver, mode=0,i,j;
driver=DETECT; /自动检测显示设备/
initgraph(&driver, &mode, "");/初始化图形系统/
setlinestyle(0,0,3); /设置当前画线宽度和类型:设置三点宽实线/
setbkcolor(0);/用调色板设置当前背景颜色/
setcolor(9); /设置当前画线颜色/
line(82,430,558,430);
line(70,62,70,418);
line(82,50,558,50);
line(570,62,570,418);
line(70,62,570,62);
line(76,56,297,56);
line(340,56,564,56); /画主体框架的边直线/
/arc(int x, int y, int stangle, int endangle, int radius)/
arc(82,62,90,180,12);
arc(558,62,0,90,12);
setlinestyle(0,0,3);
arc(82,418,180,279,12);
setlinestyle(0,0,3);
arc(558,418,270,360,12); /画主体框架的边角弧线/
setcolor(15);
outtextxy(300,53,"CLOCK"); /显示标题/
setcolor(7);
rectangle(342,72,560,360); /画一个矩形,作为时钟的框架/
setwritemode(0); /规定画线的方式。mode=0, 则表示画线时将所画位置的原来信息覆盖/
setcolor(15);
outtextxy(433,75,"CLOCK");/时钟的标题/
setcolor(7);
line(392,310,510,310);
line(392,330,510,330);
arc(392,320,90,270,10);
arc(510,320,270,90,10); /绘制电子动画时钟下的数字时钟的边框架/
/绘制数字时钟的时分秒的分隔符/
setcolor(5);
for(i=431;i<=470;i+=39)
for(j=317;j<=324;j+=7){
setlinestyle(0,0,3);
circle(i,j,1); /以(i, y)为圆心,1为半径画圆/
}
setcolor(15);
line(424,315,424,325); /在运行电子时钟前先画一个光标/
/绘制表示小时的圆点/
for(i=0,m=0,h=0;i<=11;i++,h++){
x=100sin((h60+m)/360PI)+451;
y=200-100cos((h60+m)/360PI);
setlinestyle(0,0,3);
circle(x,y,1);
}
/绘制表示分钟或秒钟的圆点/
for(i=0,m=0;i<=59;m++,i++){
x=100sin(m/30PI)+451;
y=200-100cos(m/30PI);
setlinestyle(0,0,1);
circle(x,y,1);
}
/在电子表的左边打印帮助提示信息/
setcolor(4);
outtextxy(184,125,"HELP");
setcolor(15);
outtextxy(182,125,"HELP");
setcolor(5);
outtextxy(140,185,"TAB : Cursor move");
outtextxy(140,225,"UP : Time ++");
outtextxy(140,265,"DOWN: Time --");
outtextxy(140,305,"ESC : Quit system!");
outtextxy(140,345,"Version : 20");
setcolor(12);
outtextxy(150,400,"Nothing is more important than time!");
clockhandle();/开始调用时钟处理程序/
closegraph(); /关闭图形系统/
return 0; /表示程序正常结束,向 *** 作系统返回一个0值/
}
void clockhandle()
{
int k=0,count;
setcolor(15);
gettime(t);/取得系统时间,保存在time结构类型的数组变量中/
h=t[0]ti_hour;
m=t[0]ti_min;
x=50sin((h60+m)/360PI)+451; /时针的x坐标值/
y=200-50cos((h60+m)/360PI); /时针的y坐标值/
line(451,200,x,y);/在电子表中绘制时针/
x1=80sin(m/30PI)+451; /分针的x坐标值/
y1=200-80cos(m/30PI); /分针的y坐标值/
line(451,200,x1,y1); /在电子表中绘制分针/
digitclock(408,318,digithour(h)); /在数字时钟中,显示当前的小时值/
digitclock(446,318,digitmin(m)); /在数字时钟中,显示当前的分钟值/
setwritemode(1);
/规定画线的方式,如果mode=1,则表示画线时用现在特性的线
与所画之处原有的线进行异或(XOR) *** 作,实际上画出的线是原有线与现在规定
的线进行异或后的结果。因此, 当线的特性不变, 进行两次画线 *** 作相当于没有
画线,即在当前位置处清除了原来的画线/
for(count=2;k!=ESC;){ /开始循环,直至用户按下ESC键结束循环/
setcolor(12);/淡红色/
sound(500);/以指定频率打开PC扬声器,这里频率为500Hz/
delay(700);/发一个频率为500Hz的音调,维持700毫秒/
sound(200);/以指定频率打开PC扬声器,这里频率为200Hz/
delay(300);
/以上两种不同频率的音调,可仿真钟表转动时的嘀哒声/
nosound(); /关闭PC扬声器/
s=t[0]ti_sec;
m=t[0]ti_min;
h=t[0]ti_hour;
x2=98sin(s/30PI)+451; /秒针的x坐标值/
y2=200-98cos(s/30PI); /秒针的y坐标值/
line(451,200,x2,y2);
/绘制秒针/
/利用此循环,延时一秒/
while(t[0]ti_sec==s&&t[0]ti_min==m&&t[0]ti_hour==h)
{ gettime(t);/取得系统时间/
if(bioskey(1)!=0){
k=bioskey(0);
count=keyhandle(k,count);
if(count==5) count=1;
}
}
setcolor(15);
digitclock(485,318,digitsec(s)+1);/数字时钟增加1秒/
setcolor(12); /淡红色/
x2=98sin(s/30PI)+451;
y2=200-98cos(s/30PI);
line(451,200,x2,y2);
/用原来的颜色在原来位置处再绘制秒针,以达到清除当前秒针的目的/
/分钟处理/
if(t[0]ti_min!=m){ /若分钟有变化/
/消除当前分针/
setcolor(15); /白色/
x1=80sin(m/30PI)+451;
y1=200-80cos(m/30PI);
line(451,200,x1,y1);
/绘制新的分针/
m=t[0]ti_min;
digitclock(446,318,digitmin(m)); /在数字时钟中显示新的分钟值/
x1=80sin(m/30PI)+451;
y1=200-80cos(m/30PI);
line(451,200,x1,y1);
}
/小时处理/
if((t[0]ti_hour60+t[0]ti_min)!=(h60+m)){ /若小时数有变化/
/消除当前时针/
setcolor(15); /白色/
x=50sin((h60+m)/360PI)+451;/50:时钟的长度(单位:像素),451:圆心的x坐标值/
y=200-50cos((h60+m)/360PI);
line(451,200,x,y);
/绘制新的时针/
h=t[0]ti_hour;
digitclock(408,318,digithour(h));
x=50sin((h60+m)/360PI)+451;
y=200-50cos((h60+m)/360PI);
line(451,200,x,y);
}
}
}
int keyhandle(int key,int count) /键盘控制 /
{ switch(key)
{case UP: timeupchange(count-1); /因为count的初始值为2,所以此处减1/
break;
case DOWN:timedownchange(count-1); /因为count的初始值为2,所以此处减1/
break;
case TAB:setcolor(15);
clearcursor(count); /清除原来的光标/
drawcursor(count); /显示一个新的光标/
count++;
break;
}
return count;
}
int timeupchange(int count) /处理光标上移的按键/
{
if(count==1){
t[0]ti_hour++;
if(t[0]ti_hour==24) t[0]ti_hour=0;
settime(t); /设置新的系统时间/
}
if(count==2){
t[0]ti_min++;
if(t[0]ti_min==60) t[0]ti_min=0;
settime(t); /设置新的系统时间/
}
if(count==3){
t[0]ti_sec++;
if(t[0]ti_sec==60) t[0]ti_sec=0;
settime(t); /设置新的系统时间/
}
}
int timedownchange(int count) /处理光标下移的按键/
{
if(count==1) {
t[0]ti_hour--;
if(t[0]ti_hour==0) t[0]ti_hour=23;
settime(t);/设置新的系统时间/
}
if(count==2) {
t[0]ti_min--;
if(t[0]ti_min==0) t[0]ti_min=59;
settime(t);/设置新的系统时间/
}
if(count==3) {
t[0]ti_sec--;
if(t[0]ti_sec==0) t[0]ti_sec=59;
settime(t);/设置新的系统时间/
}
}
int digithour(double h)/将double型的小时数转换成int型/
{int i;
for(i=0;i<=23;i++)
{if(h==i) return i;}
}
int digitmin(double m)/将double型的分钟数转换成int型/
{int i;
for(i=0;i<=59;i++)
{if(m==i) return i;}
}
int digitsec(double s) /将double型的秒钟数转换成int型/
{int i;
for(i=0;i<=59;i++)
{if(s==i) return i;}
}
void digitclock(int x,int y,int clock)/在指定位置显示数字时钟:时\分\秒/
{char buffer1[10];
setfillstyle(0,2);
bar(x,y,x+15,328);
if(clock==60) clock=0;
sprintf(buffer1,"%d",clock);
outtextxy(x,y,buffer1);
}
void drawcursor(int count) /根据count的值,画一个光标/
{switch(count)
{
case 1:line(424,315,424,325);break;
case 2:line(465,315,465,325);break;
case 3:line(505,315,505,325);break;
}
}
void clearcursor(int count) /根据count的值,清除前一个光标/
{switch(count)
{
case 2:line(424,315,424,325);break;
case 3:line(465,315,465,325);break;
case 1:line(505,315,505,325);break;
}
}
以上就是关于用六个数码管编电子时钟程序,汇编程序是什么要求:用定时器T0工作方式1,初值为0BDCH,P1口为段远,...全部的内容,包括:用六个数码管编电子时钟程序,汇编程序是什么要求:用定时器T0工作方式1,初值为0BDCH,P1口为段远,...、用汇编语言做单片机时钟显示、求单片机c51完成电子时钟显示的原理图及汇编程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)