如何拿单片机用C语言编程做一个闹钟?

如何拿单片机用C语言编程做一个闹钟?,第1张

下面的程序就是用AT89C2051做的数字式时钟,数码管显示,具有闹钟功能,整点报时,几点蜂鸣器响几下,晚上九点到第二天早上六点整点不报时。给你参考一下吧。

#include<AT89X051h>

#include<intrinsh>

#define uint unsigned int

#define uchar unsigned char

sbit sda=P3^1;

sbit scl=P3^0;

sbit key1=P1^7;

sbit key2=P1^6;

sbit key3=P1^5;

sbit kz=P3^5;

sbit bs=P3^4;

char shi=12,fen=12,ke1,mm,mi,nh,nf,mn,mms,baos,a;

bit ms,nt,b;

uchar code SEG8[]={ 0x50,0x5F,0x94,0x15,0x1B,

0x31,0x30,0x57,0x10,0x11,

0x40,0x4F,0x84,0x05,0x0B,

0x21,0x20,0x47,0x00,0x01,

0x21,0xa2,0x52,0xff};

//0-9,0-9;s,f,n 暗

void delay1ms(uchar ms)

{

uchar i;

while(ms--)

{

for(i = 0; i< 250; i++)

{

_nop_();

_nop_();

_nop_();

_nop_();

}

}

}

void display(char numh,char numf)

{

uchar qian,bai,sh,ge;

if(ke1==1)

qian=20;

else if(ke1==2)

qian=21;

else if((ke1==3)||(ke1==4))

qian=22;

else if(ke1==0)

qian=numh/10;

if((ke1==1)||(ke1==2))

bai=23;

else if(ke1==3)

bai=20;

else if(ke1==4)

bai=21;

else if(ke1==0)

{

bai=numh%10;

if(ms)

bai=bai+10;

}

if((ke1==1)||(ke1==3))

{sh=numh/10;ge=numh%10;}

else if((ke1==2)||(ke1==4)||(ke1==0))

{sh=numf/10;ge=numf%10;}

P1=SEG8[qian];

P3_3=0;delay1ms(2);P3_3=1;

P1=SEG8[bai];

P3_7=0;delay1ms(2);P3_7=1;

P1=SEG8[sh];

P3_2=0;delay1ms(2);P3_2=1;

P1=SEG8[ge];

P3_0=0;delay1ms(2);P3_0=1;

}

///////////x24c02//////////////////

void delay24()

{ ;; }

void init24c02() //初始化

{

sda=1;

delay24();

scl=1;

delay24();

}

void start2() //开始信号

{

sda=1;

delay24();

scl=1;

delay24();

sda=0;

delay24();

}

void stop() //停止

{

sda=0;

delay24();

scl=1;

delay24();

sda=1;

delay24();

}

void respons() //应答

{

uchar i;

scl=1;

delay24();

while((sda==1)&&(i<250))i++;

scl=0;

delay24();

}

void write_byte(char date) // 写数据子函数

{

uchar i,temp;

temp=date;

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

{

temp=temp<<1;

scl=0;

delay24();

sda=CY;

delay24();

scl=1;

delay24();

}

scl=0;

delay24();

sda=1;

delay24();

}

uchar read_byte() // 读数据子函数

{

uchar i,k;

scl=0;

delay24();

sda=1;

delay24();

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

{

scl=1;

delay24();

k=(k<<1)|sda;

scl=0;

delay24();

}

return k;

}

///////写数据函数///////////////////

void write_add(uchar address,char date)

{

start2();

write_byte(0xa0);

respons();

write_byte(address);

respons();

write_byte(date);

respons();

stop();

}

char read_add(uchar address) //读数据函数

{

uchar date;

start2();

write_byte(0xa0);

respons();

write_byte(address);

respons();

start2();

write_byte(0xa1);

respons();

date=read_byte();

stop();

return date;

}

void keyf(char con,char up,char don)

{

uint i;

for(i=0;i<800;i++)

{

if((ke1==1)||(ke1==2))

display(shi,fen);

else if((ke1==3)||(ke1==4))

display(nh,nf);

P1=0xff;

if(key1==0)

{

delay1ms(10);

if(key1==0)

{

ke1++;

if(ke1>=5)

ke1=0;

while(!key1);

break;

}

}

if(key2==0)

{

delay1ms(10);

if(key2==0)

{

i=0;

con+=1;

if(con>up)

con=0;

while(!key2);

}

}

if(key3==0)

{

delay1ms(10);

if(key3==0)

{

i=0;

con-=1;

if(con<don)

con=up;

while(!key3);

}

}

}

}

void key()

{

P1=0xff;

if(key1==0)

{

EA=0;

delay1ms(20);

if(key1==0)

{

ke1++;

if(ke1>=5)

ke1=0;

while(!key1);

}

if(ke1==1)

{

keyf(&shi,23,0);

}

if(ke1==2)

{

keyf(&fen,59,0);

}

if(ke1==3)

{

keyf(&nh,23,0);

}

if(ke1==4)

{

keyf(&nf,59,0);

}

P1=0xff;P3=0xff;

write_add(0x01,nh);

delay1ms(5);

write_add(0x03,nf);

ke1=0;

EA=1;

}

}

void Timer0Init(void)

{

TMOD |= 0x01;

TL0 = 0xB0;

TH0 = 0x3C;

TF0 = 0;

TR0 = 1;

EA=1;

ET0=1;

}

void main()

