建材秒知道
登录
建材号 > 设计 > 正文

单片机课程设计的目的

碧蓝的诺言
单薄的长颈鹿
2022-12-21 04:10:12

单片机课程设计的目的

最佳答案
无奈的小兔子
英俊的冥王星
2025-08-21 09:45:18

1.熟练掌握C51系统仿真开发系统的应用。

2.加强单片机的综合运用能力、提高单片机的软件编程和调试能力,为以后的学习和开发工作打下良好基础。

3.掌握的液晶的工作原理以及应用设计。能够对液晶芯片进行编程。

4.掌握小系统开发设计的流程以及设计思路。

最新回答
坦率的柠檬
明理的大碗
2025-08-21 09:45:18

单片机的外部结构:1.DIP40双列直插;52.P0,P1,P2,P3四个8位准双向I/O引脚;(作为I/O输入时,要先输出高电平)3.电源VCC(PIN40)和地线GND(PIN20);4.高电平复位RESET(PIN9);(10uF电容接VCC与RESET,即可实现上电复位)5.内置振荡电路,外部只要接晶体至X1(PIN18)和X0(PIN19);(频率为主频的12倍)6.程序配置EA(PIN31)接高电平VCC;(运行单片机内部ROM中的程序)7.P3支持第二功能:RXD、TXD、INT0、INT1、T0、T1单片机内部I/O部件:(所为学习单片机,实际上就是编程控制以下I/O部件,完成指定任务)1.四个8位通用I/O端口,对应引脚P0、P1、P2和P3;2.两个16位定时计数器;(TMOD,TCON,TL0,TH0,TL1,TH1)3.一个串行通信接口;(SCON,SBUF)4.一个中断控制器;(IE,IP)针对AT89C52单片机,头文件AT89x52.h给出了SFR特殊功能寄存器所有端口的定义。C语言编程基础:1.十六进制表示字节0x5a:二进制为01011010B;0x6E为01101110。2.如果将一个16位二进数赋给一个8位的字节变量,则自动截断为低8位,而丢掉高8位。3.++var表示对变量var先增一;var—表示对变量后减一。4.x|=0x0f表示为x=x|0x0f5.TMOD=(TMOD&0xf0)|0x05表示给变量TMOD的低四位赋值0x5,而不改变TMOD的高四位。6.While(1)表示无限执行该语句,即死循环。语句后的分号表示空循环体,也就是{}在某引脚输出高电平的编程方法:(比如P1.3(PIN4)引脚)代码1.#include//该头文档中有单片机内部资源的符号化定义,其中包含P1.32.voidmain(void)//void表示没有输入参数,也没有函数返值,这入单片机运行的复位入口3.{4.P1_3=1//给P1_3赋值1,引脚P1.3就能输出高电平VCC5.While(1)//死循环,相当LOOP:gotoLOOP6.}注意:P0的每个引脚要输出高电平时,必须外接上拉电阻(如4K7)至VCC电源。在某引脚输出低电平的编程方法:(比如P2.7引脚)代码1.#include//该头文档中有单片机内部资源的符号化定义,其中包含P2.72.voidmain(void)//void表示没有输入参数,也没有函数返值,这入单片机运行的复位入口3.{4.P2_7=0//给P2_7赋值0,引脚P2.7就能输出低电平GND5.While(1)//死循环,相当LOOP:gotoLOOP6.}在某引脚输出方波编程方法:(比如P3.1引脚)代码1.#include//该头文档中有单片机内部资源的符号化定义,其中包含P3.12.voidmain(void)//void表示没有输入参数,也没有函数返值,这入单片机运行的复位入口3.{4.While(1)//非零表示真,如果为真则执行下面循环体的语句5.{6.P3_1=1//给P3_1赋值1,引脚P3.1就能输出高电平VCC7.P3_1=0//给P3_1赋值0,引脚P3.1就能输出低电平GND8.}//由于一直为真,所以不断输出高、低、高、低……,从而形成方波9.}将某引脚的输入电平取反后,从另一个引脚输出:(比如P0.4=NOT(P1.1))代码1.#include//该头文档中有单片机内部资源的符号化定义,其中包含P0.4和P1.12.voidmain(void)//void表示没有输入参数,也没有函数返值,这入单片机运行的复位入口3.{4.P1_1=1//初始化。P1.1作为输入,必须输出高电平5.While(1)//非零表示真,如果为真则执行下面循环体的语句6.{7.if(P1_1==1)//读取P1.1,就是认为P1.1为输入,如果P1.1输入高电平VCC8.{P0_4=0}//给P0_4赋值0,引脚P0.4就能输出低电平GND2008-11-2110:57回复chen33chen10位粉丝2楼9.else//否则P1.1输入为低电平GND10.//{P0_4=0}//给P0_4赋值0,引脚P0.4就能输出低电平GND11.{P0_4=1}//给P0_4赋值1,引脚P0.4就能输出高电平VCC12.}//由于一直为真,所以不断根据P1.1的输入情况,改变P0.4的输出电平13.}将某端口8个引脚输入电平,低四位取反后,从另一个端口8个引脚输出:(比如P2=NOT(P3))代码1.#include//该头文档中有单片机内部资源的符号化定义,其中包含P2和P32.voidmain(void)//void表示没有输入参数,也没有函数返值,这入单片机运行的复位入口3.{4.P3=0xff//初始化。P3作为输入,必须输出高电平,同时给P3口的8个引脚输出高电平5.While(1)//非零表示真,如果为真则执行下面循环体的语句6.{//取反的方法是异或1,而不取反的方法则是异或07.P2=P3^0x0f//读取P3,就是认为P3为输入,低四位异或者1,即取反,然后输出8.}//由于一直为真,所以不断将P3取反输出到P29.}注意:一个字节的8位D7、D6至D0,分别输出到P3.7、P3.6至P3.0,比如P3=0x0f,则P3.7、P3.6、P3.5、P3.4四个引脚都输出低电平,而P3.3、P3.2、P3.1、P3.0四个引脚都输出高电平。同样,输入一个端口P2,即是将P2.7、P2.6至P2.0,读入到一个字节的8位D7、D6至D0。第一节:单数码管按键显示单片机最小系统的硬件原理接线图:1.接电源:VCC(PIN40)、GND(PIN20)。加接退耦电容0.1uF2.接晶体:X1(PIN18)、X2(PIN19)。注意标出晶体频率(选用12MHz),还有辅助电容30pF3.接复位:RES(PIN9)。接上电复位电路,以及手动复位电路,分析复位工作原理4.接配置:EA(PIN31)。说明原因。发光二极的控制:单片机I/O输出将一发光二极管LED的正极(阳极)接P1.1,LED的负极(阴极)接地GND。只要P1.1输出高电平VCC,LED就正向导通(导通时LED上的压降大于1V),有电流流过LED,至发LED发亮。实际上由于P1.1高电平输出电阻为10K,起到输出限流的作用,所以流过LED的电流小于(5V-1V)/10K=0.4mA。只要P1.1输出低电平GND,实际小于0.3V,LED就不能导通,结果LED不亮。开关双键的输入:输入先输出高一个按键KEY_ON接在P1.6与GND之间,另一个按键KEY_OFF接P1.7与GND之间,按KEY_ON后LED亮,按KEY_OFF后LED灭。同时按下LED半亮,LED保持后松开键的状态,即ON亮OFF灭。代码1.#include2.#defineLEDP1^1//用符号LED代替P1_13.#defineKEY_ONP1^6//用符号KEY_ON代替P1_64.#defineKEY_OFFP1^7//用符号KEY_OFF代替P1_75.voidmain(void)//单片机复位后的执行入口,void表示空,无输入参数,无返回值6.{7.KEY_ON=1//作为输入,首先输出高,接下KEY_ON,P1.6则接地为0,否则输入为18.KEY_OFF=1//作为输入,首先输出高,接下KEY_OFF,P1.7则接地为0,否则输入为19.While(1)//永远为真,所以永远循环执行如下括号内所有语句10.{11.if(KEY_ON==0)LED=1//是KEY_ON接下,所示P1.1输出高,LED亮12.if(KEY_OFF==0)LED=0//是KEY_OFF接下,所示P1.1输出低,LED灭13.}//松开键后,都不给LED赋值,所以LED保持最后按键状态。14.//同时按下时,LED不断亮灭,各占一半时间,交替频率很快,由于人眼惯性,看上去为半亮态15.}数码管的接法和驱动原理一支七段数码管实际由8个发光二极管构成,其中7个组形构成数字8的七段笔画,所以称为七段数码管,而余下的1个发光二极管作为小数点。作为习惯,分别给8个发光二极管标上记号:a,b,c,d,e,f,g,h。对应8的顶上一画,按顺时针方向排,中间一画为g,小数点为h。我们通常又将各二极与一个字节的8位对应,a(D0),b(D1),c(D2),d(D3),e(D4),f(D5),g(D6),h(D7),相应8个发光二极管正好与单片机一个端口Pn的8个引脚连接,这样单片机就可以通过引脚输出高低电平控制8个发光二极的亮与灭,从而显示各种数字和符号;对应字节,引脚接法为:a(Pn.0),b(Pn.1),c(Pn.2),d(Pn.3),e(Pn.4),f(Pn.5),g(Pn.6),h(Pn.7)。如果将8个发光二极管的负极(阴极)内接在一起,作为数码管的一个引脚,这种数码管则被称为共阴数码管,共同的引脚则称为共阴极,8个正极则为段极。否则,如果是将正极(阳极)内接在一起引出的,则称为共阳数码管,共同的引脚则称为共阳极,8个负极则为段极。以单支共阴数码管为例,可将段极接到某端口Pn,共阴极接GND,则可编写出对应十六进制码的七段码表字节数据

