完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
各位高人好:
我是在用 STC89c516RD+, DS1302, 红外发射器TC9012 红外接收头1838T 写一个电子时钟,时钟正常运行,在数码管上也正确显示,只是当进行红外控制时,当扫描的频率很低时,能够较好的按照预期效果执行;但当扫描的频率高时,程序根本接收不到我发送的正确信息,现象只是数码管在很短的时间内乱闪,然后恢复正常,没有起到红外的控制作用。不管是延时扫描还是定时扫描都不行,求大家帮忙啊,我改了好长时间都没有成功,都快崩溃了! 下面是程序 #include #define uc unsigned char #define ui unsigned int ***it led=P1^2; //流水灯控制位 ***it zhh=P1^3; //8*8点阵的行控制位 ***it wei=P1^1; //数码管位选控制 ***it duan=P1^0; //数码管段选控制 ***it dio=P3^2; //ds1302数据位 ***it sclk=P3^3; //ds1302时钟位 ***it rst=P3^4; //ds1302控制位 ***it en=P1^7; //1602控制位 uc dm[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//段码0-9 uc wm[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位码 uc hc[]={0,0,0x40,0,0,0x40,0,0};//缓存显示的时钟数据,时,分,秒 uc hc1[33]={0}; //用于接收解码后红外信号 uc shuju[4]={0}; //接收到红外信号,整理为四个字节 uc hour,minute,second,jishi,done,ready,con,j; /*************************************************** 延时 ***************************************************/ void delay(ui n) { ui x,y; for(x=25;x>0;x--) //扫描频率高时x定为25,低时定为4000 for(y=n;y>0;y--); } /*************************************************** 显示函数 ***************************************************/ void display() { uc i; for(i=0;i<8;i++) { duan=1; P0=0x00; duan=0; P0=0xff;//用于消隐 wei=1; P0=wm[i]; wei=0; P0=0x00;//用于消隐 duan=1; if(i==2||i==5) //在时分秒中间加一杠 P0=hc[i]; else P0=dm[hc[i]]; duan=0; delay(1); // TR1=1; //这是用定时来扫描 // while(!j); // j=0; // TR1=0; } } /*************************************************** 初始化 ***************************************************/ void init() { P0=0xff; //关闭流水灯 led=0; P0=0x00; //关闭点阵 zhh=0; wei=0; //关闭数码管,在显示程序中再打开 duan=0; rst=0; //关闭ds1302 en=0; //关闭1602液晶 } /*************************************************** 1302设置 读写都按照1302的时序要求完成 ***************************************************/ void write(uc dat) { uc i; for(i=0;i<8;i++) { if(dat&0x01) dio=1; else dio=0; sclk=0; sclk=1; dat>>=1; } } void write1302(uc add,uc dat) { rst=0; sclk=0; rst=1; write(add); write(dat); rst=0; sclk=1; } uc read() { uc i,dat; for(i=0;i<8;i++) { if(dio) dat|=0x80; sclk=1; sclk=0; dat>>=1; } return(dat); } uc read1302(uc add) { uc dat; rst=0; sclk=0; rst=1; write(add); dat=read(); rst=0; sclk=1; return(dat); } void init1302() //1302初始化,时分秒的设置 { write1302(0x8e,0x00); write1302(0x80,(0/10*16+0%10)); write1302(0x82,(46/10*16+46%10)); write1302(0x84,(20/10*16+20%10)); write1302(0x8e,0x80); } void change1302() //1302更改,改变时分秒,在红外控制时用 { write1302(0x8e,0x00); write1302(0x80,(second/10*16+second%10)); write1302(0x82,(minute/10*16+minute%10)); write1302(0x84,(hour/10*16+hour%10)); write1302(0x8e,0x80); } /*************************************************** DTB转换 ***************************************************/ void convert() { hour=read1302(0x85); //从1302中读取数据 minute=read1302(0x83); second=read1302(0x81); hour=hour/16*10+hour%16; //将读取的BCD码转换为十进制 minute=minute/16*10+minute%16; second=second/16*10+second%16; hc[0]=hour/10; //将时分秒的各位放入缓存 hc[1]=hour%10; hc[3]=minute/10; hc[4]=minute%10; hc[6]=second/10; hc[7]=second%10; } /*************************************************** 定时器初始化 ***************************************************/ void tinit() { TMOD=0x12; TH0=0x00; TL0=0x00; TH1=(65536-4000)/256; TL1=(65536-4000)%256; EA=1; ET0=1; ET1=1; TR0=1; } /*************************************************** 外部中断0初始化 ***************************************************/ void einit() { EX0=1; IT0=1; } /*************************************************** 红外信号接收 ***************************************************/ void rec() { uc i,j,k=1,dat; for(i=0;i<4;i++) //将接收到的红外信号进行整理 { for(j=0;j<8;j++) { dat>>=1; if(hc1[k]>7) //晶振为11.0592MHz dat|=0x80; k++; } shuju[i]=dat; dat=0; } ready=1; } /*************************************************** 红外信号解码 ***************************************************/ void jiema() //信号的散转 { switch(shuju[2]) { case 0x47: { con=1; //开启红外控制 } break; case 0x15: { hour++; if(hour==24) hour=0; } break; case 0x07: { hour--; if(hour>=24) hour=23; } break; case 0x40: { minute++; if(minute==60) minute=0; } break; case 0x44: { minute--; if(minute>=60) minute=59; } break; case 0x46: { second++; if(second==60) second=0; } break; case 0x45: { second--; if(second>=60) second=59; } break; case 0x43: { con=0; //关闭红外控制 } break; } } /*************************************************** 红外处理 ***************************************************/ void redcon() //红外信号综合处理 { if(done) { rec(); done=0; } if(ready) { jiema(); ready=0; } } /*************************************************** 主函数 ***************************************************/ void main() { init(); //初始化 init1302(); tinit(); einit(); while(1) { while(con==1) { change1302(); //将时分秒重新写入1302 convert(); //将数据读出并转换为十进制 display(); //显示 } while(con==0) { convert(); //将数据读出并转换为十进制 display(); //显示 } } } void timer0() interrupt 1 { jishi++; //记录两个下降沿间的时间 } void timer1() interrupt 3 //用于定时扫描时 { TH1=(65536-4000)/256; TL1=(65536-4000)%256; j=1; } void exter0() interrupt 0 //红外中断控制 { static uc i; uc flag; if(flag) { if(jishi<55&&jishi>30) //辨别头码 i=0; hc1[i]=jishi; //存后32位信号 jishi=0; i++; if(i==33) { i=0; done=1; } } else { jishi=0; flag=1; } redcon(); //接收完后进行红外信号综合处理 } |
|
相关推荐
3个回答
|
|
请高人们帮帮忙啊
|
|
|
|
本帖最后由 sin88 于 2013-5-27 22:28 编辑
#include #define uc unsigned char #define ui unsigned int ***it led=P1^2; //流水灯控制位 ***it zhh=P1^3; //8*8点阵的行控制位 ***it wei=P2^7; //数码管位选控制 ***it duan=P2^6; //数码管段选控制 ***it dio=P2^4; //ds1302数据位 ***it sclk=P2^5; //ds1302时钟位 ***it rst=P2^3; //ds1302控制位 ***it en=P1^7; //1602控制位 uc dm[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//段码0-9 uc wm[]={0XFE,0XFD,0XFB,0XF7,0XEF,0XDF};//位码 uc hc[]={0,0,0,0,0,0};//缓存显示的时钟数据,时,分,秒 uc hc1[33]={0}; //用于接收解码后红外信号 uc shuju[4]={0}; //接收到红外信号,整理为四个字节 uc hour,minute,second,jishi,done,ready,con; /*************************************************** 延时 ***************************************************/ void delay(ui n) { ui x,y; for(x=25;x>0;x--) //扫描频率高时x定为25,低时定为4000 for(y=n;y>0;y--); } /*************************************************** 显示函数 ***************************************************/ void display() { uc i; for(i=0;i<6;i++) { duan=1; P0=0x00; duan=0; P0=0xff;//用于消隐 wei=1; P0=wm; wei=0; P0=0x00;//用于消隐 duan=1; P0=dm[hc]; duan=0; delay(1); } } /*************************************************** 初始化 ***************************************************/ void init() { P0=0xff; //关闭流水灯 led=0; P0=0x00; //关闭点阵 zhh=0; wei=0; //关闭数码管,在显示程序中再打开 duan=0; rst=0; //关闭ds1302 en=0; //关闭1602液晶 } /*************************************************** 1302设置 读写都按照1302的时序要求完成 ***************************************************/ void write(uc dat) { uc i; for(i=0;i<8;i++) { if(dat&0x01) dio=1; else dio=0; sclk=0; sclk=1; dat>>=1; } } void write1302(uc add,uc dat) { rst=0; sclk=0; rst=1; write(add); write(dat); rst=0; sclk=1; } uc read() { uc i,dat; for(i=0;i<8;i++) { if(dio) dat|=0x80; sclk=1; sclk=0; dat>>=1; } return(dat); } uc read1302(uc add) { uc dat; rst=0; sclk=0; rst=1; write(add); dat=read(); rst=0; sclk=1; return(dat); } void init1302() //1302初始化,时分秒的设置 { write1302(0x8e,0x00); write1302(0x80,(0/10*16+0%10)); write1302(0x82,(46/10*16+46%10)); write1302(0x84,(20/10*16+20%10)); write1302(0x8e,0x80); rst=0; sclk=0; } void change1302() //1302更改,改变时分秒,在红外控制时用 { write1302(0x8e,0x00); write1302(0x80,(hc[4]*16+hc[5])); write1302(0x82,(hc[2]*16+hc[3])); write1302(0x84,(hc[0]*16+hc[1])); write1302(0x8e,0x80); } /*************************************************** DTB转换 ***************************************************/ uc BCD(uc bcd){ uc Decimal; Decimal=bcd>>4; return(Decimal=Decimal*10+(bcd&=0x0F)); } void convert() { hc[0]=BCD(hour)/10; //将时分秒的各位放入缓存 hc[1]=BCD(hour)%10; hc[2]=BCD(minute)/10; hc[3]=BCD(minute)%10; hc[4]=BCD(second)/10; hc[5]=BCD(second)%10; } /*************************************************** 定时器初始化 ***************************************************/ void tinit() { TMOD=0x12; TH0=0x00; TL0=0x00; TH1=0; TL1=0; EA=1; ET0=1; ET1=1; TR0=1; TR1=1; } /*************************************************** 外部中断0初始化 ***************************************************/ void einit() { EX0=1; IT0=1; } /*************************************************** 红外信号接收 ***************************************************/ void rec() { uc i,j,k=1,dat; for(i=0;i<4;i++) //将接收到的红外信号进行整理 { for(j=0;j<8;j++) { dat>>=1; if(hc1[k]>7) //晶振为11.0592MHz dat|=0x80; k++; } shuju=dat; dat=0; } ready=1; } /*************************************************** 红外信号解码 ***************************************************/ void jiema() //信号的散转 { switch(shuju[2]) { case 0x47: { con=1; //开启红外控制 } break; case 0x40: { hour++; if(hour==24) hour=0; } break; case 0x44: { hour--; if(hour>=24) hour=23; } break; case 0x15: { minute++; if(minute==60) minute=0; } break; case 0x07: { minute--; if(minute>=60) minute=59; } break; case 0x0d: { second++; if(second==60) second=0; } break; case 0x19: { second--; if(second>=60) second=59; } break; case 0x45: { con=0; //关闭红外控制 } break; } } /*************************************************** 红外处理 ***************************************************/ void redcon() //红外信号综合处理 { if(done) { rec(); done=0; } if(ready) { jiema(); ready=0; } } /*************************************************** 主函数 ***************************************************/ void main() { init(); //初始化 init1302(); tinit(); einit(); while(1) { while(con==1) { TR1=0; while(con){ convert(); //将数据读出并转换为十进制 display(); } change1302(); //将时分秒重新写入1302 TR1=1; //显示 } while(con==0) { convert(); //将数据读出并转换为十进制 display(); //显示 } } } void timer0() interrupt 1 { jishi++; //记录两个下降沿间的时间 } void timer1() interrupt 3 //用于定时扫描时 { TH1=0; TL1=0; hour=read1302(0x85); //从1302中读取数据 minute=read1302(0x83); second=read1302(0x81); } void exter0() interrupt 0 //红外中断控制 { static uc i; uc flag; if(flag) { if(jishi<55&&jishi>30) //辨别头码 i=0; hc1=jishi; //存后32位信号 jishi=0; i++; if(i==33) { i=0; done=1; } } else { jishi=0; flag=1; } redcon(); //接收完后进行红外信号综合处理 } 改好的了 数码管驱动部分请无视,按我是我学习版上改的这块 现在不管你如何扫描频率都没错 遥控解码部分是我手里遥控的键值,请无视 主要原因是1302不能读取的太频繁,不然就出错了 |
|
|
|
真的非常感谢你,通过你修改过的程序,我的红外确实起作用了,其它的都是小问题,不懂了再向你请教。 |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
求助一下关于51系列单片机的Timer0的计时问题,TH0、TL0+1的时间是怎么算的?
195 浏览 0 评论
【RA-Eco-RA4E2-64PIN-V1.0开发板试用】开箱+Keil环境搭建+点灯+点亮OLED
172 浏览 0 评论
【敏矽微ME32G070开发板免费体验】使用coremark测试敏矽微ME32G070 跑分
453 浏览 0 评论
【敏矽微ME32G070开发板免费体验】开箱+点灯+点亮OLED
697 浏览 2 评论
602 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11985 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-21 08:59 , Processed in 0.722806 second(s), Total 74, Slave 57 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号