方案论证主要是写你做设计时有几种可选的方案比如用stc51单片机还是lpc51或者用pic还有时钟芯片选择还有显示用1284还是1602等等
说说各自的优缺点最后经过对比选择较合适的那一种,比如从成本的对比,控制的对比,性能的对比还有就是可行性,希望帮到你
#include<reg52h>
#include<intrinsh>
#define uchar unsigned char
#define uint unsigned int
sbit dq=P3^7; //////18b20
sbit lcden=P2^7; ////lcd
sbit rs=P2^6;
sbit wr=P2^5;
sbit sck=P3^6; ////1302
sbit sda=P3^4;
sbit rst=P3^5;
sbit a=P1^0;
sbit b=P1^1;
sbit c=P1^2;
sbit d=P1^3;
sbit kj=P1^4;
sbit beep=P1^5;
uchar ritime;
uchar startflag;
uchar ridate[33];
uchar bitnum;
uchar rireceok;
uchar ricode[4];
uchar riprosok;
uchar dis[8];
void dis_key(void);
void riwork(void);
void ripros(void);
void keyscan(void);
void bep(void);
void timer0init(void);
void init0init(void);
uchar key0,key1,key2,key0num,passwordok;
uchar key,p,m,pnum,sha;
uchar password[9];
uchar password1[9]={6,7,4,6,8,8,6,4,6};
void password_scan();
void post_key();
void dj1();
void dj2();
//////////////////////函数声明1302
void wr1302_byte(uchar byte);
void wr1302 (uchar add,uchar dat);
uchar read1302(uchar add);
uchar time_date[7]={10,3,12,8,21,37,20};////年周月日时分秒
uchar time_add[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};////写入地址
uchar read_add[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};////读出地址
uchar disp[13]; ////将读出时间装入
void set_rtc();
void read_rtc();
void timepost(); ////处理时间为10进制
void display();
void password_display();
void timeplay();
void runnian1(); ///闰年加
void runnian2(); ///闰年减
void keypost(); //按键处理
///////////////////////////// 函数声明 lcd ////////////////////
uchar code lcd_tab[]="0123456789- ():c";
uchar code lcd_tab1[]="Plese Password:";
uchar code table1[]="key=00-00-00-00";
uchar code table[]=" QQ:674688646";
uchar code numtab[]="0123456789ABCDEF";
uchar code numtab1[]=" 1234567890";
void delay(uint z);
void init_lcd();
void write_com(uchar com);
void write_date(uchar x);
///////////////////////////18b20////////////
void init18b20(void);
void wr1820_byte(uchar dat);
uchar read18b20_byte(void);
uchar read1820(void);
void delay1(uint t);
//////////////////////////////////////////
void timer0init(void) //开定时器2
{
TMOD=0X02;
TH0=0X00;
TL0=0X00;
ET0=1;
EA=1;
TR0=1;
}
void init0init(void) //外部中断
{
IT0=1;
EX0=1;
EA=1;
}
void riwork(void)
{
dis[0]=ricode[0]/16;
dis[1]=ricode[0]%16;
dis[2]=ricode[1]/16;
dis[3]=ricode[1]%16;
dis[4]=ricode[2]/16;
dis[5]=ricode[2]%16;
dis[6]=ricode[3]/16;
dis[7]=ricode[3]%16;
}
void ripros(void)
{ uchar j,k,i,value;
k=1;
for(j=0;j<4;j++)
{
for(i=0;i<8;i++)
{
value=value>>1;
if(ridate[k]>6)
{
value=value|0x80;
}
k++;
}
ricode[j]=value;
}
riprosok=1;
}
void timer0 () interrupt 1
{
ritime++;
}
void int0() interrupt 0
{
if(startflag==1)
{
if(ritime>32)//检测引导码
{
bitnum=0;
}
ridate[bitnum]=ritime;
ritime=0;
bitnum++;
if(bitnum==33)
{
bitnum=0;
rireceok=1;
}
}
else
{
startflag=1;
ritime=0;
}
}
void keyscan(void)
{ if(rireceok==1)
{bep(); //按键发声 但影响蜂鸣器 *** 作
ripros();
rireceok=0;
}
if(riprosok==1)
{ riwork();
riprosok=0;
switch(ricode[2])
{ case 0x46:p=1;pnum++;break;
case 0x0c:key=1;break;
case 0x18:key=2;break;
case 0x5e:key=3;break;
case 0x08:key=4;break;
case 0x1c:key=5;break;
case 0x5a:key=6;break;
case 0x42:key=7;break;
case 0x52:key=8;break;
case 0x4a:key=9;break;
case 0x16:key=10;break;
case 0x09:key0=1;key0num++;break;
case 0x15:key1=1;break;
case 0x07:sha=1;key2=1;break;
if(key0==1){if(key0num==1)read_rtc();}
}
}
////按下设定键后读一次1302保证time_date内数据正常
}
void bep(void)
{
beep=0;delay(100);beep=1;
}
///////////////////////////////////////////////////////////
void write_com(uchar com) /////写命令
{
rs=0;
P0=com;
lcden=1;
delay(5);
lcden=0;
}
void write_date(uchar x)/////写数据
{
rs=1;
P0=x;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init_lcd()// ///lcd初始化
{
wr=0;
lcden=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
}
void display()
{timepost();
write_com(0x80+2);
write_date(lcd_tab[2]);
write_date(lcd_tab[0]);
write_date(lcd_tab[disp[0]]);
write_date(lcd_tab[disp[1]]);
write_date(lcd_tab[10]);
write_date(lcd_tab[disp[3]]);
write_date(lcd_tab[disp[4]]);
write_date(lcd_tab[10]);
write_date(lcd_tab[disp[5]]);
write_date(lcd_tab[disp[6]]);
write_date(lcd_tab[11]);
write_date(lcd_tab[12]);
write_date(lcd_tab[disp[2]]);
write_date(lcd_tab[13]);
write_com(0x80+0x40+4);/////////第二行
write_date(lcd_tab[disp[7]]);
write_date(lcd_tab[disp[8]]);
write_date(lcd_tab[14]);
write_date(lcd_tab[disp[9]]);
write_date(lcd_tab[disp[10]]);
write_date(lcd_tab[14]);
write_date(lcd_tab[disp[11]]);
write_date(lcd_tab[disp[12]]);
write_date(lcd_tab[11]);
write_date(lcd_tab[read1820()/10]);/////显示温度
write_date(lcd_tab[read1820()%10]);
write_date(lcd_tab[15]);
}
//////////////// 1302 //////////////////////////////
void wr1302_byte(uchar byte) /////写入一个字节
{ uchar i;
for(i=0;i<8;i++)
{ sck=0;
sda=byte&0x01;
byte>>=1;
sck=1;
}
}
void wr1302 (uchar add,uchar dat)/////写进1302 时间和地址
{ rst=0;
_nop_();
sck=0;
_nop_();
rst=1;
_nop_();
wr1302_byte(add);
wr1302_byte(dat);
rst=0;
//_nop_();
//sda=1;
//sck=1;
}
uchar read1302(uchar add)
{ uchar i,temp;
rst=0;
_nop_();
sck=0;
_nop_();
rst=1;
_nop_();
wr1302_byte(add);////////////////////写入要读的地址
for(i=0;i<8;i++)
{
if(sda)temp=temp|0x80;
sck=0;
temp>>=1;
_nop_();
sck=1;
}
rst=0; //////// 延时很重要
_nop_();
sck=0;
_nop_();
sck=1;
_nop_();
sda=0;
_nop_();
sda=1;
_nop_();
return temp;
}
void set_rtc()
{
uchar i,j;
for(i=0;i<7;i++)
{
j=time_date[i]/10; ///////将10进制变成16进制
time_date[i]=time_date[i]%10;
time_date[i]=time_date[i]+j16;
}
wr1302(0x8e,0x00);//////去除写保护
for(i=0;i<7;i++)
{
wr1302(time_add[i],time_date[i]);
}
wr1302(0x8e,0x80);//////加写保护
}
void read_rtc()
{uchar i,j;
for(i=0;i<7;i++)
{
time_date[i]=read1302(read_add[i]);
////将读到的bcd码转化成10进制码
j=time_date[i]&0x0f;
time_date[i]>>=4;
time_date[i]&=0x0f;
time_date[i]=10;
time_date[i]=time_date[i]+j;
}
}
void timepost()
{ disp[0]=time_date[0]/10;/////年
disp[1]=time_date[0]%10;
disp[2]=time_date[1]%10;/////周
disp[3]=time_date[2]/10;/////月
disp[4]=time_date[2]%10;/////
disp[5]=time_date[3]/10;/////日
disp[6]=time_date[3]%10;////
disp[7]=time_date[4]/10;////时
disp[8]=time_date[4]%10;////
disp[9]=time_date[5]/10;////分
disp[10]=time_date[5]%10;////
disp[11]=time_date[6]/10;////秒
disp[12]=time_date[6]%10;////
}
void delay(uint z)
{
uint x,y;
for(x=0;x<20;x++)
for(y=z;y>0;y--);
}
/////////////////////////18b20////////
void delay1(uint t)
{
while (t--);
}
void init18b20(void)
{
uchar n;
dq=1;
delay1(8);
dq=0;
delay1(80);
dq=1;
delay1(8);
n=dq;
delay1(4);
}
void wr18b20_byte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
dq=0;
dq=dat&0x01;
delay1(4);
dq=1;
dat>>=1;
}
delay1(4);
}
uchar read18b20_byte(void)
{
uchar i,value;
for(i=0;i<8;i++)
{ dq=0;
value>>=1;
dq=1;
if(dq)
value|=0x80;
delay1(4);
}
return value;
}
uchar read1820(void)
{ uchar a,b;
init18b20();
wr18b20_byte(0xcc);
wr18b20_byte(0x44);
delay1(50);
init18b20();
wr18b20_byte(0xcc);
wr18b20_byte(0xbe);
a=read18b20_byte();
b=read18b20_byte();
b<<=4;
b+=(a&0xf0)>>4;
return b;
}
///////////////////////////////////////////////////////
void keypost()
{ uchar n;
if(key0==1)
{
if(key0num==1)
{write_com(0x80+0x40+10);
write_com(0x0f);delay(1000);
if(key1==1)
{ key1=0;n=1;
time_date[6]++;
if(time_date[6]==60)time_date[6]=0;
display();
}
if(key2==1)
{
key2=0;n=1;
time_date[6]--;
if(time_date[6]==-1)time_date[6]=59;
display();
}
}
if(key0num==2)
{write_com(0x80+0x40+8);
write_com(0x0f);delay(1000);
if(key1==1)
{ key1=0;n=1;
time_date[5]++;
if(time_date[5]==60)time_date[5]=0;
display();
}
if(key2==1)
{
key2=0;n=1;
time_date[5]--;
if(time_date[5]==-1)time_date[5]=59;
display();
}
}
if(key0num==3)
{write_com(0x80+0x40+5);
write_com(0x0f);delay(1000);
if(key1==1)
{ key1=0;n=1;
time_date[4]++;
if(time_date[4]==24)time_date[4]=0;
display();
}
if(key2==1)
{
key2=0;n=1;
time_date[4]--;
if(time_date[4]==-1)time_date[4]=23;
display();
}
}
if(key0num==4)
{write_com(0x80+14);
write_com(0x0f);delay(1000);
if(key1==1)
{ key1=0;n=1;
time_date[1]++;
if(time_date[1]==8)time_date[1]=1;
display();
}
if(key2==1)
{
key2=0;n=1;
time_date[1]--;
if(time_date[1]==0)time_date[1]=7;
display();
}
}
if(key0num==5)
{write_com(0x80+10);
write_com(0x0f);delay(1000);
if(key1==1)
{ key1=0;n=1;
time_date[3]++;
runnian1();
display();
}
if(key2==1)
{
key2=0;n=1;
time_date[3]--;
if(time_date[3]<1)time_date[3]=31;
runnian2();
display();
}
}
if(key0num==6)
{write_com(0x80+7);
write_com(0x0f);delay(1000);
if(key1==1)
{ key1=0;n=1;
time_date[2]++;
if(time_date[2]>12)time_date[2]=1;
runnian2();
display();
}
if(key2==1)
{
key2=0;n=1;
time_date[2]--;
if(time_date[2]==0)time_date[2]=12;
runnian2();
display();
}
}
if(key0num==7)
{write_com(0x80+4);
write_com(0x0f);delay(1000);
if(key1==1)
{ key1=0;n=1;
time_date[0]++;
if(time_date[0]==100)time_date[0]=0;
runnian2();
display();
}
if(key2==1)
{
key2=0;n=1;
time_date[0]--;
if(time_date[0]==-1)time_date[0]=99;
runnian2();
display();
}
}
if(key0num==8)
{ key0num=0;key0=0;
write_com(0x0c);
if(n){n=0;set_rtc();}
}
}
else
{
read_rtc();
timepost();
display();
if(time_date[5]==0) ///整点报时
{if(time_date[6]==0)beep=0;
else beep=1;
}
}
}
void runnian1()////闰年加
{
if(time_date[2]==2) /////判断2月
{ if((time_date[0]+4)%4==0)
{ if(time_date[3]>29)time_date[3]=1;}//判断闰年
else
{if(time_date[3]>28)time_date[3]=1;}
}
else
{ if(time_date[2]<8)///判断月小于8
{
if((time_date[2]+1)%2==0)
{if(time_date[3]>31)time_date[3]=1;}
else
{if(time_date[3]>30)time_date[3]=1;}
}
if(time_date[2]>7)
{
if((time_date[2])%2==0)
{if(time_date[3]>31)time_date[3]=1;}
else
{if(time_date[3]>30)time_date[3]=1;}
}
}
}
void runnian2()//闰年减
{
if(time_date[2]==2) /////判断2月
{ if((time_date[0]+4)%4==0)
{ if(time_date[3]>29)time_date[3]=29;}//判断闰年
else
{if(time_date[3]>28)time_date[3]=28;}
}
else
{
if(time_date[2]<8)///判断月小于8
{
if((time_date[2]+1)%2==0)
{if(time_date[3]>31)time_date[3]=31;}
else
{if(time_date[3]>30)time_date[3]=30;}
}
if(time_date[2]>7)
{
if((time_date[2])%2==0)
{if(time_date[3]>31)time_date[3]=31;}
else
{if(time_date[3]>30)time_date[3]=30;}
}
}
}
void password_scan() ////////输入密码界面
{uchar l,i,j;
write_com(0x80);
for(l=0;l<15;l++)
{write_date(lcd_tab1[l]);}
write_com(0x80+0x40+4+i);
write_com(0x0f);delay(1000);
if(key!=0)
{
password[i]=key;
write_com(0x80+0x40+4+i);
write_date(numtab1[key]);
write_com(0x14);
i++;key=0;
}
if(i>0)
{if(sha==1)
{sha=0;i--;
write_com(0x80+0x40+4+i);
write_date(numtab1[0]);
write_com(0x10);
}
}
if(i==9)
{ i=0;
for(j=0;j<9;j++)
{
if(password1[j]==password[j])m++;
else {init_lcd();m=0;break;}
}
if(m==9)
{
m=0;passwordok=1;
p=0;pnum=0;key=0;
init_lcd();
for(i=0;i<15;i++)
{write_date(table[i]);}
write_com(0x80+0x40);
for(i=0;i<15;i++)
{write_date(table1[i]);}
}
}
}
void dis_key(void) //显示键值
{
write_com(0x80+0x40+4);
write_date(numtab[dis[0]]);
write_date(numtab[dis[1]]);
write_com(0x80+0x40+7);
write_date(numtab[dis[2]]);
write_date(numtab[dis[3]]);
write_com(0x80+0x40+10);
write_date(numtab[dis[4]]);
write_date(numtab[dis[5]]);
write_com(0x80+0x40+13);
write_date(numtab[dis[6]]);
write_date(numtab[dis[7]]);
}
void timeplay()
{
if(p==1)
{ uchar v;key0num=0;key0=0;
if(v==0){v=1;init_lcd();key=0;}
if(pnum==1)
{
password_scan();
}
if(pnum==2)
{ p=0;pnum=0;m=0;v=0;
init_lcd();
}
}
else keypost();
}
//////////////////////////主函数////////////////////////
void main()
{
init_lcd(); /////初始化lcd
timer0init();///// 开定时器中断
init0init();///// 开外部器中断
key=0;
while(1)
{
keyscan();
if(passwordok)
{ dis_key();
post_key();
if(p==1)
{ if(pnum==1)
{if(ricode[2]!=0x46)pnum=0;}
if(pnum==2)
{pnum=0;m=0;
passwordok=0;p=0;
break;
}
}
}
else timeplay();
}
}
void post_key()
{
if(key==1){key=0;kj=0;}
if(key==2){key=0;kj=1;}
if(key==3){key=0;dj1();}
if(key==4){key=0;dj2();}
}
void dj1()
{
uint i;
for(i=0;i<512;i++)
{if(rireceok==1)break;
a=0;b=0;delay(20);
a=1;b=0;delay(20);
b=0;c=0;delay(20);
b=1;c=0;delay(20);
c=0;d=0;delay(20);
c=1;d=0;delay(20);
d=0;a=0;delay(20);
d=1;delay(20);
}
}
void dj2()
{ uint i;
for(i=0;i<512;i++)
{if(rireceok==1)break;
d=0;a=0;delay(20);
a=1;d=0;delay(20);
c=0;d=0;delay(20);
c=0;d=1;delay(20);
b=0;c=0;delay(20);
c=1;b=0;delay(20);
a=0;b=0;delay(20);
a=0;b=1;delay(20);
}
}
使用方法 本程序用于HC6800 V26 实验箱,需要装上1602液晶屏,18b20 温度传感器,红外接收头,和步进电机,同时保证遥控器好用(要用配套的小遥控器并且要按键值和我的一样才能准确的 *** 作本程序)
我的遥控器按键值如下
ch-0x45 ch 0x46 ch+0x47
<< 0x44 >> 0x40 >= 0x43
- 0x07 + 0x15 EQ 0x09
0 0x16 100+ 0x19 200+ 0x0d
1 0x0c 2 0x18 3 0x5e
4 0x08 5 0x1c 6 0x5a
7 0x42 8 0x52 9 0x4a
主要 *** 作键为 ch EQ + - 123456789 等键,
程序下进去后 1602会显示日期 时间 温度
用EQ键可对日期 时间进行设定
用+ - 键对日期时间进行调节
调节日期时会自动识别大小月,及闰年并对日期进行相应调整
按下ch键后 会进入输入密码界面 依次输入674688646 会进入按键读值界面 ,输入错误可用 - 键退回
在按键读值界面 连续按两次ch 键后,程序 会退出到时间显示界面
在按键读值界面 按1 打开继电器 按2 关闭继电器 按3 步进电机正转一周,按 4 步进电机反转一周 ,步进电机转的过程中按其他键,步进电机停止
#include<reg52h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^7;
sbit rs=P3^5;
sbit lcden=P3^4;
sbit s1=P3^0;
sbit s2=P3^1;
sbit s3=P3^2;
sbit rd=P3^7;
uchar count,s1num;
char miao,shi,fen;
uchar code table[]=" 2007-7-30 MON";
uchar code table1[]=" 00:00:00";
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com)
{
rs=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_date(uchar date)
{
rs=1;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()
{
uchar num;
dula=0;
wela=0;
lcden=0;
// fen=59;
// miao=53;
// shi=23;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(num=0;num<15;num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<12;num++)
{
write_date(table1[num]);
delay(5);
}
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void write_sfm(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void keyscan()
{
rd=0;
if(s1==0)
{
delay(5);
if(s1==0)
{ s1num++;
while(!s1);
if(s1num==1)
{
TR0=0;
write_com(0x80+0x40+10);
write_com(0x0f);
}
}
if(s1num==2)
{
write_com(0x80+0x40+7);
}
if(s1num==3)
{
write_com(0x80+0x40+4);
}
if(s1num==4)
{
s1num=0;
write_com(0x0c);
TR0=1;
}
}
if(s1num!=0)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!s2);
if(s1num==1)
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!s3);
if(s1num==1)
{
/ if(miao==0)
{
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}/
miao--;
if(miao==-1)
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen--;
if(fen==-1)
fen=59;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi--;
if(shi==-1)
shi=23;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
}
}
void main()
{
init();
while(1)
{
keyscan();
}
// while(1);
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==18)
{
count=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
}
write_sfm(4,shi);
}
write_sfm(7,fen);
}
write_sfm(10,miao);
}
} 自己在网上找个图看哈就差不多了希望采纳
以上就是关于单片机课程设计万年历方案论证怎么写全部的内容,包括:单片机课程设计万年历方案论证怎么写、C51系列单片机课程设计:电子闹钟和万年历的程序、怎样用单片机做一个多功能万年历,用12864屏,不能用时钟芯片,万年历有闹钟,计算机秒表等功能,等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)