51单片机控制DS1302,时间显示在数码管上。
1 3 02 .c #turn on案例5 :p2 = bit_ser [5 ]; iflag == 1 )p0 =标志| == 1 0){j = 0; ifflag == 0)ds1 3 02 _getTime(&time); //如果setFlag为0,则读取1 3 02 的时间。
由于setFlag不是0,这意味着它处于调整状态,不需要读取。
con/1 0; dis_buffer [3 ] = time.minute%1 0; dis_buffer [2 ] = time.minute/1 0; dis_buffer [1 ] = time;}} void main(){onirent_ds1 3 02 (time); timer0_init(); while(1 ){set_down(); timer_down(); up_down(); download_down(); beepflag_down(); ifflag == 0 && time .hour == rommhour && time.minute == romminute && beepflag == 1 )//判断Zummer是否应呼叫beep =! 嘟; unsigned intuchar i = 0,j = 0,x = 0,setflag,flag_set,flag_timer; 系统时间= {0.2 0,1 5 ,3 ,3 0,6 ,1 0}; 4 ; = p3 ^5 ; //签名是否包含警报//函数函数void delay(uchar x){while(x)x-;} //安装密钥处理void set(){setflag ++; flag_set = 1 ; if(setFlag> = 4 ){setFlag = 0; flag_set = 0; prinity_ds1 3 02 (time);} //处理void Timer(){setFlag ++的功能; flag_timer = 1 ; ifflag == 1 ){time.hour = romhour; time.minute = romminute; 。
flag_timer = 0; romhour = time.hour; romminute = time.minute; romsec = time.second;} //添加add -ups void up(){setFlag){case 0:break; break; 案例1 :时间。
第二++; if(time.second> = 6 0)time.second = 0; 休息; 案例2 :Time.minute ++; if(time.minute> = 6 0)时间。
分钟= 0; 休息; 案例3 :time.hour ++; if(time.hour> = 2 4 )time.hour = 0; break;}} //键处理函数void down(){switch(setflag){case 0:break; 案例1 :时间5 9 ; 休息; 案例3 :时间<0)时间。
时间= 2 3 ; break;}} //安装键void set_dow {set();} while(!key_seet);}}} //键扫描函数是void Timer_dow 0){timer()while(!key_timer );}}}}}} //扫描void的功能 添加键_Down(){if(key_up == 0 && setflag!= 0){dehlays(1 00); if(key_up == 0){up(); while(!down_down(){if(key_down == 0 && setflag!= 0){dehlays(1 00); if_down == 0){down(); (beep_flag == 0){1 00); _real_timer_ds1 3 02 #打开
unsigned char)//设置时间{DS1 3 02 _SETPRO TECT(0); write1 3 02 (地址,((value/1 0)<< 4 |(value%1 0))); } //获取时间函数,读取DS1 3 02 的时间,然后在时间上保存它void ds1 3 02 _getTime(SystemTime*time){无签名的Charist ReadValue; readValue = read1 3 02 (ds1 3 02 _second); 时间 - > second =((readValue&0x7 0)>> 4 )*1 0+(readValue&0x0f); //转换为十进制秒readvalue = read1 3 02 (ds1 3 02 _minut 4 )*1 0+(readValue&0x0f); readValue = read1 3 02 (ds1 3 02 _hour); 时间 - > hour =((readValue&0x7 0)>> 4 )*1 0+(readValue&0x0f); readValue = read1 3 02 (ds1 3 02 _day); Time-> day =((readValue&0x7 0)>> 4 )*1 0+(readValue&0x0f); readValue = read1 3 02 (ds1 3 02 _week); Time-> Week =((ReadValue&0x7 0)>> 4 )* 1 0+ alaue = read1 3 02 (ds1 3 02 _year); Time-> Year =(((readValue&0x7 0)>> 4 )*1 0+(readValue&0x0f);} //使用Stime初始化DS1 3 02 VOID initial_ds1 3 02 (SystemTime stime) read1 3 02 (ds1 3 02 _seceec); if(第二和0x8 0)DS1 3 02 _SETTIME(DS1 3 02 _SECOND,0); s1 3 02 _second,stime.second); 一天,stime.day); DS1 3 02 _SETTIME(DS1 3 02 _MONTH,stime.month); DS1 3 02 _SETTIME(DS1 3 02 _YEAR,Stime.Year); DS1 3 02 _SETTIME(DS1 3 02 _WEEK,Stime.week);}#endif
单片机驱动数码管动态显示延迟时间
不能! 数字化偏差的延迟,如果时间太长,它会闪烁,如果太短,它将导致鬼魂! 慢慢地安装它,什么是数码管动态显示
本实验中使用的实验板源电路图如下:其中端口P0是段代码,在低级别上有效。端口P2 是一个位代码,高级别是有效的。
端口P2 .0控制第一个数字管,直至p2 .7 控制第八。
表段代码表如下:每个数字管的段代码是从端口P0输出的,也就是说,每个数字管的输入段代码是相同的。
动态显示可以使用。
借助视觉适应性,只要我们的延迟缩短,数字显示器就会看起来非常稳定且清晰。
此过程如下所示。
上述方法和想法写得如下:org0000h start:mova,#08 H; 0; movp0段代码,movp2 ,#01 H; 位lcalldelay_1 ms mova,#0abh; 1 2 H; 2 movp0,一个movp2 ,#04 H lcalldelay_1 ms mova,#2 2 H; 3 movp0,a movp2 ,#08 h lcalldelay_1 ms mova,#0a1 h; 4 movp0,一个movp2 ,#1 0H lcalldelay_1 ms mova,#2 4 H; 5 movp0,一个movp2 ,#2 0H lcalldelay_1 ms mova,#04 H; 6 movp0,一个movp2 ,#4 0H lcalldelay_1 ms; Mova,#0aah; 7 MOVP0,A MOVP0,#0AAH; 经文也是实施的,这种习惯在Movp2 的未来可能很有用,#8 0H lcalldelay_1 ms ljmpstart deleved_1 m数字从低视图0到7 (包括点)。
★上述方法将值一个或P2 一个一个一个。
如果要更改显示的数字,则很难更改程序。
因此,我们需要在5 1 个微控制器中使用常用方法:表搜索方法。
例如,在删除P0端口上的片段代码时,我们可以将段代码放置在表中显示,然后每次从该表中获取数字,然后将其发送到P0端口。
在P2 端口上删除位代码时,您可以将位代码放在另一个表中,并每次从该表中获取数字并将其发送到P2 端口。
这样,如果要更改显示的数字,则只需要更改表中的数字即可。
org0000h启动:movr7 ,#0ffh; R7 ,R6 查看表时,它将发送到列表索引A(添加1 后为0,因此是FFH预设)MOVR6 ,#0FFH循环:lcallplay1 ; CallPlay1 ; CallPlay子例程显示段lcallplay2 ; 呼叫play bitcode subroutine lcalldelay_1 ms cjnea,#8 0H,loop; 它是否达到左左数,即-8 ajmpstart play1 :;的位代码。
搜索时间表并搜索细分代码子布鲁丹; Mova,R7 ; 印加; movr7 ,encr7 ; R7 ; 这里是movdptr的注册列表,#table1 ; +dptr; 基本注册加MOVP0地址寄存器索引,ret Play2 :; BitCode子例程搜索台(原理与Play1 相同)MOVA,R6 INCA MOVR6 ,MOVDPTR,#Table2 Movca,@a+Dptr movp2 ,a ret table1 :db08 h,0abh,1 2 h,1 2 h,2 2 h,2 2 h,0a1 h,0a1 ; Table2 Table2 段代码:DB01 H,02 H,04 H,08 H,1 0H,2 0H,4 0H,8 0H; 位代码表deled_1 m $ djnzr5 ,temp ret下载到板上以确认并获得预期结果。
----------------------------------------------------------------------------- ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- ------包括
,//如果在P2 .0端口的数字管连接到UnignedCharcodedis_code [1 1 ] = {0x08 ,0xab,0x1 2 ,0x2 2 ,0xa1 ,// 0x1 2 ,2 ,3 ,4 0x2 4 ,0x04 ,0x2 2 ,0x04 ,0x2 2 ,0x04 ,0x2 2 ,0x04 ,0x2 2 4 0x2 4 ,0x04 ,0x2 2 4 0x2 4 ,0x04 ,0x2 2 4 0x2 4 ,0x04 , 0xaa,0x00,0x2 0,0xff}; (){p0 = 0xff; //关闭所有数字。
TubeP2 = 0x00; ] dis_code [4 ]; 0; //当前偏移量为0暂时(1 ){p0 = dis_buf [dis_ind ex]; //段代码发送p0端口p2 = dis_digit; //选择位(即位代码)延迟(1 ); // 延迟dis_digit = _crol_(dis_digit,1 ); //位门向左,向下和下一个strob dis_index ++移动; //下一个段代码dis_index&= 0x07 ; //请参阅注释} {所有管子一次,返回第一个开始下一次扫描。
写回常规形式:dis_index = dis_index&0x07 此方法相对较新。
例如,在第一个循环之后,dis_index值为0000001 ,并且0x07 值保持不变,并且仍然为0x01 直到值增加。
可以用(dis_index == 8 )dis_index = 0代替此句子,效果是相同的。
★使用上述方法实现C5 1 时,将段代码放置在数组dis_code [1 1 ]中,然后将要在程序中调用的值通过dis_buf预算阵列加载,以便可以订阅以便订阅用过的。
这看起来有些复杂,但是这些想法很清楚,结构很清楚,而且多才多艺且易于生长。
★此外,仅扩大程序中的延迟,例如延迟(1 000),然后将其下载到板上,您可以看到数字管实际上逐渐从低至高显示。
----------------------------------------------------------------------------- ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- ------值从0到7 的值在下标上标记,而没有设置dis_buf缓冲区数组[],实现就像 以下:#include
0x2 2 ,0xa1 ,// 0,1 ,2 ,3 ,4 0x2 4 ,0x04 ,0xaa,0x00,0x2 0,0xff}; // 5 ,6 ,7 ,8 ,9 ,来自unsnedchardatadis_index index; //,识别数字管偏移和缓冲voida(){p0 = 0xff; //关闭所有管子代码编号P2 = 0x00; 端口P2 (1 )延迟代码(1 ); 程序(晶体振荡器1 2 m){unsignedChari; dis_index <8 ; dis_index ++){p0 = dis_code [dis_index]; //段代码发送p0端口p2 = dis_index+1 ; //位代码发送P2 端口开发(1 ); 0达到第二名的三位数显示了三个8 ,第三位数字显示了7 个,没有显示四个较高的数字。
一点点观察的漫长延误没有发现任何错误,我对KEM的调试并不熟悉。
[2 006 .5 .2 ]找出原因,添加它:我今天回头找出上面的错误。
当时,我想将dis_index值用作位代码,即,当第一个位显示0时,段代码为dis_code [0],即dis_index值为0,而值位代码目前是1 当第二位显示1 时,段代码为dis_code [1 ],dis_index值为1 ,目前的位代码值为2 因此,我仅使用1 个操作将端口P0偏移值与端口P2 位代码相关联。
但是,如果您仔细考虑BIT代码的原理,则上述方法显然是错误的。
dis_index值为2 ,添加1 后,它是3 遵循上述方法时,将此3 用作位代码,并且正确的位代码应为4 (000001 00B)。
所以出了点问题。
实际上,该字母的这封信存在,但它不仅添加了1 个。
++){p0 = dis_code [dis_index]; //段代码发送p0端口p2 =(char)pow(2 ,dis_index); //位代码发送端口(2 5 5 ); 再次下载到董事会,发现仍然存在一个问题,也就是说,当延迟很小时,显示器是混乱的,但是如果延迟时间增加(例如程序的值),您可以看到数字管正确显示。
此外,该方法产生的代码数量也很大(从写作速度来看)。
这里只有一个想法,它仅适用于此实验,这并不重要,因此仅此而已。
[附加支持] ------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------- ----------------------------------------------------------------------------------- ----------------------------------------------------------------------------- - - - - - - - - - - - - - - - - - - - - - - - - - 参考对我的董事会进行修改,该程序如下:#include
] = {0x08 ,0xab,0x1 2 ,0x2 2 ,0xa1 ,// 0.1 ,2 ,3 ,4 0x2 4 ,0x04 ,0xaa,0x00,0x2 0,0xff}; // 5 ,6 ,7 ,8 ,9 ,在unsignedchardatadis_buf [8 ]; // DIS_BUF显示在基本的unsignedchardatadis_index基本索引上; //显示,用于识别数字管偏移量和VoidMain缓冲区当前显示(){p0 = 0xff; //关闭所有数字管P2 = 0x00; FC1 7 H = 6 4 5 3 5 d,2 1 6 -6 4 5 3 5 = 1 001 US = 1 MS IE = 0x8 2 ; // 1 000001 0bt0溢出dis_buf [0] = dis_code [0x0]; dis_buf [5 ] = dis_code [0 x5 ]; = 1 ; //启动T0临时(1 ); //循环等待中断} voidimer0()interu pt1 //计时器0中断服务程序,用于数字管动态扫描{th0 = 0xfc; //中断时间发生/计数器重新安装TL0 = 0x1 7 ; //我认为(及以上)必须为1 7 中的0x1 8 ,分析以下P2 = 0x00; //修复所有数字管p0 = dis_buf [dis_index]; //段代码发送p0端口p2 = dis_digit; // /位代码发送端口p2 dis_digit = _crol_(dis_digit,1 ); //位门的值向左移动,将来分散注意力随后被中断,下一个数字管连接到下一个DIS_INDEX数字管; = 0x07 ; //所有8 个数字试管都已在一次通行后扫描,返回第一个启动下一次扫描}★时间/计数器输入周期与机器周期相同,即1 /1 2 时钟摇摆频率。
当晶体振荡器为1 2 m时,输入循环间隔为1 U。
机器周期为1 U。
假设T0的初始值是x,是计算初始值的方法:在此示例中,计时器使用方法1 ,即1 6 位计时器,即,最大值为2 1 6 = 6 5 5 3 6 此值,此值,溢出将发生,导致中断并输入程序处理中断。
在这里,如果您想用1 ms慢慢速度,即1 000US,则有一个2 1 6 -X = 1 000公式,您可以获得x = 6 4 5 3 6 ,它将转换为hexadecimal to fc1 8 ,即Th0的初始值= 0xfc,tl0 = 0x1 8 也就是说,计时器开始计算6 4 5 3 6 ,其价值为6 5 5 3 6 ,经过1 ,000起指控。
在上面的示例中,加载的初始值不是FC1 8 (6 4 5 3 6 ),而是FC1 7 (6 4 5 3 5 )。
我认为这可能就是为什么计算范围为0〜6 5 5 6 5 的原因,我也想到这个问题,我只是写了一些书,但是第一个使用了更多,我认为容器更合理,因为在计算机中,二进制1 6 位不能表示6 5 5 3 6 当所有位均为1 时,表示的值为6 5 5 3 5 ,即6 5 5 3 5 h = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 b,也可以说6 5 5 3 6 是通过 溢出。
当响应干扰时是关键。
也没有触发中断。
它仅在下一个计数之后发生。
确切的值应为1 001 U。
如果初始值为6 4 5 3 6 (FC1 8 ),则是必需的值,因此上面示例中的初始值是FC1 8 而不是FC1 7 这只是我自己的看法。
----------------------------------------------------------------------------- ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- ------- ############################# ###################################################### #如下(特定条件的屏幕截图):★电路段代码对应于车载连接方法,即先前的段代码顺序连接。
此外,八位数字管的左端是第一个和正确的位置,是第八位,这与董事会的顺序相反,因此为了统一,该数字是根据董事会连接的。
上面的图还可以模拟结果而不添加拉力电阻,但是端口P0的高水平显示为灰色,即高电阻。
实现实时时钟在数码管上显示时间
该实验在与实时手表模块DS1 3 02 的应用有关的数字管上执行实时时钟显示时间,这是下一个接口的实时时钟芯片。CHIP通过简单的串行接口与微处理器进行通信,并在几秒钟,几分钟,小时,每天,日期,每月和一年中提供信息。
该芯片旨在以低功耗以低功率运行,数据和时钟信息保留在1 μs之内。
DS1 3 02 芯片使用同步通信,只需要三行即可连接:CE(选择),I/O(数据线)和SCLK(串行手表线)。
数据可以一次传输1 个字节,也可以在爆炸中传输3 1 个字节。
该芯片具有用于主电源和备份的双电动引脚,小型充电器罐程序和7 个字节添加了临时内存。
蓝色芯片单元上的MO -DS1 3 02 的图表显示了其与电路的连接关系。
日历寄存器是学习的关键,需要精通每个位的含义。
在Blue Bridge Cup Chip单元竞赛中,该官员将提供数据包,包括日历登记册,您可以通过参考注册指南获得详细信息。
在电路中,X1 和X2 电线连接到标准的3 2 ,7 6 8 kHz石英晶体,内部振荡器与晶体一起运行。
DS1 3 02 摩西在竞争表上的工作电路图显示了主要组件的布局。
了解DS1 3 02 芯片的内部框图对于实际活动非常重要。
在学习过程中,您需要掌握主要技能,例如阅读时间,编写初始价值并转换公式。
BCD代码转换为十进制是另一个重要点。
BCD代码和十进制数字之间的熟练转换公式对于MO -DS1 3 02 的准确操作非常重要。
当DS1 3 02 芯片与蓝桥杯唯一的芯片单元竞争时,它将正式提供相应的驱动程序,包括DS1 3 02 .C和DS1 3 02 .H文件。
DS1 3 02 .C文件包含控制代码。
主要注意阅读真实时钟,写作,转换和其他活动。
在显示实时时钟时间的代码中,有必要遵循模块设计的原理并将函数分为多个模块,例如创建,阅读时间,显示时间,等。
各种模型-DS1 3 02 .C,DS1 3 02 .H和Text.c提供了部署详细信息。
最终运行结果显示了显示时间并验证代码有效性的功能。
简而言之,在实时DS1 3 02 时钟模块的数字管上显示显示时间的实现包括许多链接,例如芯片原理,注册活动,BCD代码和小数转换。
了解并掌握基本知识和细节此活动是实现此功能的关键。
通过实验和代码实施,我们可以更好地了解DS1 3 02 和它的应用程序,以后为更复杂的项目奠定了坚实的基础。