{

P1=0xff;

P3=0xff;

init24c02();

nh=read_add(0x01);

delay1ms(50);

nf=read_add(0x03);

delay1ms(50);

Timer0Init();

while(1)

{

key();

display(shi,fen);

}

}

void tim0 ()interrupt 1

{

TH0=0X3C;

TL0=0XB0;

if(++mms>=10)

{

mms=0;

ms=!ms;

}

if(++mm>=20)

{

mm=0;

if(++mi>=60)

{

mi=0;

if(++fen>=60)

{

fen=0;

if(++shi>=24)

shi=0;

}

}

}

if(fen==0)

{

if((shi>=7)&&(shi<=20))

{

if((baos==0)&&(b==0))

{

baos=shi;

baos=baos2;

b=1;

}

if(++a==10)

{

a=0;

if(--baos!=0)

{

bs=!bs;

}

else

{

bs=1;

}

}

}

}

else

b=0;

if(nh==shi)

{

if(nf==fen)

{

if(nt==0)

{

P1=0xff;

if(++mn==10)

{

mn=0;

kz=!kz;

}

if(key3==0)

{

nt=1;

kz=1;

}

}

}

else

{

nt=0;

kz=1;

}

}

}

先简单给你个思路吧,可以考虑用状态机的方式来写程序,就拿一档换二档为例一档是一个状态,空档是一个状态,二档是一个状态,熄火是一个状态初始状态在一档,当你检测到档位变成空档的时候,程序进入空档状态,在这个状态里面,定时器打开,一直检测是否超时,如果在超时前发现输入变到了二档,那么程序进入二档状态,同时输出二档的代码,如果时间到了还没有检测到档位变换,那么就进入熄火状态,就是这样,本来想给你画个图,但是我电脑有点问题,上传不了

然后说计时的问题,有一种简单的方法就是用定时器的终端累加来计时,比如说你把定时器设置为1ms,并且打开溢出中断,那么定时器在计时1ms的时候就会产生一次中断,你设置一个变量,定时器每进行一次中断,变量就加1,这样等变量加到1000的时候你就知道1s到了

1、理解基本原理,学习单片机前,了解计算机体系结构、数字电子学和微控制器的基本原理是很重要的,包括了解中央处理器、存储器、输入/输出接口和时钟等组成部分的功能和工作原理。

2、掌握编程语言,单片机使用汇编语言或高级编程语言进行编程,掌握相应的编程语言,如C语言或汇编语言,是学好单片机的基础,了解编程语言的语法、数据类型、控制结构和函数等概念,并能够编写简单的程序。

单片机系统实现对舵机输出转角的控制,必须首先完成两项任务:首先,产生基本的PWM周期信号,即产生20ms的周期信号;其次,调整脉宽,即单片机调节PWM信号的占空比。单片机能使PWM信号的脉冲宽度实现微秒级的变化,从而提高舵机的转角精度。单片机完成控制算法,再将PWM信号输出到舵机。

发一个自己原来写的简单的。

#include<reg52h>

#define uchar unsigned char

#define uint unsigned int

uchar count,jd;

sbit pwm=P1^0;

sbit jia=P3^2;

sbit jian=P3^3;

uchar code table[10] = {0x3f,0x06,0x5b,

0x4f,0x66,0x6d,

0x7d,0x07,0x7f,0x6f};

//延时函数

void delay(uchar x)

{

uchar i,j;

for(i=x;i>0;i--)

for(j=125;j>0;j--);

}

//定时器初始化

void Time0_init()

{

TMOD=0x01; //定时器0工作方式1

IE=0x82;

TH0=0xfe;

TL0=0x33; //110592MHZ晶振,05ms

TR0=1;

}

//定时器0中断程序

void Time0() interrupt 1

{

TH0=0xfe;

TL0=0x33;

if(count<jd) //判断05ms次数是否小于角度标识

pwm=1; //是,pwm输出高电平

else

pwm=0; //否,输出低电平

count=count+1;

count=count%40; //次数始终保持为40,即保持周期为20ms

}

//按键扫描

void keyscan()

{

if(jia==0)

{

delay(10);

if(jia==0)

{

jd++; //角度增加 1

count=0; //按键按下则20ms周期重新开始计时

if(jd==6)

jd=5; //已经是180度,保持

while(jia==0);

}

}

if(jian==0)

{

delay(10);

if(jian==0)

{

jd--;

count=0;

if(jd==0)

jd=1; //已经0度,保持

while(jian==0);

}

}

}

//数码管显示

void display()

{

uchar bai ,shi,ge ;

switch(jd)

{

case 1:

bai=0;

shi=0;

ge=0;

break;

case 2:

bai=0;

shi=4;

ge=5;

break;

case 3:

bai=0;

shi=9;

ge=0;

break;

case 4:

bai=1;

shi=3;

ge=5;

break;

case 5:

bai=1;

shi=8;

ge=0;

break;

}

P0=table[bai];

P2=1;

delay(5);

P0=table[shi];

P2=2;

delay(5);

P0=table[ge];

P2=3;

delay(5);

}

void main()

{

//jd=1;

count=0;

Time0_init();

while(1)

{

keyscan();

display();

}

}

电路图很简单的,几个按键,再在单片机最小系统上接出一个信号线,再给舵机供上电就可以了。

欢迎分享,转载请注明来源:浪漫分享网

原文地址:https://hunlipic.com/langman/3376580.html

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

发表评论

登录后才能评论

评论列表(0条)

    保存