温柔的烤鸡
神勇的爆米花
2025-08-21 09:45:18

#include <reg52.h>

#include<stddef.h>

#define uchar unsigned char

#define uint unsigned int

#define LCD1602_FLAG

#define LCD1602_PORT P0

sbit lcd1602_rs=P2^0

sbit lcd1602_e=P2^2

sbit lcd1602_rw=P2^1

sbit lcd1602_busy=P0^7

sbit key_ch=P3^5

sbit key_add=P3^6

sbit key_minus=P3^7

uchar i,sec,min,h,date,month,flag

uint year

uchar *chgstr[7]={"  ","sec","min","hour","date","min","year"}

uchar j,k,m,n,o,p

uchar code table[]={

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71}

uchar timestr[10],datestr[10]

void init()

void delay(uint)

void time_display()

void date_display()

void control()

void time()

void lcd1602_CheckBusy()

{

do

{

lcd1602_busy=1

lcd1602_rs=0

lcd1602_rw=1

lcd1602_e=0

lcd1602_e=1

}

while(lcd1602_busy)

}

void lcd1602_WriteCmd(const uchar cmd)

{

lcd1602_CheckBusy()

lcd1602_rs=0

lcd1602_rw=0

lcd1602_e=1

LCD1602_PORT=cmd

lcd1602_e=0

}

void lcd1602_WriteData(const uchar c)

{

lcd1602_CheckBusy()

lcd1602_rs=1

lcd1602_rw=0

lcd1602_e=1

LCD1602_PORT=c

lcd1602_e=0

}

void lcd1602_Init()

{

lcd1602_WriteCmd(0x38) //显示模式为8位2行5*7点阵

lcd1602_WriteCmd(0x0c)//display enable,flag enable,flash enable,

lcd1602_WriteCmd(0x06)//flag move to right,screen don't move

lcd1602_WriteCmd(0x01)//clear screen

}

void lcd1602_Display(const uchar *ptr,uchar line,uchar xaddr)

{

uchar data i=0

uchar *data q

q=ptr

switch(line)

{

case 0:

lcd1602_WriteCmd(0x80+xaddr)

while(q!=NULL &&(*q!='\0') &&i<16)

{

lcd1602_WriteData(*q)

q++

i++

}

break

case 1:

lcd1602_WriteCmd(0xc0+xaddr)

while(q!=NULL &&(*q!='\0') &&i<16)

{

lcd1602_WriteData(*q)

q++

i++

}

break

}

}

void main()

{

lcd1602_Init()

init()

while(1)

{

time_display()

date_display()

control()

}

}

void init()

{

i=0

sec=0

min=30

h=7

date=17

month=10

year=2017

flag=0

EA=1

ET0=1

TMOD=0x01

TH0=(65536-50000)/256

TL0=(65536-50000)%256

TR0=1

}

void delay(uint z)

{

uint x,y

for(x=zx>0x--)

for(y=110y>0y--)

}

void time_display()

{

timestr[7]=0x30+sec%10

timestr[6]=0x30+sec/10

timestr[5]=':'

timestr[4]=0x30+min%10

timestr[3]=0x30+min/10

timestr[2]=':'

timestr[1]=0x30+h%10

timestr[0]=0x30+h/10

timestr[8]=0

lcd1602_Display(timestr,1,3)

}

void date_display()

{

datestr[9]=0x30+date%10

datestr[8]=0x30+date/10

datestr[7]=':'

datestr[6]=0x30+month%10

datestr[5]=0x30+month/10

datestr[4]=':'

datestr[3]=0x30+year%10

datestr[2]=0x30+year/10%10

datestr[1]=0x30+year/100%10

datestr[0]=0x30+year/1000

lcd1602_Display(datestr,0,2)

}

void control()

{

if(!key_ch)

{

delay(5)

if(!key_ch)

{

flag++

TR0=0

if(flag==7)

{flag=0TR0=1lcd1602_Init()}

lcd1602_Display(chgstr[flag],1,12)

}

}

while(!key_ch)

if(flag==1&&key_add==0)

{

while(!key_add)

sec++

if(sec==60)

sec=0

}

if(flag==1&&key_minus==0)

{

while(!key_minus)

sec--

if(sec==-1)

sec=59

}

if(flag==2&&key_add==0)

{

while(!key_add)

min++

if(min==60)

min=0

}

if(flag==2&&key_minus==0)

{

while(!key_minus)

min--

if(min==-1)

min=59

}

if(flag==3&&key_add==0)

{

while(!key_add)

h++

if(h==24)

h=0

}

if(flag==3&&key_minus==0)

{

while(!key_minus)

h--

if(h==-1)

h=23

}

if(flag==4&&key_add==0)

{

while(!key_add)

date++

if(date==29)

if((year%4!=0)&&(month==2))

date=1

if(date==30)

if((year%4==0)&&(month==2))

date=1

if(date==31)

if((month==4)||(month==6)||(month==9)||(month==11))

date=1

if(date==32)

if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12))

date=1

}

if(flag==4&&key_minus==0)

{

while(!key_minus)

if(date>1)date--

}

if(flag==5&&key_add==0)

