完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
经常写代码太累太没趣了,DIY遥控时钟玩玩,还别说一动起手来才知道模电没学好。在调试过程中还发现比遥控更牛B的功能,小手一模到屏的数据线还会调时。哈哈能到这就是传说中的触屏功能??可用在这里有点浪费啊,费了大半天原来是没上拉受干拢了。时钟掉电可走两年1602+1302+C52。用着自己造的东东就是爽啊,下次想DIY手机(呵呵技术难达到) 牛人多的是在这里本人只是想写点东东与大家交流下,分享DIY的乐趣,以及激励学习的热情。以下是时钟源程序(程序写的啰嗦别笑)
#include //寄存器宏定义 #define W_SECOND 0x80 #define W_MINUTE 0x82 #define W_HOUR 0x84 #define R_SECOND 0x81 #define R_MINUTE 0x83 #define R_HOUR 0x85 #define W_PROTECT 0x8E #define R_DAY 0x87 #define R_MONTH 0x89 #define R_YEAR 0x8D #define W_YEAR 0x8C #define W_MONTH 0x88 #define W_DAY 0x86 #define uchar unsigned char #define uint unsigned int #define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0替换 #define wei P2 ***it RS=P2^6; ***it RW=P2^5; ***it PSB=P1^2; ***it EN=P2^4; //位寻址寄存器宏定义 ***it ACC_7=ACC^7; ***it SCLK=P2^1; ***it DIO=P2^2; ***it CE=P2^3; ***it IR=P3^2; //红外接口标志 ***it BUZZ=P3^4; //***it SZEN=CH; uchar GUBIAO,jishu,busy; char dat1,flag,flag1,miao,fen,shi,r,yue,flag2,flag3,h; uchar code addr_tab[]={ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,//第一行汉字位置 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,//第二行汉字位置 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,//第三行汉字位置 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,//第四行汉字位置 }; uchar code tab[]={'0','1','2','3','4','5','6','7','8','9'}; unsigned char IRcord[4]; unsigned char irdata[33]; /*------------------------------------------------ 函数声明 ------------------------------------------------*/ void lcd_wcmd(uchar cmd); void lcd_wdat(uchar dat); void dipl(unsigned char a); void W1302(unsigned char addr,dat) ; void Ir_work(void); void Ircordpro(void); void Delay(unsigned int t); void queding(); void lcd_rdat(); void delay(uchar z); void gonnen(); void taojia(); void taojian(); unsigned char R1302(unsigned char addr); void delay_1ms(void); /*------------------------------------------------ 全局变量声明 ------------------------------------------------*/ unsigned char irtime;//红外用全局变量 unsigned char a,b,m,n; bit irpro_ok,irok; /*------------------------------------------------ 定时器0中断处理 ------------------------------------------------*/ void tim0_isr (void) interrupt 1 using 1 { irtime++; //用于计数2个下降沿之间的时间 } /*------------------------------------------------ 外部中断0中断处理 ------------------------------------------------*/ void EX0_ISR (void) interrupt 0 //外部中断0服务函数 { static unsigned char i; //接收红外信号处理 static bit startflag; //是否开始处理标志位 if(startflag) { if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms i=0; irdata=irtime;//存储每个电平的持续时间,用于以后判断是0还是1 irtime=0; i++; if(i==33) { irok=1; i=0; } } else { irtime=0; startflag=1; } } /*------------------------------------------------ 定时器0初始化 ------------------------------------------------*/ void TIM0init(void)//定时器0初始化 { TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值 TH0=0x00; //重载值 TL0=0x00; //初始化值 ET0=1; //开中断 TR0=1; } /*------------------------------------------------ 外部中断0初始化 ------------------------------------------------*/ void EX0init(void) { IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2) EX0 = 1; //使能外部中断 EA = 1; //开总中断 } //************************************************************* //************************************************************* //调时间功能选择 //************************************************************* //************************************************************* void gonnen() //功能键函数 { unsigned char f,g; R1302(R_MINUTE); if(flag2==0) //中断功能函数运行后读DS1302数标志 { fen=dat1; R1302(R_HOUR); shi=dat1; R1302(R_DAY); r=dat1; R1302(R_MONTH); yue=dat1; flag2=1; } W1302(W_PROTECT,0X00); // W1302(W_SECOND,0X80); W1302(W_PROTECT,0X80); flag=1; flag1=1; //中断功能函数运行后调时间函数进入标志 flag3=1; GUBIAO++; //屏幕光标 if(GUBIAO==1) //光标位置选择 { lcd_wcmd(0x80+0x4a); lcd_wcmd(0x0F); } if(GUBIAO==2) { lcd_wcmd(0x80+0x47); lcd_wcmd(0x0F); } if(GUBIAO==3) { lcd_wcmd(0x80+0x44); lcd_wcmd(0x0F); } if(GUBIAO==4) { lcd_wcmd(0x80+0x0b); lcd_wcmd(0x0F); } if(GUBIAO==5) { lcd_wcmd(0x80+0x08); lcd_wcmd(0x0F); } if(GUBIAO==6) //功能键函数退出前处理各标志和对DS1302写入数据 { GUBIAO=0; flag=0; //中断功能函数退出后主函数恢复运行标志 flag1=0; //中断功能函数退出后调时间函数不能进入标志 flag2=0; flag3=0; lcd_wcmd(0x0c); f=fen/10; //十进制转十六进制准备给DS1302送数据 g=fen%10; // fen=f*16+g; // f=shi/10; // g=shi%10; // shi=f*16+g; // f=r/10; // g=r%10; // r=f*16+g; // f=yue/10; // g=yue%10; // yue=f*16+g; // W1302(W_PROTECT,0X00); //把转好的十六进制数送给DS1302 W1302(W_MINUTE,fen); W1302(W_HOUR,shi); W1302(W_DAY,r); W1302(W_MONTH,yue); W1302(W_SECOND,0X55); W1302(W_PROTECT,0X80); } } //************************************************************* //************************************************************* // 调时间加加 //************************************************************* //************************************************************* void taojia() { if(flag1==1) { if(GUBIAO==2) //分 { fen++; if(fen>=60) fen=0; lcd_wcmd(0x80+0x47); dipl(fen); lcd_wcmd(0x80+0x47); } if(GUBIAO==3) //时 { shi++; if(shi>=24) shi=0; lcd_wcmd(0x80+0x44); dipl(shi); lcd_wcmd(0x80+0x44); } if(GUBIAO==4) //日 { r++; if(r>=32) r=1; lcd_wcmd(0x80+0x0b); dipl(r); lcd_wcmd(0x80+0x0b); } if(GUBIAO==5) //月 { yue++; if(yue>=13) yue=1; lcd_wcmd(0x80+0x08); dipl(yue); lcd_wcmd(0x80+0x08); } } } //************************************************************* //************************************************************* // 调时间减减 //************************************************************* //************************************************************* void taojian() { if(flag3==1) { if(GUBIAO==2) //分 { fen--; if(fen<0) fen=59; lcd_wcmd(0x80+0x47); dipl(fen); lcd_wcmd(0x80+0x47); } if(GUBIAO==3) //时 { shi--; if(shi<0) shi=23; lcd_wcmd(0x80+0x44); dipl(shi); lcd_wcmd(0x80+0x44); } if(GUBIAO==4) //日 { r--; if(r<1) r=31; lcd_wcmd(0x80+0x0b); dipl(r); lcd_wcmd(0x80+0x0b); } if(GUBIAO==5) //月 { yue--; if(yue<1) yue=12; lcd_wcmd(0x80+0x08); dipl(yue); lcd_wcmd(0x80+0x08); } } } /*------------------------------------------------ 键值处理 ------------------------------------------------*/ void zuanhuan(void) //a--b { switch(a) { case 0x45:gonnen(); break; case 0x46:taojia(); break; case 0x40:taojian(); break; default:break; } } //************************************************************* //************************************************************* //红外键值散转 //************************************************************* //************************************************************* void Ir_work(void) { a=IRcord[2]; zuanhuan(); irpro_ok=0;//处理完成标志 } /*------------------------------------------------ 红外码值处理 ------------------------------------------------*/ void Ircordpro(void)//红外码值处理函数 { unsigned char i, j, k; unsigned char cord,value; k=1; for(i=0;i<4;i++) //处理4个字节 { for(j=1;j<=8;j++) //处理1个字节8位 { cord=irdata[k]; if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差 value|=0x80; if(j<8) { value>>=1; } k++; } IRcord=value; value=0; } irpro_ok=1;//处理完毕标志位置1 } //************************************************************* //************************************************************* //延时 //************************************************************* //************************************************************* void delay_1ms(void) //延时程序 { uchar K,L; for(K=0;K<10;K++) for(L=0;L<20;L++); } void delay(uchar z) { uchar i,j; for(i=z;i>0;i--) for(j=220;j>0;j--); } //************************************************************* //************************************************************* //检测LCD忙 //************************************************************* //************************************************************* void busy_1602(void) //查询忙碌标志信号程序 { do { EN=0; RW=1; RS=0; EN=1; busy=P0; EN=0; delay_1ms(); } while(busy&&0x10==1); } //************************************************************* //************************************************************* //LCD显汉字 //************************************************************* //************************************************************* void hanzi_Disp(uchar x,uchar y,uchar *pt) { lcd_wcmd(addr_tab[8*x+y]); //写地址 while(*pt>0) { lcd_wdat(*(pt++)); //写数据 } } //************************************************************* //************************************************************* //LCD写指令 //************************************************************* //************************************************************* void lcd_wcmd(uchar cmd) { busy_1602(); EN=0; RW=0; RS=0; EN=1; P0=cmd; EN=0; } //************************************************************* //************************************************************* //LCD写数据 //************************************************************* //************************************************************* void lcd_wdat(uchar dat) { busy_1602(); EN=0; RW=0; RS=1; EN=1; P0=dat; EN=0; } //************************************************************* //************************************************************* //LCD读数据 //************************************************************* //************************************************************* /*void lcd_rdat() { unsigned char lcddat; EN = 0; RS = 0; RW = 1; delay(4); EN = 1; lcddat = P0; delay(4); EN = 0; } */ //************************************************************* //************************************************************* //LCD初始化 //************************************************************* //************************************************************* void lcd_init()//LCD初始化 { lcd_wcmd(0x38); lcd_wcmd(0x0c); lcd_wcmd(0x06); } //***************************************************************** //DS1302写地址,数据发送函数**************************** //****************************************************************** void W1302(unsigned char addr,dat) { unsigned char i,temp; CE=0; SCLK=0; CE=1; //DS1302发地址 for(i=8;i>0;i--) { SCLK=0; temp=addr; DIO=(bit)(temp&0x01); //每次传输低字节 addr>>=1; SCLK=1; } //DS1302发送数据 for(i=8;i>0;i--) { SCLK=0; temp=dat; DIO=(bit)(temp&0x01); dat>>=1; SCLK=1; } CE=0; } //************************************************************* //************************************************************** //DS1302数据读取函数 //************************************************************* //************************************************************* unsigned char R1302(unsigned char addr) { unsigned char i,temp,dat2; CE=0; SCLK=0; CE=1; //DS1302发送地址 for(i=8;i>0;i--) { SCLK=0; temp=addr; DIO=(bit)(temp&0x01); //每次传输低字节 addr>>=1; SCLK=1; } //DS1302读取数据 for(i=8;i>0;i--) { ACC_7=DIO; SCLK=1; ACC>>=1; SCLK=0; } CE=0; dat1=ACC; dat2=dat1/16; dat1=dat1%16; dat1=dat1+dat2*10; return(dat1); } //************************************************************* //************************************************************* //初始化DS1302 //************************************************************* //************************************************************* void Init(void) { P2=0XFF; W1302(W_PROTECT,0X00); // W1302(W_SECOND,0X00); // W1302(W_MINUTE,0X10); // W1302(W_HOUR,0X20); W1302(W_YEAR,0X12); // W1302(W_MONTH,0X04); // W1302(W_DAY,0X21); W1302(W_PROTECT,0X80); } //************************************************************* //************************************************************* //转换显示时间 //************************************************************* //************************************************************* void dipl(unsigned char a) { unsigned char b,c,d; b=a/10; c=a%10; lcd_wdat(tab); lcd_wdat(tab[c]); } //************************************************************* //************************************************************* //主函数 //************************************************************* //************************************************************* void main() //主函数 { EX0init(); //初始化外部中断 TIM0init();//初始化定时器 lcd_init(); Init(); while(1) { while(flag==1) { if(irok) //如果接收好了进行红外处理 { Ircordpro(); irok=0; } if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等 { Ir_work(); } } lcd_wcmd(0x80+0x4a); //秒 R1302(R_SECOND); dipl(dat1); lcd_wcmd(0x80+0x47); //分 R1302(R_MINUTE); dipl(dat1); lcd_wcmd(0x80+0x44); //时 R1302(R_HOUR); dipl(dat1); lcd_wcmd(0x80+0x05); //年 R1302(R_YEAR); dipl(dat1); lcd_wcmd(0x80+0x08); //月 R1302(R_MONTH); dipl(dat1); lcd_wcmd(0x80+0x0b); //日 R1302(R_DAY); dipl(dat1); lcd_wcmd(0x80+0x07); lcd_wdat('-'); lcd_wcmd(0x80+0x0a); lcd_wdat('-'); lcd_wcmd(0x80+0x46); lcd_wdat(':'); lcd_wcmd(0x80+0x49); lcd_wdat(':'); lcd_wcmd(0x80+0x03); lcd_wdat('2'); lcd_wcmd(0x80+0x04); lcd_wdat('0'); if(irok) //如果接收好了进行红外处理 { Ircordpro(); irok=0; } if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等 { Ir_work(); } } }
|
|
相关推荐
26 个讨论
|
|
学习
|
|
|
|
|
|
685 浏览 0 评论
使用Keil建立完整的工程,并使用外部中断0触发数码管显示903
1235 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-使用AHT20进行环境监测之AHT20传感器介绍
1175 浏览 0 评论
896 浏览 0 评论
944 浏览 1 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11848 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-3 00:25 , Processed in 0.759063 second(s), Total 47, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号