嵌入式软件开发基础实验报告 实时时钟
- 格式:doc
- 大小:146.00 KB
- 文档页数:7
实验报告5.按下Key4 Key3执行时,该按键执行加一操作,Led灯按照5秒顺时针一个一个亮。
6.按下Key5 Key3执行时,该按键执行减一操作,Led灯按照5秒顺时针一个一个亮。
7.按下Key6 Key3执行时,该按键执行确定操作,Led灯按照5秒顺时针一个一个亮。
8.按下INT 闹钟关闭。
5、实验总结本次实验是对课本上“电子日历钟设计”的加深。
通过本次试验我对led和led显示有了更加熟悉的认识,能熟练应用它们的功能。
同时我对时钟计数器也有了一定的认识,可以使用定时中断实现实时时钟,更重要的是我的实践能力有很大的提高。
程序设计中遇到的问题(1)、问题:初始完成程序后秒针走的时间很快,不是精确的一秒走一次。
原因:单片机只能用主系统时间,修改fprs后可以真确显示。
(2)、问题:时间切换函数与显示函数和设计的不一样,如只需要显示时,却多显示分。
原因:在仔细看代码后发现每次按键中断都在调用time1()函数,而seeond++在里面,所以每次都会加快秒的运行。
把seeond++移到外面放入time()函数后这个问题就解决了。
(3)、问题:运行时发现按键中断总会加快秒的运行,不是很精确。
原因:最后设置了一个虚拟的key7,当执行完时间指向ease7,然后调用Freshddisplaybuffer函数,这样就很好的解决了这个问题。
在程序调试过程中,设置断点并且在断点处增加一个LED灯,通过判断灯是否亮可以判断程序是否执行到该位置,对程序调试有很大的帮助。
开始WhileKey? 6 1 3 2 4 结束主程序流程图附件程序流程图:Yd_c_inter() Freshddisp laybuffer(); Set_D_T(); noise(); key=7; , 5 NDownNum() ; Freshddispl aybuffer(); Set_D_T(); noise(); key=7; FreshddisplaybufferTime1();Show_Time();Show_Time(); Time1() Freshddis playbuffer ();; Display_D ate(); noise(); 初始化蜂鸣器并关闭蜂鸣器BZOE = 0;初始化 INT 按键 Init_Inter();初始化 Lcd 和 Led; Init_Lcd(),Init_Led();UpNum(); Freshddis playbuffer (); Set_D_T(); noise(); key=7; key = 0; noise(); Time1(); Freshddis playbuffer (); Set_D_T(); noise();初始化按键中断InitKey_INTKR();Time1(); noise();关中断DI ()关中断EI()开中断EI();源代码:#pragma sfr#pragma EI#pragma DI#pragma access#pragma interrupt INTTM000 Time#pragma interrupt INTKR OnKeyPress#pragma interrupt INTP5 OnKeyOver void Init_Led();void InitKey_INTKR();void Init_Lcd();void Init_Inter();void LightOneLed(unsigned char ucNum);void LightOff();int Count_Day(int month);〃定义变量i,是切换时间的标志//定义 key=0 〃用于存放当前月的天数 〃默认的秒second=0 〃默认的分minute=0 〃默认的时hour=12 〃默认的天day=1 〃默认的月month=5 〃默认的年year=2014 〃默认的闹钟时=1 〃默认的闹钟分=1 〃秒的数码显示缓存区 〃分的数码显示缓存区 〃时的数码显示缓存区 〃天的数码显示缓存区 〃月的数码显示缓存区 〃年的数码显示缓存区 〃月,天的数码显示缓存区 〃时,分的数码显示缓存区 〃分,秒的数码显示缓存区 〃闹钟时的数码显示缓存区 〃闹钟分的数码显示缓存区 //INT 中断中间变量LCD_num[10]={0X070d,0x0600,0x030e,0x070a,0x0603,0x050b,0x050f,0x0700,0x070f,0x070b);//数字0〜〜9的显示码unsigned char Scond;// ......................................................... 延时函数1 .............................................. //void Delay(int k){int i,j;for(i=0;i<k;i++){for(j=0;j<k;j++){〃使用特殊功能寄存器 〃开中断 〃关中断 〃使用绝对地址指令 〃定义时间中断函数为Time 〃定义按键中断为OnKeyPress //定义INT 中断为OnKeyOverchar i=0;int key=0;int temp=1;int temp1 = 1;int second=0;int minute=0;int hour=12;int day=1;int month=5;int year=2014;int c_hour=1;int c_minute=1;int buffs[2];int buffm[2];int buffh[2];int buffday[2];int buffmonth[2];int buffyear[4];int buffmd[4];int buffhm[4];int buffms[4];int buffch[2];int buffcm[2];unsigned char Que = 0;int// .................................................. 初始化Led函数................ //void Init_Led(){PM13=0XF0; 〃端口13的第四位为输出模式PM14=0XF0; 〃端口14的第四位为输出模式PM15=0XF0; 〃端口15的第四位为输出模式)// ............................................................. 按键中断函数............... •//void InitKey_INTKR(){PM4 = 0x3F; //P4的六个端口设置为输入模式PU4 = 0x3F; 〃接通上拉电阻KRM = 0x3F; 〃允许六个按键中断KRMK = 0;PM3.0 = 1;PU3.0 = 1;EGP.5 = 1;PMK5 = 0;PPR5 = 0;KRPR = 1;)// ............................... 初始化lcd函数............... //void Init_Lcd(){ PFALL=0x0F; 〃所有接lcd引脚指定为lcd引脚LCDC0=0x34; 〃设置原时钟和时钟频率LCDMD=0x30; //设置lcd电压为3/5电压LCDM=0xC0; //4分时1/3偏压模式)// ............................... 初始化定时器Inter函数.............. 〃void Init_Inter(){ CRC00)=0; //CR000为比较寄存器PRM00=0X04; 〃计数时钟为fprs/2A8 CR000=0X7FFF;//时间间隔为1s TMMK010=1;//TMMK010 中断屏蔽TMMK000=0; //TMMK000 中断允许TMC00=0X0C; //TM00和CR000相等时进入清零&启动模式)void Time(){ second++;)// ............................................................. 按键中断函数............... •//void OnKeyPress(){DI();switch(P4&0x3F) 〃判断哪个按键按下{case 0x3e:key=1; //按键keyl按下break;case 0x3d:key=2; //按键key2按下break;case 0x3b:key=3; //按键key3按下break;case 0x37:key=4; //按键key4按下break;case 0x2f:key=5; //按键key5按下break;case 0x1f:key=7; //按键key6按下break;default:break;)EI();)// ............................................................... I NT按键中断函数............... //void OnKeyOver(){DI();Que = 0; //判断Que是否为0BZOE = 0; 〃蜂鸣器关闭EI();)// ................................................... Led小灯函数............... //void LightOneLed(unsigned char ucNum){switch(ucNum){ 〃检测变量ucNumcase 0:case 1:case 2:case 3:P13 |= (unsigned char) 1 << (ucNum);〃如果为0到3中的一个值则让LED1到LED4中的一个亮break;case 4:case 5:case 6:case 7:P14 |= (unsigned char) 1 << (ucNum - 4);〃如果为4到7中的一个值则让LED5到LED8中的一个亮break;case 8:case 9:case 10:case 11:P15 |= (unsigned char) 1 << (ucNum - 8);〃如果为8至U 11中的一个值则让LED9至U LED12中的一个亮break;default:break;))// ................................................... Led小灯熄灭函数............... 〃void LightOff(){P13 = 0;P14 = 0;P15 = 0;)// ............................................. 时间函数.............. 〃void Time1(){if((second % 5) == 0){ 〃秒大于 5 变为0Scond = second / 5 + 1;LightOff(); 〃调用小灯亮函数LightOneLed(Scond % 12);)if(second>=60){minute++; //秒大于60时分加1second=0;if(minute>=60){minute=0;hour++; //分大于60时时加1if(hour>=24){hour=0;day++; 〃时大于24时天加1temp=Count_Day(month);if(day>=temp){day=1;month++; 〃天大于当前月份的天数时月加1if(month>=13){month=1;year++; //月大于12时年加1))))))// ...................................... 计算当前月的天数.............. •//int Count_Day(int month){int day;if((month==4)||(month==6)||(month==9)||(month==11))//4,6,9,11 月为30 天day=30;else if(month==2){if((year%4==0&&year%100==0)||(year%400==0))day=29; 〃闰年2月29天elseday=28; //平年2月28天)elseday=31; //1,3,5,7,8,10,12 月为31 天return (day);)// ................................ 倒计时函数 ...... //void Show_Time(){ pokew(0xFA40,0x00); pokew(0xFA42,0x00); pokew(0XFA48,buffs[1]); pokew(0XFA4A,buffs[0]); pokew(0XFA44,buffm[1]); pokew(0XFA46,buffm[0]); pokew(0xFA4C,0x00); pokew(0xFA4E,0x00); Delay(100);) // ..................................................................... 日期显示函数 ................. •// void Display_Date(){buffm[0]|=0x0800;pokew(0xFA40,buffyear[3]);〃显示年 pokew(0xFA42,buffyear[2]);pokew(0xFA44,buffyear[1]);pokew(0xFA46,buffyear[0]);pokew(0xFA48,buffmonth[1]);〃显示月 pokew(0xFA4A,buffmonth[0]);pokew(0xFA4C,buffday[1]);〃显示日pokew(0xFA4E,buffday[0]);temp1=0;) // .................................................................... 时间显示函数 .............. •//void Display_Time(){ pokew(0xFA40,0x00);pokew(0xFA42,0x00);pokew(0xFA44,buffh[1]);〃显示时 pokew(0xFA46,buffh[0]);pokew(0xFA48,buffm[1]);〃显示分 pokew(0xFA4A,buffm[0]);pokew(0xFA4C,buffs[1]);〃显示秒 pokew(0xFA4E,buffs[0]);)// ..................................................................... 设定时间函数 .............. •//void Set_D_T(){int lcd_addr;lcd_addr = 0xFA40;switch(i){case 1:pokew(lcd_addr,buffyear[3]);〃时间年 pokew(lcd_addr+2,buffyear[2]);pokew(lcd_addr+4,buffyear[1]);pokew(lcd_addr+6,buffyear[0]);pokew(lcd_addr+8,0x00);pokew(lcd_addr+10,0x00);pokew(lcd_addr+12,0x00);pokew(lcd_addr+14,0x00);break;case 2:pokew(lcd_addr,0x00);pokew(lcd_addr+2,0x00);pokew(lcd_addr+4,0x00);pokew(lcd_addr+6,0x00);pokew(lcd_addr+8,buffmonth[1]);〃时间月 pokew(lcd_addr+10,buffmonth[0]);pokew(lcd_addr+12,0x00);pokew(lcd_addr+14,0x00);break;case 3:pokew(lcd_addr,0x00); //在lcd 右边显示1〃在lcd 右边显示0 〃在lcd 右边显示1 〃在lcd 右边显示0pokew(lcd_addr+2,0x00);pokew(lcd_addr+4,0x00);pokew(lcd_addr+6,0x00);pokew(lcd_addr+8,0x00);pokew(lcd_addr+10,0x00);pokew(lcd_addr+12,buffday[1]); 〃时间日pokew(lcd_addr+14,buffday[0]);break;case 4:pokew(lcd_addr,0x00);pokew(lcd_addr+2,0x00);pokew(lcd_addr+4,buffh[1]); 〃时间时pokew(lcd_addr+6,buffh[0]);pokew(lcd_addr+8,0x00);pokew(lcd_addr+10,0x00);pokew(lcd_addr+12,0x00);pokew(lcd_addr+14,0x00);break;case 5:pokew(0xFA40,0x00);pokew(0xFA42,0x00);pokew(0xFA44,0x00);pokew(0xFA46,0x00);pokew(0xFA48,buffm[1]); 〃时间分pokew(0xFA4A,buffm[0]);pokew(0xFA4C,0x00);pokew(0xFA4E,0x00);break;case 6:pokew(0xFA40,0xd1);pokew(0xFA42,0xd0);pokew(0xFA44,0xd7);pokew(0xFA46,0xd1);pokew(0xFA48,0x50);pokew(0xFA4A,0x56);pokew(0xFA4C,buffch[1]); 〃闹钟时pokew(0xFA4E,buffch[0]);break;case 7:pokew(0xFA40,0xd1);pokew(0xFA42,0xd0);pokew(0xFA44,0xd7);pokew(0xFA46,0xd1);pokew(0xFA48,0x50);pokew(0xFA4A,0x00);pokew(0xFA4C,buffcm[1]); 〃闹钟分pokew(0xFA4E,buffcm[0]);break;default:break;))// ........................................................ 切换时间函数 .............. …// void d_c_inter(){DI(); 〃关中断i++;if(i>7) 〃切换标志>7, i=1,否则i++i=1;EI(); 〃开中断)// ........................................................ 调整时间加函数 .............. •// void UpNum(){ switch(i){ case 1:year++;case 2:month++;if(month > 12){month = 1;)break;case 3:temp = Count_Day(month);day++;if(temp < day)day = 1;break;case 4:hour++;if(hour > 23)hour = 1;break;case 5:minute++;if(minute > 59)minute = 0;break;case 6:c_hour++;if(c_hour > 23)c_hour = 1;break;case 7:c_minute++;if(c_minute > 59)c_minute = 0;break;default:break;))// ........................................................ 调整时间减函数.............. …// void DownNum(){switch(i){case 1:year--;case 2:month--;if(month < 1){month = 12;)break;case 3:temp = Count_Day(month);day--;if(day < 1)day = temp;break;case 4:hour--;if(hour < 1)hour = 23;break;case 5:minute--;if(minute < 0)minute = 59;break;case 6:c_hour--;if(c_hour < 1)c_hour = 23;break;case 7:c_minute--;if(c_minute < 0)c_minute = 59;break;default: break;))// .................................................. 闹铃以及小灯函数.............. •//void noise(){if(c_hour == hour && c_minute == minute && Que == 1){ 〃闹铃的时,分与系统时,分相等,并且闹钟标志开启CKS=0XE0; 〃开启蜂鸣器输出,输出频率为0.98khz的音频Time1(); 〃调用时间函数))// ........................................................ 显示缓存区刷新时间函数.............. •//void Freshddisplaybuffer(){buffs[1]=LCD_num[second/10];/期的显示码放入秒的数码显示缓存区buffs[0]=LCD_num[second%10];buffm[1]=LCD_num[minute/10];//分的显示码放入分的数码显示缓存区buffm[0]=LCD_num[minute%10];buffm[0]|=0x0800; 〃分的后面显示一个"."buffh[1]=LCD_num[hour/10]; 〃时的显示码放入时的数码显示缓存区buffh[0]=LCD_num[hour%10];buffh[0]|=0x0800; 〃时的后面显示一个"."buffday[1]=LCD_num[day/10];//天的显示码放入天的数码显示缓存区buffday[0]=LCD_num[day%10];buffmonth[1]=LCD_num[month/10];//月的显示码放入月的数码显示缓存区buffmonth[0]=LCD_num[month%10];buffmonth[0]|=0x0800; 〃月的后面显示一个"."buffyear[3]=LCD_num[year/100/10];/^的显示码放入年的数码显示缓存区buffyear[2]=LCD_num[(year/100)%10];buffyear[1]=LCD_num[(year%100)/10];buffyear[0]=LCD_num[(year%100)%10];buffyear[0]|=0x0800; 〃年的后面显示一个"."buffmd[3]=LCD_num[month/10];//月,天的显示码放入月,天的数码显示缓存区buffmd[2]=LCD_num[month%10];buffmd[2]|=0x0800; 〃月,天后显示一个"."buffmd[1]=LCD_num[day/10];buffmd[0]=LCD_num[day%10];buffhm[3]=LCD_num[hour/10];//时,分的显示码放入时,分的数码显示缓存区buffhm[2]=LCD_num[hour%10];buffhm[2]|=0x0800; 〃时,分的后显示一个"."buffhm[1]=LCD_num[minute/10];buffhm[0]=LCD_num[minute%10];buffms[3]=LCD_num[minute/10];/^,秒的显示码放入分,秒的数码显示缓存区buffms[2]=LCD_num[minute%10];buffms[2]|=0x0800; 〃分,秒的后显示一个"."buffms[1]=LCD_num[second/10];buffms[0]=LCD_num[second%10];buffch[1]=LCD_num[c_hour/10];//闹钟时的显示码放入闹钟时的数码显示缓存区buffch[0]=LCD_num[c_hour%10];buffcm[1]=LCD_num[c_minute/10];//闹钟分的显示码放入闹钟分的数码显示缓存区buffcm[0]=LCD_num[c_minute%10];)// ................................. 主函数............... 〃void main(){DI(); 〃关中断PM3.4 = 0; //P3.3,P3.4端口设置为输出模式P3.4 = 1; //led灯初始化为点亮状态PM3.3 = 0;P3.3 = 0;BZOE = 0; 〃蜂鸣器初始化为熄灭Init_Lcd(); 〃初始化lcdInit_Led(); 〃初始化ledInitKey_INTKR(); 〃初始化按键EI(); 〃开中断Init_Inter(); //初始化中断while(1){ Time1(); noise(); switch(key){ case 0: Freshddisplaybuffer(); Time1(); Show_Time();Show_Time(); break; case 1:Time1();Freshddisplaybuffer(); Display_Date(); noise();break;case 2:Time1();Freshddisplaybuffer(); Display_Time(); noise();break;case 3:d_c_inter();Freshddisplaybuffer(); Set_D_T();noise();key=7; break;case 4:UpNum();Freshddisplaybuffer(); Set_D_T();noise();key=7; break;case 5:DownNum();Freshddisplaybuffer(); Set_D_T();noise();key=7; break;case 6:key = 0;if(i > 5)Que = 1;1 = 0;noise();case 7:Time1();Freshddisplaybuffer(); Set_D_T(); 〃调用计算时间函数 〃调用闹钟函数 〃没有按键执行 〃调用刷新函数 〃计算时间 〃调用显示时间函数 //按键1执行 〃计算时间 〃调用刷新函数 〃调用显示日期函数 〃调用闹钟函数 //按键2执行 //计算时间 //调用刷新函数 //调用时间显示函数 //调用闹钟函数 //按键3执行 〃调用时间切换函数 //调用刷新函数 〃调用时间设置函数 //调用闹钟函数 //按键4执行 〃调用时间加函数 //调用刷新函数 //调用时间设置函数 //调用闹钟函数 //按键5执行〃调用时间减函数 //调用刷新函数 //调用时间设置函数//调用闹钟函数//按键6执行〃判断是否确认 //调用闹钟函数〃虚拟按键7 //调用刷新函数//调用时间设置函数〃调用闹钟函数noise();break;。
实时时钟实验总结一、实验目的本实验的主要目的是了解实时时钟的原理及其应用,掌握实时时钟的使用方法,以及通过实验学习如何编写驱动程序。
二、实验原理1. 实时时钟是一种能够提供时间和日期信息的芯片,它通常由一个晶体振荡器和一组计数器组成。
2. 实时时钟可以通过I2C总线与处理器进行通信,读取或设置时间和日期信息。
3. 实现实时时钟需要编写相应的驱动程序,并将其与操作系统进行集成。
三、实验设备与材料1. 实验板:STM32F407ZET6开发板;2. 模块:DS1307实时时钟模块;3. 软件:Keil uVision5开发环境。
四、实验内容1. 硬件连接:将DS1307模块与STM32F407ZET6开发板连接,包括SDA、SCL、VCC和GND等引脚。
2. 编写驱动程序:根据DS1307模块手册编写相应的驱动程序,并将其集成到操作系统中。
3. 测试程序:编写测试程序,通过读取DS1307模块返回的时间和日期信息来验证驱动程序是否正常工作。
五、实验步骤1. 连接硬件:将DS1307模块与STM32F407ZET6开发板连接。
2. 编写驱动程序:根据DS1307模块手册编写相应的驱动程序,并将其集成到操作系统中。
3. 编写测试程序:编写测试程序,通过读取DS1307模块返回的时间和日期信息来验证驱动程序是否正常工作。
4. 下载程序:使用Keil uVision5开发环境将编写好的程序下载到STM32F407ZET6开发板上。
5. 运行测试:启动STM32F407ZET6开发板,通过串口助手等工具查看DS1307模块返回的时间和日期信息,验证驱动程序是否正常工作。
六、实验结果经过测试,实时时钟模块能够正确返回当前时间和日期信息,并且能够根据需要进行设置和调整。
七、实验总结本次实验通过对实时时钟原理的学习以及编写驱动程序和测试程序的练习,加深了对嵌入式系统中硬件与软件协同工作的理解。
同时也掌握了一些基本的嵌入式系统开发技能,如硬件连接、驱动编写、调试等。
目录摘要 (4)第1章设计要求 (5)1.1设计要求 (5)1.2设计内容 (5)1.3设计基本环境 (5)第2章设计方案和论证 (6)2.1总设计原理框图 (6)2.2设计方案选择 (7)第3章硬件电路 (8)3.1单片机的选择 (8)3.1.1 单片机内部原理分析 (8)3.1.2单片机的引脚及封装 (9)3.1.3单片机最小系统 (11)3.2 数码管显示工作原理 (11)3.3 8255A模块 (12)3.4时间调节模块 (13)3.4.1 时间设置 (13)3.4.2整点报时 (13)第4章软件调试 (14)4.1时间调节程序流程图 (14)4.2主程序流程图 (18)第5章仿真调试 (22)第6章总结与体会 (23)第7章参考文献 (23)摘要单片计算机即单片微型计算机。
由RAM ,ROM,CPU构成,集定时,计数和多种接口于一体的微控制器。
它体积小,成本低,功能强,广泛应用于智能产业和工业自动化上。
而51系列单片机是各单片机中最为典型和最有代表性的一种。
通过本子课程设计掌握单片机的基本原理,加深对课堂知识的理解,从而达到学习、设计、开发单片机软硬的能力。
本课程设计由AT89C51,BUTTON,六段数码管等构成,结合单片机最小系统晶振电路作为驱动电路,复位电路作为系统复位使用;结合proteus和keil软件进行设计此系统,通过四个按键调整走时时间和定时时间,由定时器定时并在数码管上显示相应的时间,通过中断和按键扫描实现对时间的停止、启动和设置调整。
程序利用C语言进行编写,结合单片机的引脚的以及相关知识完成程序的编写,由延时程序和循环程序产生的一秒定时,达到时分秒的计时,六十秒为一分钟,六十分钟为一小时,满二十四小时为一天。
运行仿真时,可以显示时钟走时时间,通过按键可以修改时间,以及可以进行手动设置闹钟闹铃时间,同时通过蜂鸣器进行闹铃的效果,通过仿真调试效果真实、准确,节省了硬件资源。
实时时钟一、实验目的1.掌握RTC (Real Time Clock) 工作原理。
2.学习掌握其编程实验方法及应用。
二、实验内容阅读芯片手册,掌握RTC工作原理、编程方法及应用。
三、预备知识1.用ARM ADS1.2集成开发环境,编写和调试程序的基本过程。
2.ARM应用程序的框架结构。
3.RTC工作原理四、实验设备及工具硬件:ARM嵌入式开发板、用于ARM7TDMI的JTAG仿真器、PC机Pentumn100以上、串口线软件:PC机操作系统win98、Win2000或WinXP、ARM ADS1.2集成开发环境、仿真器驱动程序、RTC实验原理及说明五、实验原理1.RTC原理实时时钟(RTC---- Real Time Clock)的基本功能是保持跟踪时间和日期等信息,但许多RTC还提供有多种附加功能,如:看门狗定时器、系统复位、非易失存储器(NV RAM)、序列号、方波输出、涓流充电等。
接口方式RTC芯片提供有多种接口方式,其中并行接口可实现存储器的快速访问或有较大的存储容量,适合于那些对价格、尺寸要求不是很荷刻的系统,许多采用并行接口的实时时钟芯片还与晶振和电池封装在一起构成一个完整的时钟模块,从而简化了硬件设计。
并行接口包括复用总线(数据与地址总线复用)和独立的地址、数据总线。
一般用于时间保持的NV RAM都采用与SRAM相同的控制信号,并可以方便地与常用的微处理器容量。
另外,有些Phantom实时时钟还将时钟数据隐含在备用电池支持的RAM内,以便利用64位软件协议来访问时钟数据。
一般情况下,串行接口时钟芯片都具有外形尺寸较小、成本低廉等优势,但这类芯片的通信速率一般较低,因而比较适合便携式产品。
这类芯片通常包括1-Wire 接口、2线、3线、4线或SPI接口,而许多处理器也包括2线或SPI接口,当然,也有些处理器(如8051及其派生产品)则支持复用的地址和数据总线。
备用电池在有些应用中(如VCR),时钟和日期信息在系统掉电时将会丢失,而在大多数应用中要求系统主电池断电时仍保持时钟和日期有效。
嵌入式数字时钟实验总结本次实验是关于嵌入式数字时钟的设计与实现。
我们通过使用单片机和数码管,成功构建了一个功能完善的数字时钟。
在实验过程中,我们学习了嵌入式系统的基本原理和设计技巧,同时也加深了对数字电路和计时器的理解。
首先,我们明确了实验的目标和需求。
作为一款嵌入式数字时钟,它应该具备显示时间、日期的功能,同时还可以提供闹钟功能和计时功能。
基于这些需求,我们进行了系统的设计和功能模块的划分。
其次,我们选用了适合该项目的硬件平台和软件开发工具。
我们选择了一款功能强大且易于使用的单片机作为主控芯片,以满足系统的高效运行和稳定性要求。
同时,我们使用了一种高亮度的数码管,以保证时间和日期的清晰显示。
然后,我们通过系统设计和模块划分来完成软件的开发。
我们根据系统需求,将整个项目划分为多个模块,如时钟模块、日期模块、闹钟模块和计时模块等。
每个模块都有相应的功能和逻辑,通过合理的调用和交互,实现了整个系统的协调运行。
在实验过程中,我们遇到了一些问题并找到了解决办法。
例如,由于数码管的显示限制,我们需要通过七段数码管的编码方式来进行显示。
我们通过查阅资料和试验,成功实现了数码管的显示功能。
另外,由于闹钟和计时功能需要精确的时间控制,我们使用了定时器和中断的方法来实现,确保了系统的准确性和稳定性。
最后,我们对实验结果进行了测试和调试。
通过测试,我们发现嵌入式数字时钟能够正常显示时间和日期,并且闹钟和计时功能也运行良好。
我们还对系统进行了性能和稳定性测试,发现系统响应快速、界面友好,并且稳定运行。
通过本次实验,我们不仅学到了嵌入式系统的设计和开发技能,还获得了对数字电路和计时器的深入理解。
同时,我们也意识到了实际工程项目中的挑战和困难,锻炼了解决问题的能力。
我们相信这次实验经历对我们今后的学习和工作都具有重要意义。
动态的指针式时钟嵌入式实验报告
*若需源码,请关注后,发私信
一、实验题目:
在LCD显示屏上显示一个动态的指针式时钟
二、实验目的:
1.了解开发板的基本结构,熟悉嵌入式开发流程。
2.掌握开发板各部件的基本操作。
3.提升动手能力,在动手中掌握嵌入式开发流程。
三、实验内容:
用Qt代码编写一个动态的指针式时钟,然后能够定闹钟,当闹钟的时间到时,能够让多媒体的音乐响起来。
四、实验器材:
PC机一台,ARM2410开发板。
五、实验过程:
1.在自己的pc机上编写Qt程序,然后交叉编译该程序。
(前提
是在自己的电脑上交叉编译好Qt然后用qmake进行交叉编译
自己的Qt程序)
2.将交叉编译好的目标代码挂载在目标机上进行运行测试。
六、实验总结:
在开学之前,对嵌入式啊的了解几乎为零,刚开始老师让自己定课题,自己觉得什么都不懂。
但随着学习的深入,加之对实验指导书上的操作,慢慢的就了解了arm2410开发板的结
构和工作机制。
通过前边的基础实验,在我开始做自己的实验之前,我先在自己的pc机上编写应用程序,在我准备好自己机子上的运行环境之后,我就开始编写应用程序,测试成功之后,然后交叉编译qt的应用程序,交叉编译Qt时会耗费很长的时间。
等一切工作做完后,然后我在开发板上进行烧写VIVI、内核、根文件系统等工作,然后把自己的程序挂载在目标机上进行运行,最后定闹钟,让多媒体能够响起来。
通过这学期的学期,我对嵌入式的开发了解啦很多,也提升啦我很大的兴趣,从而为我下学期的学习做啦很好的铺垫,也多谢老师的耐心指导,。
实时钟实验报告小结实验目标和要求实时钟实验的目标是设计并实现一个能够显示当前时间的实时钟系统。
要求能够使用外部振荡器作为时钟源,实现时钟的计时和显示功能,同时能够通过按键进行时间的设置和调整。
实验过程和方法实验中,我们使用了数码管、按键、外部振荡器和微控制器等硬件组件。
其中,数码管用于显示时间信息,按键用于设置和调整时间,外部振荡器提供时钟信号,微控制器作为控制中心。
在实验过程中,首先进行了硬件的连接。
将数码管的七段显示引脚与微控制器的IO口连接,按键引脚与IO口连接,外部振荡器的时钟引脚连接到微控制器的定时器输入引脚。
根据实验要求,我们使用了定时器/计数器来控制时间的计时和显示。
其次,进行了软件的编写。
使用C语言编写了控制程序,实现了时钟的计时和显示功能。
通过定时器中断的方式,每秒钟触发一次中断,计时器加一,重新更新数码管显示的时间。
通过按键的中断,可以设置和调整时间的小时和分钟。
最后,进行了调试和测试。
将程序烧录到微控制器中,将外部振荡器连接并提供时钟源,随后按下按键进行时间的设置和调整。
观察数码管显示的时间是否正确,确保实时钟系统能够正常运行。
实验结果评价经过实验测试,实时钟系统能够实现预期的功能,能够准确地计时并显示时间。
通过按键的设置和调整功能,时间也能够根据需要进行修改。
在不接通外部振荡器的情况下,实时钟系统会使用内部振荡器提供的时钟信号,确保时钟系统可以继续运行。
然而,在实验过程中也发现了一些问题。
首先是按键的抖动问题,由于按键的机械结构,按键在按下和释放的瞬间会有抖动现象,导致程序可能多次响应按键中断。
为了解决这个问题,需要在程序中增加合适的延时机制。
其次是外部振荡器的稳定性问题。
如果外部振荡器的频率不稳定,会导致计时显示的时间不准确。
因此,在选择外部振荡器时,需要注意其稳定性和精度。
另外,实时钟系统的显示模式也可以进一步优化。
目前,我们使用了数码管来显示时间,但是显示的信息有限。
实时时钟设计试验报告一、实验目的本实验的目的是设计一个实时时钟系统,具有实时显示时间、日期和闹钟功能。
通过该实验,我们可以了解实时时钟的设计原理、硬件电路连接及软件程序编写方法。
二、实验原理实时时钟系统由时钟芯片、显示模块、按键模块和控制模块组成。
时钟芯片负责计时和日期的记录,显示模块用于显示时间和日期,按键模块用于设置时间和日期,控制模块用于控制各模块之间的协作。
三、实验器材1.STM32开发板2.DS3231时钟模块3.数码管显示模块4.按键模块5.连接线四、实验步骤1.连接硬件电路。
将STM32开发板与DS3231时钟模块、数码管显示模块和按键模块进行连接,确保电路连接正确无误。
2.编写程序。
使用C语言编写程序,通过读取DS3231时钟模块的寄存器获取时间和日期数据,并将其显示在数码管模块上。
同时,设置按键模块的功能,使其可以进行时间和日期的设置。
3.烧录程序。
使用烧录器将编写好的程序烧录到STM32开发板上,并进行调试。
4.运行实验。
接通电源,启动实时时钟系统,观察数码管是否正确显示时间和日期,按下按键模块进行时间和日期的设置,并观察设置是否生效。
五、实验结果经过实验,我们成功设计出了一个实时时钟系统。
系统能够实时地显示当前的时间和日期,并且可以通过按键进行时间和日期的设置。
在设置新的时间和日期后,系统能够正确地更新并显示。
六、实验总结通过本次实验,我们深入地了解了实时时钟系统的设计原理和实现方法。
我们熟悉了DS3231时钟模块的使用方法,并学会了通过C语言编写程序来实现实时时钟系统的功能。
同时,我们也发现了实时时钟系统的一些问题,并加以解决。
我们对实时时钟系统的稳定性和精确性进行了测试,发现系统的计时精度较高,能够达到亚秒级的准确度。
然而,在用户进行时间和日期的设置时,可能由于误操作导致时间和日期出错。
需要在后续的工作中进一步优化系统的操作界面,提高用户设置的便捷性和准确性。
总而言之,实时时钟系统是一种非常有实用价值的设计,可以广泛应用于各种计时需求的场合,如办公室、实验室、车载设备等。
ARM嵌入式系统软件实时时钟的设计ARM嵌入式系统软件实时时钟的设计类别:嵌入式系统1 引言现在的许多设备对实时时钟都有很高的要求,在片集成的实时时钟往往只注意到了其使用的方便,而没有考虑在实际应用中还有很多特殊的要求。
本文讨论如何使用独立的外扩实时时钟,来满足这些要求。
什么是实时系统?就是系统运行时的反馈信息或者指令,必须在要求的时间内发出或者返回,否则视为无效。
例如,数据采集的时候,必须在对应的时间内得到信号,以保证数据采集的有效性。
那么什么是实时时钟?就是采用独立的晶振(或集成),拥有独立供电系统,永不间断的运行,从而给系统提供可靠的系统时间。
集成的实时时钟和独立实时时钟的比较:以博创up-netarm3000开发板为例,它使用的是三星公司生产的s3c44b0xarm7处理器,该处理器内部集成了一个实时时钟,其中的2个中断源int_rtc和int_adc中断源在26个中断源中优先级最低。
rtc的电压要求2.5v或3v,但是不支持3.3v。
也就是说开发板上的实时时钟不能脱离开发板独立地运行,同时中断级别低,电压范围窄,精度不可调,不具备通用性。
而外扩的独立实时时钟电压范围宽,使用i2c总线,中断级别高,同时独立于开发板运行,通用性好。
特别是精度是可以矫正调节的,这对实时性来说精度是很重要的指标。
2 arm处理器 arm(advanced risc machines)是一类微处理器的通称[1]。
1991年arm公司成立于英国剑桥,主要出售芯片设计技术的授权。
arm现在已遍及工业控制,消费类电子产品,通信系统,网络系统,无线系统等各类产品市场,基于arm技术的微处理器应用占据了32位risc微处理器75%以上的市场比例,arm 技术正在逐步渗入到我们生活的各个方面。
3 pcf8563 pcf8563是philips公司生产的低功耗cmos实时时钟/日历芯片, 芯片最大总线速度为400kbits/s,每次读写数据后,其内嵌的字地址寄存器会自动产生增量。
一、实验目的与要求1. 理解嵌入式实时系统的基本概念和特点。
2. 掌握实时操作系统(RTOS)的基本原理和常用实时调度算法。
3. 学习使用实时操作系统进行嵌入式系统开发,并实现简单的实时任务调度。
4. 通过实验加深对实时系统性能分析和优化的理解。
二、实验正文1. 实验内容本次实验采用嵌入式实时操作系统FreeRTOS进行,通过编写代码实现以下功能:(1)创建实时任务,包括高优先级任务、中优先级任务和低优先级任务。
(2)实现任务间的通信,包括信号量、互斥锁和消息队列。
(3)实时任务调度,观察任务调度策略对系统性能的影响。
2. 实验原理实时操作系统(RTOS)是一种专门为实时系统设计的操作系统,它能够在规定的时间内完成任务的调度和执行。
RTOS的主要特点包括:(1)实时性:RTOS能够在规定的时间内完成任务,满足实时系统的需求。
(2)抢占性:RTOS支持抢占式调度,高优先级任务可以打断低优先级任务的执行。
(3)确定性:RTOS的任务调度和执行具有确定性,便于系统分析和优化。
FreeRTOS是一款开源的实时操作系统,具有以下特点:(1)轻量级:FreeRTOS代码量小,易于移植和集成。
(2)跨平台:FreeRTOS支持多种硬件平台,如ARM、AVR、PIC等。
(3)模块化:FreeRTOS提供丰富的模块,便于用户根据需求进行定制。
3. 实验步骤(1)环境搭建:在PC上安装FreeRTOS相关开发工具,如Keil、IAR等。
(2)创建实时任务:编写代码创建三个实时任务,分别具有高、中、低优先级。
(3)任务间的通信:使用信号量、互斥锁和消息队列实现任务间的通信。
(4)实时任务调度:观察任务调度策略对系统性能的影响,分析不同调度算法的特点。
(5)实验结果分析:对比不同任务调度策略下的系统性能,总结实时系统性能优化的方法。
三、实验总结或结论1. 实验总结通过本次实验,我们深入了解了嵌入式实时系统的基本概念和特点,掌握了RTOS 的基本原理和常用实时调度算法。
嵌入式实时操作系统实验报告一、实验目的本实验的目的是让学生了解嵌入式实时操作系统的基本概念和特点,并能够运用实时操作系统编写嵌入式程序。
同时,通过本实验让学生对实时性和可靠性的要求有更深入的理解。
二、实验内容本实验的内容包括以下几个方面: 1. 实时操作系统的概念和基本特点; 2. 实时操作系统的任务调度机制; 3. 实时操作系统的信号量和消息队列; 4. 在实时操作系统上编写一个简单的示例程序。
三、实验原理1. 实时操作系统的概念和基本特点实时操作系统是一种以时间为基础的操作系统,它具有两个主要特点:可预测性和可靠性。
可预测性是指系统可以在规定时间内完成特定的任务,同时提供精确的响应时间。
可靠性是指系统能够保证任务的正确性和可靠性。
2. 实时操作系统的任务调度机制实时操作系统的任务调度有两种方式:一种是基于优先级的抢占式调度,另一种是基于时间片的轮询式调度。
在优先级抢占式调度中,系统会根据任务的优先级来决定任务的执行顺序。
而在时间片轮询式调度中,系统会为每个任务分配一个时间片,当时间片用完后会切换到下一个任务。
3. 实时操作系统的信号量和消息队列信号量是操作系统中一种用于同步和互斥的机制,信号量可以用来保护共享资源,从而避免多个任务同时访问共享资源导致的冲突。
消息队列是一种用于任务之间通信的机制,它可以保证任务之间传递的消息的可靠性和有序性。
4. 编写示例程序在实时操作系统上编写程序时,需要首先定义任务,并对任务的优先级进行设置。
然后在任务中编写对共享资源的读/写操作,同时使用信号量或消息队列来实现任务之间的通信。
四、实验步骤1.学习实时操作系统的概念和基本特点;2.了解实时操作系统的任务调度机制,包括优先级抢占式调度和时间片轮询式调度;3.学习实时操作系统的信号量和消息队列;4.根据实验要求,编写一个简单的示例程序;5.运行程序并进行测试,检查程序的正确性和实时性。
五、实验结果与分析在本实验中,我首先学习了实时操作系统的基本概念和特点,并了解了其任务调度机制和信号量、消息队列等机制。
实验二实时时钟实验1实验目的(1) 了解实时时钟在嵌入式系统中的作用;(2) 掌握实时时钟的使用。
2 实验设备(1) S3C2410嵌入式开发板,JTAG仿真器。
(2) 软件:PC机操作系统Win98、Win2000或Windows XP,ADS1.2集成开发环境,仿真器驱动程序,超级终端通讯程序。
3 实验内容(1) 编程实现实时时钟功能,每秒显示实时时钟;(2) 编程实现实时时钟告警功能。
4 实验步骤(1) 参照模板工程,新建一个工程RTC,添加相应的文件,并修改RTC的工程设置;(2) 创建Main.c并加入到工程RTC中;(3) 编写程序每秒钟读取时钟滴答;关键代码如下:old_index=led_index;Uart_Printf(“\r\n”);While(1){/*每隔1秒更新一次数据*/if(old_index!=led_index){rtc_get_data(&m_data);old_index=led_index;/*实时时钟数据为BCD码格式,以16进制显示*/Uart_Printf(“\r%02x:%02x:%02x”,m_date.hour,m_date.min,m_date.sec);}};(4) 编写程序实现时间告警功能;关键代码如下;a.首先设置告警时间,如下例程设置每分钟的第5秒告警m_date.sec=0x05;rtc_alalm_set(&m_date.0x41);模式0x41表示使能RTC告警,以及使能秒时钟告警b.注册中断例程,打开中断install_isr_handler(HandleRTC,(void *)rtc_int_isr);rINTMSK=(rINTMSK&˜(BIT_GLOBAL|BIT_RTC);c.中断服务例程中清除中断事件rI_ISPC=BIT_RTC;if(alarm_count&1)*(unsigned char*)0x20000000=0x0f;else*(unsigned char*)0x20000000=0xff;alarm_count++;(5) 编译RTC;(6) 运行超级终端,选择正确的串口号,并将串口设置位:波特率(115200)、奇偶校验(None)、数据位数(8)和停止位数(1),无流控,打开串口;(7) 装载程序并运行,如果运行正确,在超级终端中将会显示如图2.1所示内容。
一、引言随着单片机技术的不断发展,其在各个领域的应用越来越广泛。
实时时钟(Real-Time Clock,RTC)作为一种重要的功能模块,被广泛应用于嵌入式系统中,用于实现时间的记录、显示和控制等功能。
本实训报告以单片机为平台,设计并实现了一个实时时钟系统,旨在巩固和深化单片机相关知识,提高动手实践能力。
二、实训目的1. 理解实时时钟的工作原理和基本概念;2. 掌握单片机与实时时钟芯片的接口连接方法;3. 学会使用实时时钟芯片实现时间记录、显示和控制功能;4. 提高单片机编程能力和嵌入式系统设计能力。
三、实训内容1. 实时时钟芯片介绍本实训采用DS1302实时时钟芯片,该芯片具有以下特点:(1)低功耗设计,适用于电池供电的应用场景;(2)支持闰年、星期和夏令时等功能;(3)具有32.768kHz晶振振荡器,提供精确的时间基准;(4)具有64字节RAM,可用于存储数据。
2. 单片机与DS1302的接口连接本实训选用AT89C51单片机作为控制核心,与DS1302的接口连接如下:(1)VCC:连接单片机的5V电源;(2)GND:连接单片机的地;(3)RST:DS1302复位引脚,连接单片机的P1.0引脚;(4)CE:DS1302片选引脚,连接单片机的P1.1引脚;(5)IO:DS1302数据引脚,连接单片机的P1.2引脚;(6)SQW/OUT:DS1302闹钟输出引脚,连接单片机的P1.3引脚。
3. 实时时钟系统设计(1)时间记录通过DS1302芯片的RAM存储功能,实现时间的记录。
具体操作如下:① 初始化DS1302芯片,设置时间基准;② 设置闰年、星期和夏令时等信息;③ 读取当前时间,并存入单片机的内部RAM。
(2)时间显示使用单片机的并行I/O口,将时间数据输出到LED数码管或LCD液晶显示屏,实现时间显示。
具体操作如下:① 设计显示模块的硬件电路;② 编写显示模块的驱动程序,实现时间数据的读取和显示;③ 通过按键操作,实现时间的切换和调整。
实时时钟实验总结一、引言实时时钟(Real Time Clock,RTC)是一种能够提供准确时间和日期信息的设备。
在各种应用中,实时时钟都扮演着重要的角色,例如计算机系统中的时间同步、电子设备中的时间戳记录等。
本文将对实时时钟实验进行总结,包括实验目的、实验原理、实验步骤以及实验结果分析等内容。
二、实验目的本实验旨在通过搭建实时时钟电路,并使用相应的程序进行控制,实现对时间和日期的准确显示。
具体目的如下: 1. 理解实时时钟的基本原理和工作方式; 2. 掌握实时时钟电路的搭建方法; 3. 学会使用程序控制实时时钟的功能。
三、实验原理实时时钟电路由晶振、RTC芯片、电池及其他辅助电路组成。
其工作原理如下: 1. 晶振产生基准时钟信号,供RTC芯片使用; 2. RTC芯片通过与晶振的配合,实时计时,并将时间和日期信息存储在相关寄存器中; 3. 电池供电保证RTC芯片在断电情况下仍能持续工作,避免时间和日期信息的丢失。
四、实验步骤1. 准备实验材料和工具•Arduino开发板•DS1302实时时钟模块•面包板•连接线•电池2. 搭建电路按照以下步骤搭建实时时钟电路: 1. 将DS1302模块插入面包板中,确保引脚与面包板上的连接良好; 2. 将Arduino开发板与DS1302模块通过连接线连接起来,注意连接的引脚要与程序中定义的引脚对应; 3. 连接电池到DS1302模块的电池接口上,确保电池正负极正确连接。
3. 编写程序使用Arduino开发环境,编写相应的程序代码,实现对DS1302模块的控制和时间显示功能。
程序主要包括如下功能: - 初始化DS1302模块; - 读取DS1302模块中的时间和日期信息; - 在串口监视器上显示时间和日期信息; - 实现时间和日期的设置功能。
4. 上传程序并测试将编写好的程序上传到Arduino开发板上,并打开串口监视器,观察时间和日期信息的显示情况。
同时,通过修改程序中的设置功能,验证实时时钟的准确性和可靠性。
上海电力学院嵌入式软件开发基础实验报告题目:【ARM】实时时钟实验专业:电子科学与技术年级:姓名:学号:一、实验目的1、了解实时时钟的硬件控制原理及设计方法。
2、掌握S3C44B0X 处理器的RTC 模块程序设计方法。
二、实验设备1、硬件:Embest EduKit-III 实验平台,Embest ARM 标准/增强型仿真器套件,PC 机。
2、软件:Embest IDE Pro ARM 集成开发环境,Windows 98/2000/NT/XP。
三、实验内容学习和掌握 Embest EduKit-III 实验平台中RTC 模块的使用,进行以下操作:1、编写应用程序,修改时钟日期及时间的设置。
2、使用EMBEST ARM 教学系统的串口,在超级终端显示当前系统时间。
四、实验原理1. 实时时钟(RTC)实时时钟(RTC)器件是一种能提供日历/时钟、数据存储等功能的专用集成电路,常用作各种计算机系统的时钟信号源和参数设置存储电路。
RTC 具有计时准确、耗电低和体积小等特点,特别是在各种嵌入式系统中用于记录事件发生的时间和相关信息,如通信工程、电力自动化、工业控制等自动化程度高的领域的无人值守环境。
随着集成电路技术的不断发展,RTC 器件的新品也不断推出,这些新品不仅具有准确的RTC,还有大容量的存储器、温度传感器和A/D 数据采集通道等,已成为集RTC、数据采集和存储于一体的综合功能器件,特别适用于以微控制器为核心的嵌入式系统。
RTC 器件与微控制器之间的接口大都采用连线简单的串行接口,诸如I2C、SPI、MICROWIRE和CAN 等串行总线接口。
这些串口由2~3 根线连接,分为同步和异步。
2. S3C44B0X 实时时钟(RTC)单元S3C44B0X 实时时钟(RTC)单元是处理器集成的片内外设。
由开发板上的后备电池供电,可以在系统电源关闭的情况下运行。
RTC 发送8 位BCD 码数据到CPU。
传送的数据包括秒、分、小时、星期、日期、月份和年份。
RTC 单元时钟源由外部32.768KHz 晶振提供,可以实现闹钟(报警)功能。
S3C44B0X 实时时钟(RTC)单元特性:BCD 数据:秒、分、小时、星期、日期、月份和年份1、闹钟(报警)功能:产生定时中断或激活系统2、自动计算闰年3、无2000 年问题4、独立的电源输入5、支持毫秒级时间片中断,为RTOS 提供时间基准读/写寄存器访问 RTC 模块的寄存器,首先要设RTCCON 的bit0 为1。
CPU 通过读取RTC 模块中寄存器BCDSEC、BCDMIN、BCDHOUR、BCDDAY、BCDDATE、BCDMON 和 BCDYEAR 的值,得到当前的相应时间值。
然而,由于多个寄存器依次读出,所以有可能产生错误。
比如:用户依次读取年(1989)、月(12)、日(31)、时(23)、分(59)、秒(59)。
当秒数为1 到59 时,没有任何问题,但是,当秒数为0 时,当前时间和日期就变成了1990 年1 月1 日0 时0 分。
这种情况下(秒数为0),用户应该重新读取年份到分钟的值(参考程序设计)。
后备电池:RTC 单元可以使用后备电池通过管脚RTCVDD 供电。
当系统关闭电源以后,CPU 和RTC 的接口电路被阻断,后备电池只需要驱动晶振和BCD 计数器,从而达到最小的功耗。
闹钟功能RTC 在指定的时间产生报警信号,包括CPU 工作在正常模式和休眠(power down)模式下。
在正常工作模式,报警中断信号(ALMINT)被激活。
在休眠模式,报警中断信号和唤醒信号(PMWKUP)同时被激活。
RTC 报警寄存器(RTCALM)决定报警功能的使能/屏蔽和完成报警时间检测。
时间片中断RTC 时间片中断用于中断请求。
寄存器TICNT 有一个中断使能位和中断计数。
该中断计数自动递减,当达到0 时,则产生中断。
中断周期按照下列公式计算:Period = ( n+1 ) / 128 second其中,n 为RTC 时钟中断计数,可取值为(1-127)置零计数功能RTC 的置零计数功能可以实现30、40 和50 秒步长重新计数,供某些专用系统使用。
当使用50秒置零设置时,如果当前时间是11:59:49,则下一秒后时间将变为12:00:00。
注意:所有的RTC 寄存器都是字节型的,必须使用字节访问指令(STRB、LDRB)或字符型指针访问。
五、实验设计1. 硬件电路设计2. 软件程序设计(1)时钟设置时钟设置程序必须实现时钟工作情况以及数据设置有效性检测功能。
具体实现可以参考示例程序设计。
(2)时钟显示时钟参数通过实验系统串口0 输出到超级终端,显示内容包括年月日时分秒。
参数以BCD 码形式传送,用户使用串口通信函数(参见串口通信实验)将参数取出显示。
/********************************************************************************************** name: rtc_read* func: read data from rtc* para: none* ret: none* modify:* comment:*********************************************************************************************/void rtc_read(void){while(1){// read the data from RTC registersif(rBCDYEAR == 0x99)g_nYear = 0x1999;elseg_nYear = 0x2000 + rBCDYEAR;g_nMonth = rBCDMON;g_nDay = rBCDDAY;g_nWeekday = rBCDDATE;g_nHour = rBCDHOUR;g_nMin = rBCDMIN;g_nSec = rBCDSEC;if(g_nSec != 0)break;}}/********************************************************************************************** name: rtc_display* func: display data from rtc* para: none* ret: none* modify:* comment:*********************************************************************************************/void rtc_display(void){rtc_read();uart_printf("\n\rCurrentTimeis%02x-%02x-%02x%s",g_nYear,g_nMonth,g_nDay,f_szdate[g_nWeekday]);uart_printf(" %02x:%02x:%02x\r\n",g_nHour,g_nMin,g_nSec);}六、实验操作步骤1. 准备实验环境使用Embest 仿真器连接目标板,使用Embest EduKit-III 实验板附带的串口线,连接实验板上的UART0 和PC 机的串口。
2. 串口接收设置在PC 机上运行windows 自带的超级终端串口通信程序(波特率115200、1 位停止位、无校验位、无硬件流控制);或者使用其它串口通信程序。
3. 打开实验例程1)拷贝光盘CD1\Software\EduKit44b0 文件夹到EmbestIDE\Examples\Samsung\目录下;2) 使用Embest IDE 通过Embest JTAG 仿真器连接实验板,打开实验例程目录4.5_rtc_test子目录下的rtc_test.pjf 例程,编译链接工程;3) 点击IDE 的Debug 菜单,选择Remote Connect 项或F8 键,远程连接目标板;4) 点击IDE 的Debug 菜单,选择Download 下载调试代码到目标系统的RAM 中;5) 点击Debug 菜单的Go 或F5 键运行程序。
4. 观察实验结果1).在PC 机上观察超级终端程序主窗口,可以看到如下界面:boot success...RTC Test ExampleRTC Check(Y/N)?2).用户可以选择是否对RTC 进行检查,检查正确的话,继续执行程序,检查不正确时也会提示是否重检查:RTC Check(Y/N)? ySet Default Time at 2004-12-31 FRI 23:59:59Set Alarm Time at 2005-01-01 00:00:01... RTC Alarm Interrupt O.K. ...Current Time is 2005-01-01 SAT 00:00:01RTC Working now. To set date(Y/N)?3).用户可以选择是否重新进行时钟设置,当输入不正确时也会提示是否重新设置:RTC Working now. To set date(Y/N)? y Current date is (2005,01,01, SAT). input new date (yy-mm-dd w): 5-2-23 3Current date is: 2005-02-23 WEDRTC Working now. To set time(Y/N)? y Current time is (00:02:57).To set time(hh:mm:ss): 19:32:54).最终超级终端输出信息如下:Current Time is 2005-02-23 WED 19:32:05 19:32:07七、实验参考程序1. 环境及函数声明ARM7 基础实验教程- 196 -/*------------------------------------------------------------------------------------------*//* global variables *//*------------------------------------------------------------------------------------------*/int g_nYear;intg_nMonth,g_nDay,g_nWeekday,g_nHour,g_nMi n,g_nSec;/*------------------------------------------------------------------------------------------*//* function declare *//*------------------------------------------------------------------------------------------*/int test_rtc_alarm(void);void rtc_init(void);void read_rtc(void);void display_rtc(void);void test_rtc_tick(void);void rtc_int(void);void rtc_tick(void);2. 时钟设置控制程序/******************************************************* *************************************** name: rtc_set_date* func: get and check the DATE string from uart channel to set rtc* para: none* ret: cN09 = 0 : invalid string* cN09 = 1 : set date by input string and ok* modify:* comment:******************************************************** *************************************/int rtc_set_date(char *pString){char cYn,cN09=1;char szStr[12]; // xxxx-xx-xx xint i,nTmp;memcpy((void *)szStr, pString, 12);// check the format of the datanTmp = 0;cN09 = 1;for(i = 0;((i <12)&(szStr[i] != '\0')); i++){ if((szStr[i] == '-')|(szStr[i] == ' '))nTmp += 1;}if(nTmp < 3) // at least 2 '-' and 1 ' '{ARM7 基础实验教程- 197 -cN09 = 0;uart_printf(" InValid format!!\n\r");}else // check if number 0 - 9{nTmp = i - 1; // adjust the account number// 1:MON 2:TUE 3:WED 4:THU 5:FRI 6:SAT 7:SUNif((szStr[nTmp] < '1' | szStr[nTmp] > '7')) // check weekdaycN09 = 0;for( i = nTmp; i >= 0; i--){if(!((szStr[i] == '-')|(szStr[i] == ' ')))if((szStr[i] < '0' | szStr[i] > '9'))cN09 = 0;}}// write the data into rtc registerif(cN09){rRTCCON = 0x01; // R/W enable, 1/32768, Normal(merge), No reseti = nTmp;nTmp = szStr[i]&0x0f;if(nTmp == 7)rBCDDATE = 1; // s3c44b0x: SUN:1 MON:2 TUE:3 WED:4 THU:5 FRI:6 SAT:7elserBCDDATE = nTmp+1; // -> weekday;nTmp = szStr[i-=2]&0x0f;if(szStr[--i] != '-')nTmp |= (szStr[i--]<<4)&0xff;if(nTmp > 0x31)cN09 = 0;rBCDDAY = nTmp; // -> day;nTmp = szStr[--i]&0x0f;if(szStr[--i] != '-')nTmp |= (szStr[i--]<<4)&0xff;if(nTmp > 0x12)cN09 = 0;rBCDMON = nTmp; // -> month;nTmp = szStr[--i]&0x0f;if(i)nTmp |= (szStr[--i]<<4)&0xff;if(nTmp > 0x99)cN09 = 0;rBCDYEAR = nTmp; // -> year;rRTCCON = 0x00; // R/W disableuart_printf(" Current date is:20%02x-%02x-%02x %s\n",rBCDYEAR,rBCDMON,rBCDDAY,f_szdate[rBC DDATE]);if(!cN09)uart_printf(" Wrong value!\n");}else uart_printf(" Wrong value!\n");return (int)cN09;}/******************************************************* *************************************** name: rtc_set_time* func: get and check the TIME string from uart channel to set rtc* para: none* ret: cN09 = 0 : invalid string* cN09 = 1 : set time by input string and ok* modify:* comment:******************************************************** *************************************/int rtc_set_time(char *pString){char cYn,cN09=1;char szStr[8]; // xx:xx:xxint i,nTmp;memcpy((void *)szStr, pString, 8);// check the format of the datanTmp = 0;cN09 = 1;for(i = 0;((i < 8)&(szStr[i] != '\0')); i++){if(szStr[i] == ':')nTmp += 1;}if(nTmp != 2) // at least 3 ':'{ cN09 = 0;uart_printf(" InValid format!!\n\r");}else{nTmp = i - 1;for( i = nTmp; i >= 0; i--){if(szStr[i] != ':')if((szStr[i] < '0' | szStr[i] > '9'))cN09 = 0;}}// write the data into rtc registerif(cN09){rRTCCON = 0x01; // R/W enable, 1/32768, Normal(merge), No reseti = nTmp;nTmp = szStr[i]&0x0f;if(szStr[--i] != ':')nTmp |= (szStr[i--]<<4)&0xff;if(nTmp > 0x59)cN09 = 0;rBCDSEC = nTmp; // -> second;nTmp = szStr[--i]&0x0f;if(szStr[--i] != ':')nTmp |= (szStr[i--]<<4)&0xff;if(nTmp > 0x59)cN09 = 0;rBCDMIN = nTmp; // -> min;nTmp = szStr[--i]&0x0f;if(i)nTmp |= (szStr[--i]<<4)&0xff;if(nTmp > 0x24)cN09 = 0;rBCDHOUR = nTmp; // -> hour; rRTCCON = 0x00; // R/W disableif(!cN09)uart_printf(" Wrong value!\n");ARM7 基础实验教程- 200 -}else uart_printf(" Wrong value!\n");return (int)cN09;}八、实验体会第一、对ARM的相关理论知识有了初步的了解。