{

while(!key_add)

month++

if(month==13)

month=1

}

if(flag==5&&key_minus==0)

{

while(!key_minus)

month--

if(month==0)

month=12

}

if(flag==6&&key_add==0)

{

while(!key_add)

year++

if(year==99)

year=1

}

if(flag==6&&key_minus==0)

{

while(!key_minus)

year--

if(year==0)

year=99

}

}

void T0_rpt() interrupt 1

{

TH0=(65536-50000)/256

TL0=(65536-50000)%256

i++

time()

}

void time()

{

if(i==20)

{

i=0

sec++

if(sec==60)

{

sec=0

min++

if(min==60)

{

min=0

h++

if(h==24)

{

h=0

min=0

sec=0

date++

if(date==29)

if((year%4!=0)&&(month==2))

{

date=1

month++

if(month==13)

{

month=1

year++

}

}

if(date==30)

if((year%4==0)&&(month==2))

{

date=1

month++

if(month==13)

{

month=1

year++

}

}

if(date==31)

if((month==4)||(month==6)||(month==9)||(month==11))

{

date=1

month++

if(month==13)

{

month=1

year++

}

}

if(date==32)

if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12))

{

date=1

month++

if(month==13)

{

month=1

year++

}

}

}

}

}

}

}

悦耳的小白菜
幸福的白昼
2025-08-21 09:45:18

哈哈 有个1602显示的 不过程序太长 贴不上 给你个数码管的吧 不行再联系

1302.c

#include<DS1302.h>

#include<key.h>

uchar bit_ser[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf}

uchar seven_seg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}

void timer0_init(void)  //T0初始化函数,用于时间的动态显示

{

TMOD = 0x21

TL0 = (65536-5000) % 256

TH0 = (65536-5000) / 256

EA = 1

ET0 = 1

TR0 = 1

}

void timer0_isr(void) interrupt 1  //T0中断处理函数

{

char flag   //flag用于表示调整时闪烁的亮或灭

TR0 = 0

TL0 = (65536-5000) % 256

TH0 = (65536-5000) / 256

TR0 = 1

flag = x / 100 * 0xff //设置闪烁标志,如果x大于100则flag为0xff,小于100则为0x00

x++

if(x > 200)

x = 0

switch(i)

{

case 0:

P2 = bit_ser[0]

if(setflag == 3)  //根据setflag的值判断当前位是否需要闪烁

P0 = flag | seven_seg[dis_buffer[0]]

else

P0 = seven_seg[dis_buffer[0]]

break

case 1:

P2 = bit_ser[1]

if(setflag == 3)

P0 =flag | seven_seg[dis_buffer[1]]

else

P0 =seven_seg[dis_buffer[1]]

break

case 2:

P2 = bit_ser[2]

if(setflag == 2)

P0 =flag | seven_seg[dis_buffer[2]]

else

P0 =seven_seg[dis_buffer[2]]

break

case 3:

P2 = bit_ser[3]

if(setflag == 2)

P0 =flag | seven_seg[dis_buffer[3]]

else

P0 =seven_seg[dis_buffer[3]]

break

case 4:

P2 = bit_ser[4]

if(setflag == 1)

P0 =flag | seven_seg[dis_buffer[4]]

else

P0 =seven_seg[dis_buffer[4]]

break

case 5:

P2 = bit_ser[5]

if(setflag == 1)

P0 =flag | seven_seg[dis_buffer[5]]

else

P0 =seven_seg[dis_buffer[5]]

break

}

i++

if(i >= 6)

{

i = 0

if(j == 10)

{

j = 0

if(setflag == 0)

DS1302_GetTime(&Time) //如果setflag是0,就从1302中读出时间,因为setflag不是0时,说明处于调整状态,不需要读时间

dis_buffer[5] = Time.Second % 10 //把当前时间放入显示缓冲区

dis_buffer[4] = Time.Second / 10

dis_buffer[3] = Time.Minute % 10

dis_buffer[2] = Time.Minute / 10

dis_buffer[1] = Time.Hour % 10

dis_buffer[0] = Time.Hour / 10

}

j++

}

}

void main()

{

Initial_DS1302(Time)

timer0_init()

while(1)

{

set_down()

timer_down()

up_down()

down_down()

beepflag_down()

if(setflag == 0 && Time.Hour == romhour && Time.Minute == romminute && Beepflag == 1) //判断蜂鸣器是否要响

Beep = !Beep

}

}

//key.c

#include<reg51.h>

#define uchar unsigned char

#define uint unsigned int

uchar i = 0,j = 0,x = 0,setflag,flag_set,flag_timer   //setflag用来表示调整的位置,flag_set和flag_timer分别表示当前处于调整状态还是定时状态

SYSTEMTIME Time={0,20,15,3,30,6,10}    //系统时间的初始值2010年6月30日星期三,15时20分0秒

char dis_buffer[6]    //存放显示数据的缓冲区

sbit Beep_flag = P3^2    //蜂鸣器的接口

sbit key_timer = P3^4    //定时按钮

sbit key_set = P3^5    //调整按钮

sbit key_up = P3^6    //增加按钮

sbit key_down = P3^7    //减小按钮

char romhour,romminute,romsec    //分别存放定时的时,分,秒

bit Beepflag    //标记闹钟是否开启

//延时函数

void delays(uchar x)

{

while(x) x--

}

//设置键的处理函数

void set()

{

setflag ++

flag_set = 1

if(setflag >= 4)

{

setflag = 0

flag_set = 0

Initial_DS1302(Time)

}

}

//定时间的处理函数

void timer()

{

setflag ++

flag_timer = 1

if(setflag == 1)

{

Time.Hour = romhour

Time.Minute = romminute

Time.Second = romsec

}

else if(setflag >= 4)

{

setflag = 0

flag_timer = 0

romhour = Time.Hour

romminute = Time.Minute

romsec = Time.Second

}

}

//增加键的处理函数

void up()

{

switch(setflag)

{

case 0:

break

case 1:

Time.Second ++

if(Time.Second >= 60)

Time.Second = 0

break

case 2:

Time.Minute ++

if(Time.Minute >= 60)

Time.Minute = 0

break

case 3:

Time.Hour ++

if(Time.Hour >= 24)

Time.Hour = 0

break

}

}

//减小键的处理函数

void down()

{

switch(setflag)

{

case 0:

break

case 1:

Time.Second --

if(Time.Second < 0)

Time.Second = 59

break

case 2:

Time.Minute --

if(Time.Minute < 0)

Time.Minute = 59

break

case 3:

Time.Hour --

if(Time.Hour < 0)

Time.Hour = 23

break

}

}

//设置键的扫描函数

void set_down()

{

if(key_set == 0 && flag_timer == 0)

{

delays(100)

if(key_set == 0)

{

set()

}

while(!key_set)

}

}

//定时键的扫描函数

void timer_down()

{

if(key_timer == 0 && flag_set == 0)

{

delays(100)

if(key_timer == 0)

{

timer()

}

while(!key_timer)

}

}

//增加键的扫描函数

void up_down()

{

if(key_up == 0 && setflag != 0)

{

delays(100)

if(key_up == 0)

{

up()

while(!key_up)

}

}

}

//减少键的处理函数

void down_down()

{

if(key_down == 0 && setflag != 0)

{

delays(100)

if(key_down == 0)

{

down()

while(!key_down)

}

}

}

//定时开关的扫描处理函数

void beepflag_down()

