让51单片机闹钟响十秒怎样写程序?

让51单片机闹钟响十秒怎样写程序?,第1张

显示格式为“时时分分”。由分位闪动来做秒计数表示。

一旦时间到则发出声响。

程序执行后工作洞轮让指示灯LED闪动,表示程序开始执行,显示器显示“0000”,按下 *** 作键K1~K4动作如下:

(1) K1—设置现在的时间。

(2) K2—显示闹钟设置的时间。

(3) K3—纳局设置闹铃的时间。

(4) K4—闹铃ON/OFF的状态设置,设置为ON时连续三次发出桐游“哗”的一声,设置为OFF发出“哗”的一声。

设置当前时间或闹铃时间如下。

(1) K1—时调整。

(2) K2—分调整。

(3) K3—设置完成。

(4) K4—闹铃时间到时,发出一阵声响,按下本键可以停止声响。

duanEQUP0

weiEQUP2

keyBITP3.7

ORG0000H

AJMPMAIN绝对转移指令,2kb范围(11位)内跳转LJMP16位64kb范围内跳转

短转移指令的功能是先使程序计数器PC加1两次(即:取出指令码),然后把加2后的地址和rel相加作为目标转移地址。因此,短转移指令是一条相对转移指令,是一条双字节双周期庆笑指令

ORG0030H指明后面的程序从程序存储器的历困0030H单元开始存放

DELAY200US:@11.0592MHz

NOP

NOP

NOP

PUSH30H

PUSH31H

MOV30H,#2

MOV31H,#179

NEXT:

DJNZ31H,NEXT

DJNZ30H,NEXT

POP31H

POP30H

RET

ORG0060H

DISPLAY子程序

DISPLAY:

PUSHACC不能写A,此处ACC代表地址,push后跟地址,代表把地址内的内容压入栈中

PUSH00HR0

PUSH06HR6

PUSH07HR7

PUSH83HDPH

PUSH82HDPL

MOVR6,#01H位选数据,01指的是缓冲区最低位数据

MOVR7,#08H循环次数

FLAG:

MOVduan,#0x00消影

MOVA,R6

CPLA取反

MOVwei,A位选

MOVA,#disBufDat

ADDA,R7

SUBBA,#0X08

MOVR0,A

MOVA,@R0读出要显示的数据到A

MOVDPTR,#disTab

MOVCA,@A+DPTR从rom取数据,取出要显示的数据对应的段码

MOVduan,A段选

MOVA,R6

RLA

MOVR6,A更新下一次位选

LCALLDELAY200US

DJNZR7,FLAG

POP82HDPL

POP83HDPH

POP07H

POP06H

POP00H

POPACC

RET

ORG0100H

定时器中断0初始化

T0_INIT:

MOVTMOD,#0X01

MOVTH0,#0X3C

MOVTL0,#0XB0

SETBEA

SETBTR0

SETBET0

RET

ORG0130H

T0中断处理程序

INT_TIMERE0:

PUSHACC

SETBRS0

MOVTH0,#0X3C

MOVTL0,#0XB0

INCR0

MOVA,R0

SUBBA,#0X14

JBCY,SECFLAG

MOVR0,#0x00

INCsec

SECFLAG:

CLRRS0

POPACC

RETI

ORG000BH定时器/计数器T0入口地址

LJMPINT_TIMERE0跳转到定肢差念时器/计数器中断服务程序中去

disTab:DB0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x400-f,空白,横杠的段选数据

disBufDatEQU47H定义显示缓冲数据变量区,8个

disBufDatHeadEQU40H//单片机上显示在最左边

secEQU48H

主程序

ORG0180H

MAIN:

MOVSP,#0X60将0x60到0x7f设为堆栈区

LCALLT0_INIT

MOVdisBufDatHead,#0X00

MOVdisBufDatHead+1,#0X00

MOVdisBufDatHead+2,#0X11

MOVdisBufDatHead+3,#0X11

MOVdisBufDatHead+4,#0X11

MOVdisBufDatHead+5,#0X11

MOVdisBufDatHead+6,#0X11

MOVdisBufDatHead+7,#0X11

MOVsec,#0X3A

WHILE:

JBkey,KEYSCAN

MOVsec,0x00

KEYSCAN:

MOVA,sec

SUBBA,#3CH超过60s归零

JBCY,CLEAR

MOVsec,#0X00clr加ram地址无效

CLEAR:

MOVA,sec

MOVB,#0AH

DIVABA/B,商存到A中,余数存B中

MOVdisBufDatHead,A

MOVdisBufDatHead+1,B

LCALLDISPLAY

LJMPWHILE循环

END

扩展资料

51机器周期和指令周期

1、机器周期是指单片机完成一个基本 *** 作所花费的时间,一般使用微秒来计量单片机的运行速度,51单片机的一个机器周期包括12个时钟振荡周期,也就是说如果51单片机采用12MHz晶振,那么执行一个机器周期就只需要1μs如果采用的是6MHz的晶振,那么执行一个机器周期就需要2μs。

2、指令周期是指单片机执行一条指令所需要的时间,一般利用单片机的机器周期来计量指令周期。在51单片机里有单周期指令(执行这条指令只需一个机器周期),双周期指令(执行这条指令只需要两个机器周期),四周期指令(执行这条指令需要四个机器周期)。

除了乘、除两条指令是四周期指令,其余均为单周期或双周期指令。也就是说,如果51单片机采用的是12MHz晶振,那么它执行一条指令一般只需1~2微秒的时间如果采用的是6MH晶振,执行一条指令一般就需2~4微秒的时间。