{

if(Beep_flag == 0)

{

delays(100)

{

Beepflag = !Beepflag

while(!Beep_flag)

}

}

}

//ds1302.h

#ifndef _REAL_TIMER_DS1302

#define _REAL_TIMER_DS1302

#include <REG51.h>

sbit  DS1302_CLK = P1^1              //实时时钟时钟线引脚

sbit  DS1302_IO  = P1^2              //实时时钟数据线引脚

sbit  DS1302_RST = P1^3              //实时时钟复位线引脚

sbit  ACC0 = ACC^0

sbit  ACC7 = ACC^7

sbit  Beep = P2^7

typedef struct __SYSTEMTIME__

{   char Second

char Minute

char Hour

char Week

char Day

char Month

char Year

}SYSTEMTIME //定义的时间类型

#define AM(X) X

#define PM(X) (X+12)               // 转成24小时制

#define DS1302_SECOND 0x80          //秒寄存器

#define DS1302_MINUTE 0x82          //分寄存器

#define DS1302_HOUR 0x84

#define DS1302_WEEK 0x8A

#define DS1302_DAY 0x86

#define DS1302_MONTH 0x88

#define DS1302_YEAR 0x8C

#define DS1302_RAM(X) (0xC0+(X)*2)    //用于计算 DS1302_RAM 地址的宏

void DS1302InputByte(unsigned char d)  //实时时钟写入一字节(内部函数)

{   unsigned char i

ACC = d

for(i=8 i>0 i--)

{ DS1302_IO  = ACC0            //相当于汇编中的 RRC

DS1302_CLK = 1

DS1302_CLK = 0                 //发一个高跳变到低的脉冲

ACC = ACC >> 1

}

}

unsigned char DS1302OutputByte(void)  //实时时钟读取一字节(内部函数)

{  unsigned char i

for(i=8 i>0 i--)

{ ACC = ACC >>1          //相当于汇编中的 RRC

ACC7 = DS1302_IO

DS1302_CLK = 1

DS1302_CLK = 0                 //发一个高跳变到低的脉冲

}

return(ACC)

}

void Write1302(unsigned char ucAddr, unsigned char ucDa)//ucAddr: DS1302地址, ucData: 要写的数据

{ DS1302_RST = 0

DS1302_CLK = 0

DS1302_RST = 1

DS1302InputByte(ucAddr)        // 地址,命令

DS1302InputByte(ucDa)        // 写1Byte数据

DS1302_CLK = 1

DS1302_RST = 0                  //RST 0->1->0,CLK 0->1

}

unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据

{ unsigned char ucData

DS1302_RST = 0

DS1302_CLK = 0

DS1302_RST = 1                      //enable

DS1302InputByte(ucAddr|0x01)        // 地址,命令

ucData = DS1302OutputByte()         // 读1Byte数据

DS1302_CLK = 1                      //RST 0->1->0,CLK 0->1

DS1302_RST = 0

return(ucData)

}

void DS1302_SetProtect(bit flag)        //是否写保护

{ if(flag)

Write1302(0x8E,0x80) //WP=1,不能写入

else

Write1302(0x8E,0x00)//WP=0,可以写入

}

void DS1302_SetTime(unsigned char Address, unsigned char Value)        // 设置时间函数

{ DS1302_SetProtect(0)

Write1302(Address, ((Value/10)<<4 | (Value%10))) //高4位为十位,低4位为个位

DS1302_SetProtect(1)

}

//获取时间函数,从DS1302内读取时间然后存入Time内

void DS1302_GetTime(SYSTEMTIME *Time)

{ unsigned char ReadValue

ReadValue = Read1302(DS1302_SECOND)

Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)//转换成10进制的秒

ReadValue = Read1302(DS1302_MINUTE)

Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)

ReadValue = Read1302(DS1302_HOUR)

Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)

ReadValue = Read1302(DS1302_DAY)

Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)

ReadValue = Read1302(DS1302_WEEK)

Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)

ReadValue = Read1302(DS1302_MONTH)

Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)

ReadValue = Read1302(DS1302_YEAR)

Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)

}

//利用STime初始化DS1302

void Initial_DS1302(SYSTEMTIME STime)

{ unsigned char Second=Read1302(DS1302_SECOND)

if(Second&0x80)   DS1302_SetTime(DS1302_SECOND,0)  //如果第七为1(表明没有启动), 则启动时钟

DS1302_SetTime(DS1302_SECOND,STime.Second)  //设定起始时间

DS1302_SetTime(DS1302_MINUTE,STime.Minute)

DS1302_SetTime(DS1302_HOUR,STime.Hour)

DS1302_SetTime(DS1302_DAY,STime.Day)

DS1302_SetTime(DS1302_MONTH,STime.Month)

DS1302_SetTime(DS1302_YEAR,STime.Year)

DS1302_SetTime(DS1302_WEEK,STime.Week)

}

#endif

简单的萝莉
愤怒的诺言
2025-08-21 09:45:18
#include<reg51.h>

#define uchar unsigned char

uchar num

uchar lsled[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}

uchar lsled1[7]={0x7e,0xbd,0xdb,0xe7,0xdb,0xbd,0x7e}

bit flag

void t0isr() interrupt 1

{

TH0=(65536-50000)/256

TL0=(65536-50000)%256

num++

flag=1

}

main()

{

uchar i

TMOD=0x01

TH0=(65536-50000)/256

TL0=(65536-50000)%256

ET0=1

EA=1

while(1)

{

num=0

i=0

flag=0

while(num<60)

{

while(flag==0)

flag=0

P0=lsled[i]

i++

i%=8

}

num=0

i=0

flag=0

while(num<40)

{

while(flag==0)

flag=0

P0=lsled1[i]

i++

i%=7

}

for(i=0i<2i++)

{

num=0

P0=0x55

while(num<10)

num=0

P0=0xff

while(num<10)

num=0

}

for(i=0i<2i++)

{

P0=0xaa

while(num<10)

num=0

P0=0xff

while(num<10)

}

num=0

P0=0xff

while(num<20)

}

}

哭泣的小懒猪
听话的咖啡
2025-08-21 09:45:18
1.基于labVIEW虚拟滤波器的设计与实现

2.双闭环直流调速系统设计

3.单片机脉搏测量仪

4.单片机控制的全自动洗衣机毕业设计论文

5.FPGA电梯控制的设计与实现

6.恒温箱单片机控制

7.基于单片机的数字电压表

8.单片机控制步进电机毕业设计论文

9.函数信号发生器设计论文

10.110KV变电所一次系统设计

11.报警门铃设计论文

12.51单片机交通灯控制

13.单片机温度控制系统

14.CDMA通信系统中的接入信道部分进行仿真与分析

15.仓库温湿度的监测系统

16.基于单片机的电子密码锁

17.单片机控制交通灯系统设计

18.基于DSP的IIR数字低通滤波器的设计与实现

19.智能抢答器设计

20.基于LabVIEW的PC机与单片机串口通信

21.DSP设计的IIR数字高通滤波器

22.单片机数字钟设计

23.自动起闭光控窗帘毕业设计论文

24.三容液位远程测控系统毕业论文

25.基于Matlab的PWM波形仿真与分析

26.集成功率放大电路的设计

27.波形发生器、频率计和数字电压表设计

28.水位遥测自控系统 毕业论文

29.宽带视频放大电路的设计 毕业设计

30.简易数字存储示波器设计毕业论文

31.球赛计时计分器 毕业设计论文

32.IIR数字滤波器的设计毕业论文

33.PC机与单片机串行通信毕业论文

34.基于CPLD的低频信号发生器设计毕业论文

35.110kV变电站电气主接线设计

36.m序列在扩频通信中的应用

37.正弦信号发生器

38.红外报警器设计与实现

39.开关稳压电源设计

40.基于MCS51单片机温度控制毕业设计论文

41.步进电动机竹竿舞健身娱乐器材

42.单片机控制步进电机 毕业设计论文

43.单片机汽车倒车测距仪

44.基于单片机的自行车测速系统设计

45.水电站电气一次及发电机保护

46.基于单片机的数字显示温度系统毕业设计论文

47.语音电子门锁设计与实现

48.工厂总降压变电所设计-毕业论文

49.单片机无线抢答器设计

50.基于单片机控制直流电机调速系统毕业设计论文

51.单片机串行通信发射部分毕业设计论文

52.基于VHDL语言PLD设计的出租车计费系统毕业设计论文

53.超声波测距仪毕业设计论文

54.单片机控制的数控电流源毕业设计论文

55.声控报警器毕业设计论文

56.基于单片机的锁相频率合成器毕业设计论文

57.基于Multism/protel的数字抢答器

58.单片机智能火灾报警器毕业设计论

59.无线多路遥控发射接收系统设计毕业论文

60.单片机对玩具小车的智能控制毕业设计论文

61.数字频率计毕业设计论文

62.基于单片机控制的电机交流调速毕业设计论文

63.楼宇自动化--毕业设计论文

64.车辆牌照图像识别算法的实现--毕业设计

65.超声波测距仪--毕业设计

66.工厂变电所一次侧电气设计

67.电子测频仪--毕业设计

68.点阵电子显示屏--毕业设计

69.电子电路的电子仿真实验研究

70.基于51单片机的多路温度采集控制系统

71.基于单片机的数字钟设计

72.小功率不间断电源(UPS)中变换器的原理与设计

73.自动存包柜的设计

74.空调器微电脑控制系统

75.全自动洗衣机控制器

76.电力线载波调制解调器毕业设计论文

77.图书馆照明控制系统设计

78.基于AC3的虚拟环绕声实现

79.电视伴音红外转发器的设计

80.多传感器障碍物检测系统的软件设计

81.基于单片机的电器遥控器设计

82.基于单片机的数码录音与播放系统

83.单片机控制的霓虹灯控制器

84.电阻炉温度控制系统

85.智能温度巡检仪的研制

86.保险箱遥控密码锁 毕业设计

87.10KV变电所的电气部分及继电保护

88.年产26000吨乙醇精馏装置设计

89.卷扬机自动控制限位控制系统

90.铁矿综合自动化调度系统

91.磁敏传感器水位控制系统

92.继电器控制两段传输带机电系统

93.广告灯自动控制系统

94.基于CFA的二阶滤波器设计

95.霍尔传感器水位控制系统

96.全自动车载饮水机

97.浮球液位传感器水位控制系统

98.干簧继电器水位控制系统

99.电接点压力表水位控制系统

100.低成本智能住宅监控系统的设计

101.大型发电厂的继电保护配置

102.直流操作电源监控系统的研究

103.悬挂运动控制系统

104.气体泄漏超声检测系统的设计

105.电压无功补偿综合控制装置

106.FC-TCR型无功补偿装置控制器的设计

107.DSP电机调速

108.150MHz频段窄带调频无线接收机

109.电子体温计

110.基于单片机的病床呼叫控制系统

111.红外测温仪

112.基于单片微型计算机的测距仪

113.智能数字频率计

114.基于单片微型计算机的多路室内火灾报警器

115.信号发生器

116.基于单片微型计算机的语音播出的作息时间控制器

117.交通信号灯控制电路的设计

118.基于单片机步进电机控制系统设计

119.多路数据采集系统的设计

120.电子万年历

121.遥控式数控电源设计

122.110kV降压变电所一次系统设计

123.220kv变电站一次系统设计

124.智能数字频率计

125.信号发生器

126.基于虚拟仪器的电网主要电气参数测试设计

127.基于FPGA的电网基本电量数字测量系统的设计

128.风力发电电能变换装置的研究与设计

129.电流继电器设计

130.大功率电器智能识别与用电安全控制器的设计

131.交流电机型式试验及计算机软件的研究

132.单片机交通灯控制系统的设计

133.智能立体仓库系统的设计

134.智能火灾报警监测系统

135.基于单片机的多点温度检测系统

136.单片机定时闹钟设计

137.湿度传感器单片机检测电路制作

138.智能小车自动寻址设计--小车悬挂运动控制系统

139.探讨未来通信技术的发展趋势

140.音频多重混响设计

141.单片机呼叫系统的设计

142.基于FPGA和锁相环4046实现波形发生器

143.基于FPGA的数字通信系统

144.基于单片机的带智能自动化的红外遥控小车

145.基于单片机AT89C51的语音温度计的设计

146.智能楼宇设计

147.移动电话接收机功能电路

148.单片机演奏音乐歌曲装置的设计

149.单片机电铃系统设计

150.智能电子密码锁设计

151.八路智能抢答器设计

152.组态控制抢答器系统设计

153.组态控制皮带运输机系统设计

154..基于单片机控制音乐门铃

155.基于单片机控制文字的显示

156.基于单片机控制发生的数字音乐盒

157.基于单片机控制动态扫描文字显示系统的设计

158.基于LMS自适应滤波器的MATLAB实现

159.D功率放大器毕业论文

160.无线射频识别系统发射接收硬件电路的设计

161.基于单片机PIC16F877的环境监测系统的设计

162.基于ADE7758的电能监测系统的设计

163.智能电话报警器

164.数字频率计 课程设计

165.多功能数字钟电路设计 课程设计

166.基于VHDL数字频率计的设计与仿真

167.基于单片机控制的电子秤

168.基于单片机的智能电子负载系统设计

169.电压比较器的模拟与仿真

170.脉冲变压器设计

171.MATLAB仿真技术及应用

172.基于单片机的水温控制系统

173.基于FPGA和单片机的多功能等精度频率计

174.发电机-变压器组中微型机保护系统

175.基于单片机的鸡雏恒温孵化器的设计

176.数字温度计的设计

177.生产流水线产品产量统计显示系统

178.水位报警显时控制系统的设计

179.红外遥控电子密码锁的设计

180.基于MCU温控智能风扇控制系统的设计

181.数字电容测量仪的设计

182.基于单片机的遥控器的设计

183.200电话卡代拨器的设计

184.数字式心电信号发生器硬件设计及波形输出实现

185.电压稳定毕业设计论文

186.基于DSP的短波通信系统设计(IIR设计)

187.一氧化碳报警器

188.网络视频监控系统的设计

189.全氢罩式退火炉温度控制系统

190.通用串行总线数据采集卡的设计

191.单片机控制单闭环直流电动机的调速控制系统

192.单片机电加热炉温度控制系统

193.单片机大型建筑火灾监控系统

194.USB接口设备驱动程序的框架设计

195.基于Matlab的多频率FMICW的信号分离及时延信息提取

196.正弦信号发生器

197.小功率UPS系统设计

198.全数字控制SPWM单相变频器

199.点阵式汉字电子显示屏的设计与制作

200.基于AT89C51的路灯控制系统设计

200.基于AT89C51的路灯控制系统设计

201.基于AT89C51的宽范围高精度的电机转速测量系统