//*********************************************************

//实现功能:本程序实现在P1口模拟一个流水灯程序

//*********************************************************

#include <reg51.h>

#define p_out P1 //宏定义输出的i/o口为P1

//******************时间延迟函数**********************

//描伏中 述:用指令实现延时一段时间

//入口参数:int i,为时间延迟参数

//****************************************************

void delay_time(int i)

{

while(i)

i--

}

//******************主函数***************************

//描 述:实现在P1口模拟一个流水灯程序

//****************************************************

void main(void)

{unsigned char i=0 //初始化一个局部变量为悉厅备0

p_out=0xff //初始化将要输出的i/o口,输出高电平,熄灭所有灯

while(1)

{

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

{

p_out=~(1<<i)//点亮一个灯,

delay_time(50000) //延迟一段时间

p_out=0xff//熄灭所有灯

}

}

}

//**************************************

//****************************************************

//实现功能:把键盘输入的键盘码,用led显示出来

//****************************************************

#include <reg51.h>

#define p_key P1

#define led_date P0

#define choose_p P2

unsigned char change(unsigned char i)

unsigned int display_num=0

//******************时间延迟函数**********************

//描 述:用指令实现延睁毁时一段时间

//入口参数:int i,为时间延迟参数

//****************************************************

void delay_time(int i)

{

while(i)

i--

}

//******************按键扫描函数**********************

//描述:对4*4键盘进行扫描,程序只适合4*4键盘使用,

// 键盘占用一组完整的i/o口,在使用这个程序前

// 要宏定义p_key为用户实际连接键盘的i/o口

// #define p_key Pn//(n=0、1、2、3)

//返回参数:若有检测到按键就返回按键的编号,否则返回0xff

//****************************************************

unsigned char read_key(void)

{

unsigned char j,key,key_buf=0

p_key=0xff

//检测是否有建按下//

p_key=0xf0

key=p_key

if(key==0xf0)

{

return(0xff)//没按键按下,返回0xff

}

//有按下,延时去抖//

delay_time(5000)

//确认是否有建按下//

p_key=0xf0

key=p_key

if(key==0xf0)

{

return(0xff)//没按键按下,返回0xff

}

//真的有按键按下,扫描是哪一行有按键按下//

for(j=0j<4j++)

{key=p_key&(0x10<<j)

if (key)

{

key=p_key

}

else

{

key_buf=j*4

p_key=~(0x10<<j)//第j行的按键按下了,第j行输出0,其他的i/o口输出1

//扫描是第j行的哪个按键按下//

for(j=0j<4j++)

{

key=p_key&(1<<j)

if (key)

{

key=p_key

}

else

{

key_buf+=j

return(key_buf)//扫描到按键的确定位置,返回按键的编号

}

}

}

}

//没扫描到按键,//

return(0xff)

}

//***************七段数码管显示函数*******************

//描述:对四位的扫描型七段数码管进行扫描显示,在使用

// 前要定义一个全局变量display_num

// unsigned int display_num

//入口参数:unsigned int num,要显示的数字(0-9999)

//****************************************************

void display(unsigned int num)

{

if(num<10000)

{

display_num=num

}

choose_p|=3//先关显示

led_date=change(display_num/1000)//得到千位的数字,并转换成七段码型

choose_p&=0xfe//选通千位

delay_time(50)//延时一段时间

choose_p|=1//关显示

display_num=display_num%1000

led_date=change(display_num/100)//得到百位的数字,并转换成七段码型

choose_p&=0xfd//选通百位

delay_time(50)//延时一段时间

choose_p|=2//关显示

display_num=display_num%100

led_date=change(display_num/10)//得到十位的数字,并转换成七段码型

choose_p&=0xfb//选通十位

delay_time(50)//延时一段时间

choose_p|=4//关显示

led_date=change(display_num%10)//得到个位的数字,并转换成七段码型

choose_p&=0xf7//选通十位

delay_time(50)//延时一段时间

choose_p|=8//关显示

}

//****************数字-码型转换函数*******************

//描述:把数字转换成七段码型,此程序仅配合共阳的七

// 段数码管使用

//入口参数:unsigned char i,要转换的数字(0-9),

//返回参数:转换后的七段码型,0xff表示转换失败

//****************************************************

unsigned char change(unsigned char i)

{

switch(i)

{

case 0:

return(0xc0)//0的七段码型

case 1:

return(0xf9)//1的七段码型

case 2:

return(0xa4)//2的七段码型

case 3:

return(0xb0)//3的七段码型

case 4:

return(0x99)//4的七段码型

case 5:

return(0x92)//5的七段码型

case 6:

return(0x82)//6的七段码型

case 7:

return(0xf8)//7的七段码型

case 8:

return(0x80)//8的七段码型

case 9:

return(0x90)//9的七段码型

default:

return(0xff)//转换失败

}

}

//*********************主函数*************************

//描述:把键盘输入的键盘码,用led显示出来

//****************************************************

int main(void)

{unsigned char i

while(1)

{

i=read_key()//扫描键盘

if(i<16)

display((unsigned int)i)//有效的键盘值

else

display(0xffff)//数据无效

}

}

//两个程序加起来就可以完成你要求的功能,有说明,你认真看一下吧。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12322180.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-22
下一篇2023-05-22

发表评论

登录后才能评论

评论列表(0条)

    保存