202.开关电源设计

203.基于PDIUSBD12和K9F2808简易USB闪存设计

204.微型机控制一体化监控系统

205.直流电机试验自动采集与控制系统的设计

206.新型自动装弹机控制系统的研究与开发

207.交流异步电机试验自动采集与控制系统的设计

208.转速闭环控制的直流调速系统的仿真与设计

209.基于单片机的数字直流调速系统设计

210.多功能频率计的设计

211.18信息移频信号的频谱分析和识别

212.集散管理系统—终端设计

213.基于MATLAB的数字滤波器优化设计

214.基于AT89C51SND1C的MP3播放器

215.基于光纤的汽车CAN总线研究

216.汽车倒车雷达

217.基于DSP的电机控制

218.超媒体技术

219.数字电子钟的设计与制作

220.温度报警器的电路设计与制作

221.数字电子钟的电路设计

222.鸡舍电子智能补光器的设计

223.高精度超声波传感器信号调理电路的设计

224.电子密码锁的电路设计与制作

225.单片机控制电梯系统的设计

226.常用电器维修方法综述

227.控制式智能计热表的设计

228.电子指南针设计

229.汽车防撞主控系统设计

230.单片机的智能电源管理系统

231.电力电子技术在绿色照明电路中的应用

232.电气火灾自动保护型断路器的设计

233.基于单片机的多功能智能小车设计

234.对漏电保护器安全性能的剖析

235.解析民用建筑的应急照明

236.电力拖动控制系统设计

237.低频功率放大器设计

238.银行自动报警系统

参考资料:http://bkbylw.blog.sohu.com/

跳跃的泥猴桃
默默的月光
2025-08-21 09:45:18

原理图如下,

程序如下:

=================================================

寄存器分配定义

=================================================

LED_BUF EQU 50H 显示数据首址

COUNTER_INT EQU 3BH 中断计数器

SECOND     EQU 3DH     秒单元

=================================================

常数定义

=================================================

CN_COUNT_INT  EQU  100     10ms * 100 = 1S

SET_MODEL EQU 0FFH 完全译码模式

SET_BRIGHT EQU 04H 占空比为15/32显示亮度

SET_LIMIT EQU 01H 2位显示方式

SET_NORMAL EQU 01H 测试模式

SET_START EQU 01H 进入启动工作方式?

=================================================

管脚分配定义

=================================================

m7219_DIN BIT P3.0

m7219_LOAD BIT P3.1

m7219_CLK BIT P3.2

KEYSTART BIT P1.0

KEYRESET BIT P1.1

============================================

模拟主程序

===========================================

org 0000h

ajmp main

  ORG 000BH

  LJMP Timer0Interrupt

org 0030h

main:

mov sp,#70h

lcall Init_M7219

lcall InitTimer0

MOV SECOND,#95H  TEST

Loop:

CALL disp

key_reset:

SETB KEYRESET

JB KEYRESET,key_start

DELAY

NOP

NOP

NOP

JB KEYRESET,key_start

JNB KEYRESET,$

CLR  TR0

MOV A,#0

MOV SECOND,A

MOV led_buf,A

  MOV LED_BUF+1,A

JMP key_SCAN_END

key_start:

SETB KEYSTART

JB KEYSTART,key_SCAN_END

DELAY

NOP

NOP

NOP

JB KEYSTART,key_SCAN_END

JNB KEYSTART,$

SETB  TR0

key_SCAN_END:

JMP loop

===========================================

InitTimer0:10ms一次中断

  MOV TMOD,#01H

  MOV TH0,#0D8H

  MOV TL0,#0F0H

  SETB EA

  SETB ET0

  RET

===========================================

Timer0Interrupt:

  PUSH DPH

  PUSH DPL

  PUSH ACC

  MOV TH0,#0D8H

  MOV TL0,#0F0H

  ========================

  INC COUNTER_INT

MOV  A,COUNTER_INT        10ms 计数值加1

CJNE  A,#CN_COUNT_INT,Timer0Interrupt_EXIT

MOV  COUNTER_INT,#0

MOV A,SECOND

CJNE  A,#99H,Timer0Int_sec

CLR TR0关闭计时

JMP Timer0Interrupt_EXIT  

Timer0Int_sec:

ADD A,#01     秒加1

DA A

MOV  SECOND,A

SWAP A

ANL A,#0fH

MOV led_buf,A

MOV A,SECOND

ANL A,#0FH

  MOV LED_BUF+1,A

  ========================

Timer0Interrupt_EXIT:  

  POP ACC

  POP DPL

  POP DPH

  RETI

====================================================

function:Init_M7219 初始化max719

input: ------------

output: ----------

usage: a,b

====================================================

Init_M7219:   初始化Max7219

MOV a,#0bh  设置扫描界限

MOV b,#set_limit 设置位数

lcall w_7219

MOV a,#09h  设置译码模式

MOV b,#set_model 00h非译码模式ffh为BCD译码模式

lcall w_7219

MOV a,#0ah  设置亮度

MOV b,#set_bright 15/32亮度

lcall w_7219

MOV a,#0fh  设置工作方式

MOV b,#set_normal 正常工作方式

lcall w_7219

MOV a,#0ch  进入启动工作方式

MOV b,#set_start

lcall  w_7219

RET

===================================================

function:disp  显示子程序

input: r0

output: -----------

usage: r0,r3,r4,a,b

===================================================

disp:

MOV r0,#led_buf

MOV r4,#01h

MOV r3,#set_limit

INC r3

disp1:

MOV a,@r0

MOV b,a

MOV a,r4

lcall w_7219

INC r0

INC r4

djnz r3,disp1

RET

===================================================

function:w_7219 显示驱动程序

input: a  传送7219的地址

       b  传送7219的数据

output:-------------

usage: a,r2

====================================================

w_7219:

CLR M7219_clk

CLR M7219_din

CLR  M7219_load 置load=0

lcall  sd_7219  传送7219的地址

MOV a,b

lcall sd_7219  传送数据

setb M7219_load  数据装载

CLR M7219_din

RET

=================================================

function:sd_7219  向7219传送数据或地址子程序

input:    a

output:   max7219

usage:   a, r2

==================================================

sd_7219:   向7219送地址或数据

MOV r2,#08h

c_sd:

CLR C

CLR M7219_clk

RLC a

MOV M7219_din,c 准备数据

NOP

setb M7219_clk 上升沿将数据传入

NOP

NOP

CLR M7219_clk

djnz r2,c_sd

RET

END

勤恳的红牛
迷路的滑板
2025-08-21 09:45:18

MODE_RG EQU  40H 模式选择

 MODE2 EQU  60H MODE值

 MODE3 EQU  61H

 MODE4 EQU  62H

 MODE5 EQU  63H

 MODE6 EQU  64H

 MODE1 EQU  65H

 HOUR    EQU  41H 小时缓冲区

 MIN     EQU  42H 分钟缓冲区

 SEC     EQU  43H 秒缓冲区

 TEMP EQU  4AH

 *********闹钟缓冲区********************

 H_ALARM EQU  6AH 闹钟缓冲区

 M_ALARM EQU  6BH

 S_ALARM EQU  6CH

 F_ALARM EQU  6DH

 ***********秒表缓冲区******************

 M_SEC EQU  76H

 S_SEC EQU  77H

 *********LED送显示临时变量*************

 LED0 EQU  51H

 LED1 EQU  52H

 LED2       EQU  53H

 LED3 EQU  54H

 MODE_KEY   EQU  P3.4

 UP_KEY EQU  P3.3

 DOWN_KEY EQU  P3.5

 BUF EQU  49H

ORG 0000H

LJMP MAIN

ORG 000BH

LJMP INT_0

ORG 001BH

LJMP INT_1

ORG 0080H

MAIN: MOV SP,#2FH  堆栈初始化

MOV MODE_RG,#0  MODE_RG寄存器值初始化

MOV LED0,#0FEH  初始化LED

MOV LED1,#0FDH

MOV LED2,#0FBH

MOV LED3,#0F7H

MOV MODE1,#1

MOV MODE2,#2

MOV MODE3,#3

MOV MODE4,#4

MOV MODE5,#5

MOV MODE6,#6

MOV F_ALARM,#0  错误2:一开始用 CLR F_ALARM,这导致在后面的时候JZ F_ALARM 运行错误,

MOV BUF,#0 在于 JZ 指令是对累加器A全为0或者全为1进行判断,CLR只能对一位操作

MOV TMOD,#11H  定时器初始化:定时器0,方式1,定时器1,方式1

MOV IP,#00001000B  定时器1优先级高

MOV TH0,#3CH  定时50MS

MOV TL0,#0B1H

MOV TH1,#0D8H  定时10MS

MOV TL1,#0F0H

SETB EA

SETB ET0

SETB ET1

SETB TR0             启动定时器

        MOV HOUR,#0      for test

MOV MIN,#0

MOV SEC,#0  定时器计数器,50MS中断一次,200次则刚好1S

MOV M_SEC,#0

MOV S_SEC,#0

MOV H_ALARM,#0

MOV M_ALARM,#0

MAIN1: LCALL DISPLAY12

LCALL DISPLAY34

CLR P1.4    TEST

JNB MODE_KEY,KEY_SCAN

MOV A,MODE_RG

CJNE A,MODE6,Y1   MODE6  秒表

JNB DOWN_KEY,DEALDOWN    判断秒表开关

JNB UP_KEY,DEALUP

Y1: MOV A,F_ALARM   判断闹钟

JNZ ALARM

LJMP MAIN1

-----------------------------------秒表开关程序---------------------------

DEALDOWN: LCALL DELY10MS

JB DOWN_KEY,MAIN1

H1: JNB DOWN_KEY,H1

CPL TR1

LJMP MAIN1

DEALUP: LCALL DELY10MS

JB UP_KEY,MAIN1

H2: JNB UP_KEY,H2

MOV M_SEC,#0

MOV S_SEC,#0

CLR TR1

LJMP MAIN1

-----------------------------------闹钟扫描程序---------------------------

ALARM: MOV A,H_ALARM

CPL P1.2

CJNE A,HOUR,EXIT3

MOV A,M_ALARM

CJNE A,MIN,EXIT3

LJMP STARTALARM

EXIT3: SETB P3.6

LJMP MAIN1

STARTALARM: CPL P3.6

JNB DOWN_KEY,OFFALARM

LJMP S1

OFFALARM: LCALL DELY10MS

JB DOWN_KEY,MAIN1

S2: JNB DOWN_KEY,S2

MOV F_ALARM,#0

SETB P3.6

LJMP MAIN1

S1: LCALL DELAY

LJMP MAIN1

-----------------------------------键盘扫描程序---------------------------

KEY_SCAN: LCALL DELY10MS

JB MODE_KEY,MAIN1

INC MODE_RG

SETB P1.4    测试

K1: JNB MODE_KEY,K1  按键直到用户松开按键

K2: MOV A,MODE_RG

CJNE A,#0,DEALMODE  不是在正常显示模式下则跳转到模式处理程序

LJMP MAIN1  返回主程序

*******************模式处理程序部分

DEALMODE: MOV TEMP,#0  凡转入MODE处理,则首先清除TEMP

MOV A,MODE_RG  有MODE_RG值不为5、0

CJNE A,MODE2,M0  判断MODE_RG值,不为1跳转

LJMP H_GLINT  模式1,小时位闪烁

M0: CJNE A,MODE3,M1  不是模式2,跳转

LJMP M_GLINT  模式2,分钟位闪烁

M1: CJNE A,MODE4,M2  不是模式3,跳转

LJMP H_GLINT

M2:   CJNE A,MODE5,M3

LJMP M_GLINT

M3: CJNE A,MODE6,M4

MOV M_SEC,#0

MOV S_SEC,#0

LJMP MAIN1

M4: CJNE A,MODE1,M5

CLR TR1

LJMP MAIN1

M5: MOV MODE_RG,#0

LJMP MAIN1

*****************************MODE为1,3,小时位闪烁

//MOV TEMP,HOUR  将TEMP赋值,防止在加的时候是在随机值的基础上增加

H_GLINT: CPL P1.0

MOV R0,#28

MOV R1,#28

K4: LCALL DISPLAY12  分开显示

LCALL DISPLAY34

E1: JNB MODE_KEY,K21  检测是否有按键按下,有按下则跳转到分钟位闪烁

JB UP_KEY,E9  判断加位有无按键按下

LJMP UP

E9: DJNZ R0,K4

K6: LCALL DISPLAY34

JNB MODE_KEY,K21  检测是否有按键按下,有按下则跳转延时后进行模式判断

LJMP G1

K21: LCALL DELY10MS  延时后确定有MODE按键按下,将

JB MODE_KEY,H_GLINT

W: JNB MODE_KEY,W

INC MODE_RG

CPL P1.4

LJMP DEALMODE  确定有按下,MODE+1后返回MODE处理程序

JNB UP_KEY,UP  判断加位有无按键按下

G1: DJNZ R1,K6

LJMP H_GLINT  调用完毕返回,实现闪烁

K3: LJMP MAIN1  可省略

******************************MODE为2,4,分钟位闪烁

M_GLINT: MOV R0,#28

MOV R1,#28

K23: CPL P1.7

LCALL DISPLAY12

LCALL DISPLAY34

JNB MODE_KEY,KK  跳转,确定是否有按键按下

JNB UP_KEY,UP  判断加位有无按键按下

MOV A,MODE_RG

CJNE A,MODE3,E2  在MODE5的情况下要判断闹钟确认键有没按下

LJMP E5

E2: JNB DOWN_KEY,F2

LJMP E5

F2: LJMP ONALARM2

E5: DJNZ R0,K23

K24: LCALL DISPLAY12

JNB MODE_KEY,KK  检测是否有按键按下,有按下则跳转

JNB UP_KEY,UP  判断加位有无按键按下

MOV A,MODE_RG  扫描闹钟确认键

CJNE A,MODE3,E7  在MODE5的情况下要判断闹钟确认键有没按下

LJMP G2

E7: JB DOWN_KEY,E8

CPL P1.3

LJMP ONALARM2

E8: LJMP G2

KK: LCALL DELY10MS  去抖

JB MODE_KEY,M_GLINT

W1: JNB MODE_KEY,W1

INC MODE_RG

CPL P1.4

LJMP DEALMODE  确定有按下,MODE+1后返回MODE处理程序

G2: DJNZ R1,K24

LJMP M_GLINT

*************************位加,处理程序

***************小时调整

UP: MOV R1,#20

UP11: INC TEMP

UP12: MOV A,MODE_RG  判断此时的MODE,根据MODE将临时变量给对应的赋值

CJNE A,MODE2,AA0  不是在MODE2的情况下跳转

MOV A,TEMP

CJNE A,#24,A_UP1

MOV TEMP,#0

A_UP1: MOV HOUR,TEMP  为MODE2,将临时变量赋给小时位

LJMP UP15

AA0: CJNE A,MODE4,UP13    //UP13为分钟调整入口

MOV A,TEMP

CJNE A,#24,A_UP

MOV TEMP,#0

A_UP: MOV H_ALARM,TEMP   模式3,将临时变量赋给闹钟的小时位

LJMP UP15   UP15为显示入口

****************分钟调整入口

UP13: MOV A,MODE_RG

CJNE A,MODE3,UP14  不是模式2,跳转

MOV A,TEMP

CJNE A,#60,DISOVER2

MOV TEMP,#0

DISOVER2: MOV MIN,TEMP

LJMP UP15

UP14: MOV A,TEMP  上面判断不是模式2,则必然是模式4

CJNE A,#60,DISOVER3

MOV TEMP,#0

DISOVER3: MOV M_ALARM,TEMP

LJMP UP15

UP15: LCALL DISPLAY12

LCALL DISPLAY34

DJNZ R1,UP01

MOV R1,#1   

JNB UP_KEY,UP11

UP01: JNB UP_KEY,UP12

UP16: MOV A,MODE_RG   松开键以后按照模式判断该返回哪种状态,不能返回DEALMODE函数

CJNE A,MODE2,UP17

LJMP H_GLINT

UP17: CJNE A,MODE3,UP18

MOV SEC,#0   每次设置完时间后将秒钟位置零保证时间准确

LJMP M_GLINT

UP18: CJNE A,MODE4,UP19

LJMP H_GLINT

UP19: CJNE A,MODE5,UP20

LJMP M_GLINT

UP20: LJMP MAIN1

ONALARM2: LCALL DELY10MS  延时10MS,去抖

JB DOWN_KEY,B2  抖动所致,返回分钟位闪烁

LJMP K42

B2: LJMP M_GLINT

K42: JNB DOWN_KEY,K42

MOV F_ALARM,#0FFH

MOV MODE_RG,#0

LJMP MAIN1

---------------------------------------中断程序入口---------------------

*******************时间中断0*********************

错误1:中断程序EXIT处用了MAIN1,导致一直处于中断状态

INT_0: PUSH ACC

PUSH PSW

MOV TH0,#3CH

MOV TL0,#0B1H

INC BUF

MOV A,BUF

CJNE A,#20,EXIT

TIME: MOV BUF,#0

INC SEC

MOV A,SEC

CJNE A,#60,EXIT

MOV SEC,#00H

INC MIN

MOV A,MIN

CJNE A,#60,EXIT

MOV MIN,#00H

INC HOUR

MOV A,HOUR

CJNE A,#24,EXIT

MOV HOUR,#0

RETI

EXIT:  POP PSW

   POP ACC

  RETI

******************时间中断1***********************

INT_1:  MOV TH1,#0D8H  定时10MS

MOV TL1,#0F0H

INC S_SEC

MOV A,S_SEC

CJNE A,#100,EXIT4

MOV S_SEC,#0

INC M_SEC

MOV A,M_SEC

CJNE A,#100,EXIT4

MOV M_SEC,#0

EXIT4: RETI

---------------------------------------显示-----------------------------

DISPLAY12: MOV A,MODE_RG   判断模式,决定是显示闹钟时间还是显示当前时间

CJNE A,MODE4,DIS0   模式四,显示闹钟

LJMP DIS01   MODE4

DIS0: CJNE A,MODE5,DIS20

DIS01: MOV R7,H_ALARM   闹钟模式

LJMP DIS2

DIS20: CJNE A,MODE6,DIS21

MOV R7,M_SEC   秒表模式,显示秒表高位

LJMP DIS2

DIS21: CJNE A,MODE1,DIS1

LJMP DIS22

DIS22: MOV R7,MIN

LJMP DIS2

DIS1: MOV R7,HOUR   DISPLAY12显示高位

DIS2: LCALL BCTD   判断完毕,调用显示

将秒、分 分别转码,放到R4,R3

MOV A,R4

MOV R3,A

LCALL DIVIDE

MOV DPTR,#NUMTAB

MOV P2,#0FH

MOV P2,LED0

MOV A,45H  从拆字的出口获取值

MOVC A,@A+DPTR

MOV P0,A

LCALL DELY10MS

MOV P2,LED1

MOV A,46H

MOVC A,@A+DPTR

MOV P0,A

LCALL DELY10MS

RET

DISPLAY34: MOV A,MODE_RG   判断模式,决定是显示闹钟时间还是显示当前时间

CJNE A,MODE4,DIS31

LJMP DIS32

DIS31: CJNE A,MODE5,DIS35

DIS32: MOV R7,M_ALARM

LJMP DIS34

DIS35: CJNE A,MODE6,DIS41

MOV R7,S_SEC   秒表模式,显示秒表低位

LJMP DIS34

DIS41: CJNE A,MODE1,DIS33

MOV R7,SEC

LJMP DIS34

DIS33: MOV R7,MIN  DISPLAY34显示低位

DIS34: LCALL BCTD

MOV A,R4

MOV R3,A

LCALL DIVIDE

MOV P2,LED2

MOV A,47H

MOVC A,@A+DPTR

MOV P0,A

LCALL DELY10MS

MOV P2,LED3

MOV A,48H

MOVC A,@A+DPTR

MOV P0,A

LCALL DELY10MS

SETB P2.3

RET

--------------------二翻十:入口:R6R7 出口:R2R3R4----------------------

BCTD: MOV R5,#16

CLR A

MOV R2,A

MOV R3,A

MOV R4,A

LOOP: CLR C

MOV A,R7

RLC A

MOV R7,A

MOV A,R6

RLC A

MOV R6,A

MOV A,R4

ADDC A,R4

DA A

MOV R4,A

MOV A,R3

ADDC A,R3

DA A

MOV R3,A

MOV A,R2

ADDC A,R2

DA A

MOV R2,A

DJNZ R5,LOOP

RET

-----------------------拆字:入口:R3R4 出口:45H46H47H48H------------------

DIVIDE: MOV A,R3

ANL A,#0FH

MOV 46H,A

MOV A,R3

ANL A,#0F0H

SWAP A

MOV 45H,A      时拆字 45H放时高位,46H放十低位

MOV A,R4

ANL A,#0FH

MOV 48H,A

MOV A,R4

ANL A,#0F0H

SWAP A

MOV 47H,A      分拆字 47H放分高位,48H放分低位

RET

------------------------------------延时----------------------------------

DELY10MS:   MOV R6,#10

D1:         MOV R7,#248

DJNZ R7,$

DJNZ R6,D1

RET

DELAY: MOV 74H,#2 延时子程序,12M晶振延时1.002秒

L3:  MOV 72H ,#10

L1:  MOV 73H ,#249

L2:  DJNZ 73H ,L2

LCALL DISPLAY12

LCALL DISPLAY34

JNB DOWN_KEY,OFFALARM1

LJMP S3

OFFALARM1: LCALL DELY10MS

JB DOWN_KEY,S3

S4: JNB DOWN_KEY,S4

MOV F_ALARM,#0

SETB P3.6

LJMP MAIN1

S3: DJNZ 72H ,L1

DJNZ 74H ,L3

RET

NUMTAB:     DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,88H,83H,0C6H,0A1H,86H,8EH  码表

END