单片机第三次实验.doc_第1页
单片机第三次实验.doc_第2页
单片机第三次实验.doc_第3页
单片机第三次实验.doc_第4页
单片机第三次实验.doc_第5页
免费预览已结束,剩余8页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验三 数字时钟实验一、实验目的1、掌握单片机定时器的工作原理。2、掌握单片机定时中断程序的设计方法。3、了解lcd1602的基本用法。4、了解时钟芯片ds1302的基本用法。二、实验内容1. 使用8051单片机的定时器,定时为1s。运用定时中断方式,实现每一秒钟输出状态发生一次反转,即led每隔一秒钟亮一次。2. 使用8051单片机的定时器,设计一时钟,用数码管显示,格式为“hh-mm-ss”,用中断方式实现。3. 使用8051单片机的定时器,设计一时钟,用lcd1602显示,显示自己的姓名及时间,用中断方式实现。时间格式为“hh:mm:ss”4.使用ds1302实现数字钟,用lcd1602显示,显示年月日周时分秒等信息。三、实验原理1. 定时器工作原理定时器有关的寄存器有工作方式寄存器tmod和控制寄存器tcon。tmod用于设置定时器/计数器的工作方式03,并确定用于定时还是用于计数。tcon主要功能是为定时器在溢出时设定标志位,并控制定时器的运行或停止等。内部计数器用作定时器时,是对机器周期计数。每个机器周期的长度是12个振荡器周期。因为实验系统的晶振是12mhz,所以机器周期=1212mhz=1us定时时间:t = (216- a)12/fosc (ms)最大定时时间(a=0,fosc =12mhz):t = 216(ms) = 65536 (ms)定时范围为165,536 s(65ms)在本实验的中断处理程序中,因为中断定时常数的设置对中断程序的运行起到关键作用,所以在置数前要先关对应的中断,置数完之后再打开相应的中断。2.lcd1602lcd1602的液晶屏有16x2个显示位,每个显示位对应于一个ram单元(显示缓冲区),其地址为,上排对应于000x0f,下排对应于0x400x4f,向对应ram地址写入显示代码便可显示相应的字符。实际上,地址0x100x27和0x500x67也属于显示缓冲区范围,但写入的显示代码需要运用移屏指令将其移到可显示区域才能正常显示。显示缓冲区地址分布如图所示。为了区分对显示缓冲区的读、写两种操作,系统规定,写操作时的地址最高位必须为1,读操作时为0(实际上是将操作命令与操作地址合成为一条指令)。因此,第一行第一个字符的写指令应是0x00 + 0x80 = 0x80。第二行第一个字符的读指令应是0x40 + 0x00 = 0x40,而写指令应是0x40 + 0x80 = 0xc0,其它以此类推。 lcd1602模块内部已经存储了192个点阵字符图形,具体包括:常用键盘符号;阿拉伯数字;大小写英文字母;日文假名等。每个字符都有一个固定的字符代码,其中代码0x200x7f对应于字符(规则与标准ascii码相同),代码0xa00xff对应于字符(非ascii码)。编程时可直接将字符代码写到显示缓冲区中,也可将字符串变量的内容写到显示缓冲区中(统称为写数据)。3.串行日历时钟芯片ds1302ds1302 是美国dallas公司推出的一种高性能、低功耗、带有ram的实时日历时钟的电路,采用串行方式与单片机通信。ds1302可对年、月、日、星期、时、分、秒进行实时计时,并具有闰年补偿功能;内部有一个大小为31字节的ram区,可用于存放临时性数据;采用三线接口与mcu进行同步通信;具有宽电压的工作特点。四、实验电路图单片机最小系统独立按键ds1302模块74ls138译码器动态数码管lcd1602电路五、实验步骤1. 使用8051单片机的定时器,定时为1s。运用定时中断方式,实现每一秒钟使某io引脚输出状态发生一次反转,通过外接led显示。用开发板的资源,设计程序实现并记录。(1)io引脚: 。(2)使用定时器为 。(3)基本定时时长为 ms,需要中断 次产生1s时长。(4)记录调试通过的程序。(5)拍照记录运时的状态。2. 使用8051单片机的定时器,设计一时钟,用数码管显示,格式为“hh-mm-ss”,用中断方式实现。仔细阅读参考程序,选择合适的io口并修改程序,将数码管显示时间改为当前时间(误差不超过10分钟)。(1)段码口: 。(2)位选端口: 。(3)拍照记录运时的状态。3使用8051单片机的定时器,设计一时钟,用lcd1602显示,显示自己的姓名及时间,用中断方式实现。时间格式为“hh:mm:ss”。(1)接线:将lcd1602插在lcd1602接口上(注意方向:引脚在上方,屏幕在下方)。(2)仔细阅读参考程序并修改,将自己的姓名加到源程序,将液晶屏显示时间改为当前时间(误差不超过10分钟)。(3)新建工程、保存文件、编译下载,观察按键与数码管显示的对应关系。(4)拍照记录运时的状态。4使用ds1302实现数字钟,用lcd1602显示,显示年月日周时分秒等信息。(1)接线:将lcd1602插在lcd1602接口上(注意方向:引脚在上方,屏幕在下方)。将jp595跳线帽断开,j11跳线帽断开。jp1302跳线帽接上。(2)新建工程、保存文件、编译下载,观察。(3)修改程序,将液晶屏显示日期改为实验的日期,时间改为当前时间(误差不超过10分钟)。六、实验参考程序1.(略)自己设计,调试,并记录。2. 数码管显示的数字时钟方案一:(位选信号不用74ls138)#include#define gpio_dig /段码口#define gpio_place /位选#define uchar unsigned char#define uint unsigned intuchar int_time;/定义中断次数计数变量unsigned char code dig_place8 = 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f;/位选控制unsigned char code dig_code17=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71;uchar second=55,minute=59,hour=23;uchar displaydata8;void digdisplay()unsigned char i;unsigned int j;for(i=0;i8;i+)gpio_dig=displaydatai;/发送段码gpio_place=dig_placei;j=100; /扫描间隔时间设定while(j-);gpio_dig=0x00;/消隐void main()uchar shi,ge;tmod=0x01; /设置定时器t0为方式1定时ea=1; / 总中断开 et0=1; / 允许t0中断 th0=(65536-50000)/256;/给t0装初值tl0=(65536-50000)%256;tr0=1;int_time=0;/中断次数、秒、分、时单元清0while(1)shi=hour/10;ge=hour%10;displaydata0=dig_codeshi;displaydata1=dig_codege;displaydata2=0x40;shi=minute/10;ge=minute%10;displaydata3=dig_codeshi;displaydata4=dig_codege;displaydata5=0x40;shi=hour/10;ge=hour%10;shi=second/10;ge=second%10;displaydata6=dig_codeshi;displaydata7=dig_codege;digdisplay();void t0_interserve(void) interrupt 1 using 1 /t0中断服务子程序int_time+;/中断次数加1 if(int_time=20) /若中断次数计满20次 int_time=0; /中断次数变量清0 second+;/秒计数变量加 1 if(second=60)/若计满60s second=0; /秒计数变量清0 minute +;/分计数变量加 1 if(minute=60)/若计满60分 minute=0;/分计数变量清0hour +;/小时计数变量加1if(hour=24) hour=0;/小时计数计满24,将小时计数变量清0th0=(65536-50000)/256;/定时器t0重新赋值tl0=(65536-50000)%256;方案二(用74ls138进行位选)#include#define gpio_dig #define uchar unsigned char#define uint unsigned intuchar int_time;/定义中断次数计数变量sbit lsa= ;sbit lsb= ;sbit lsc= ;unsigned char code dig_code17=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71;uchar second=55,minute=59,hour=23;uchar displaydata8;uchar num=0;void digdisplay()unsigned char i;unsigned int j;for(i=0;i0;i-)for(j=110;j0;j-);*/void main()uchar shi,ge;tmod=0x01; /设置定时器t0为方式1定时ea=1; / 总中断开 et0=1; / 允许t0中断 th0=(65536-50000)/256;/给t0装初值tl0=(65536-50000)%256;tr0=1;int_time=0;/中断次数、秒、分、时单元清0while(1) shi=hour/10;ge=hour%10;displaydata0=dig_codeshi;displaydata1=dig_codege;displaydata2=0x40;shi=minute/10;ge=minute%10;displaydata3=dig_codeshi;displaydata4=dig_codege;displaydata5=0x40;shi=second/10;ge=second%10;displaydata6=dig_codeshi;displaydata7=dig_codege;digdisplay();void t0_interserve(void) interrupt 1 using 1 /t0中断服务子程序th0=(65536-50000)/256;/定时器t0重新赋值tl0=(65536-50000)%256;int_time+;/中断次数加1 if(int_time=20) /若中断次数计满20次 int_time=0; /中断次数变量清0 second+;/秒计数变量加 1 if(second=60)/若计满60s second=0; /秒计数变量清0 minute +;/分计数变量加 1 if(minute=60)/若计满60分 minute=0;/分计数变量清0hour +;/小时计数变量加1if(hour=24) hour=0;/小时计数计满24,将小时计数变量清0 3lcd1602显示的数字时钟(1)主函数#include#include#define uchar unsigned char#define uint unsigned intuchar int_time;/定义中断次数计数变量uchar code date= xxx xxxxxx ;/lcd第1行显示的内容改为自己姓名uchar code time= time 00:00:00 ;/lcd第2行显示的内容uchar second=55,minute=59,hour=23;/初始时间修改为当前时间void clock_init()uchar i,j;for(i=0;i16;i+)write_data(datei);write_command(0x80+0x40);for(j=0;j16;j+)write_data(timej);void write_sfm(uchar add,uchar date)/写时、分、秒uchar shi,ge;shi=date/10;ge=date%10;write_command(0x80+add);write_data(0x30+shi);write_data(0x30+ge);void clock_write( uchar s, uchar m, uchar h)write_sfm(0x47,h);write_sfm(0x4a,m);write_sfm(0x4d,s);void main()lcd_initial();/lcd初始化clock_init();/时钟初始化tmod=0x01; /设置定时器t0为方式1定时ea=1; / 总中断开 et0=1; / 允许t0中断 th0=(65536-50000)/256;/给t0装初值tl0=(65536-50000)%256;tr0=1;int_time=0;/中断次数、秒、分、时单元清0second=55;minute=59;hour=23;while(1)clock_write(second ,minute, hour);void t0_interserve(void) interrupt 1 using 1 /t0中断服务子程序int_time+;/中断次数加1 if(int_time=20) /若中断次数计满20次 int_time=0; /中断次数变量清0 second+;/秒计数变量加 1 if(second=60)/若计满60s second=0; /秒计数变量清0 minute +;/分计数变量加 1 if(minute=60)/若计满60分 minute=0;/分计数变量清0hour +;/小时计数变量加1if(hour=24) hour=0;/小时计数计满24,将小时计数变量清0th0=(65536-50000)/256;/定时器t0重新赋值tl0=(65536-50000)%256;(2)lcd1602.c文件#include #include /包含_nop_( )空函数指令的头文件#define uchar unsigned char#define uint unsigned int#define out p0sbit rs=p26; /位变量sbit rw=p25;/位变量sbit e=p27; /位变量void lcd_initial(void);/lcd初始化函数void check_busy(void); /检查忙标志函数void write_command(uchar com); /写命令函数void write_data(uchar dat);/写数据函数void delay(uint);/延时函数void lcd_initial(void)/液晶显示器初始化函数write_command(0x38);/写入命令0x38:两行显示,57点阵,8位数据_nop_();/空操作,给硬件反应时间write_command(0x0c);/写入命令0x0c:开整体显示,光标关,无黑块_nop_();/空操作,给硬件反应时间write_command(0x06);/写入命令0x06:光标右移_nop_();/空操作,给硬件反应时间write_command(0x01);/写入命令0x01:清屏delay(1);void write_data(uchar dat)/写数据函数check_busy();/检测忙标志bf=1则等待,若bf=0,则可对lcd操作e=0; /按规定写数据时,e应为正脉冲,所以先置e=0rs=1;/按规定rs=1和rw=0时可以写入数据rw=0; out=dat;/将数据dat从p0口输出,即写入lcd e=1; /e产生正跳变_nop_();/空操作,给硬件反应时间e=0;/e由高变低,写数据操作结束delay(1);void write_command(uchar com) /写命令函数check_busy();e=0; /按规定rs和e同时为0时可以写入命令rs=0; rw=0;out=com;/将命令com写入p0口e=1; /按规定写命令时,e应为正脉冲,即正跳变,所以前面先置e=0_nop_( );/空操作1个机器周期,等待硬件反应e=0;/ e由高电平变为低电平,lcd开始执行命令delay(1);/延时,等待硬件响应void check_busy(void) /检查忙标志函数uchar dt;dodt=0xff; / dt为变量单元,初值为0xff e=0;rs=0; /按照表5-4读写操作规定rs=0,e=1时才可读忙标志rw=1;e=1;dt=out;/ out为p0口,p0口的状态送入dt中 while(dt&0x80); / 如果忙标志bf=1,继续循环检测,等待bf=0e=0; / bf=0,lcd不忙,结束检测void delay(uint j)/1ms延时子程序uchar i=250;for(;j0;j-)while(-i);i=249;while(-i);i=250;(3)lcd1602.h文件#include /包含头文件,头文件包含特殊功能寄存器的定义#include#ifndef _lcd1602_h_#define _lcd1602_h_void lcd_initial(void);/lcd初始化函数void check_busy(void); /检查忙标志函数void write_command(unsigned char com); /写命令函数void write_data(unsigned char dat);/写数据函数void delay(unsigned int);/延时函数 #endif4ds1302设计的时钟(1)主函数#include#includelcd1602.h#includeds1302.hvoid lcddisplay();void main()lcd_initial();ds1302init();while(1)ds1302readtime();lcddisplay();void lcddisplay()write_command(0x80+0x44);write_data(0+time2/16);/时write_data(0+(time2&0x0f); write_data(-);write_data(0+time1/16);/分write_data(0+(time1&0x0f);write_data(-);write_data(0+time0/16);/秒write_data(0+(time0&0x0f);write_command(0x82);write_data(2);write_data(0);write_data(0+time6/16);/年write_data(0+(time6&0x0f);write_data(-);write_data(0+time4/16);/月write_data(0+(time4&0x0f);write_data(-);write_data(0+time3/16);/日write_data(0+(time3&0x0f);write_command(0x8d);write_data(0+(time5&0x07);/星期 (2)ds1302.c文件#includeds1302.h/-ds1302写入和读取时分秒的地址命令-/-秒分时日月周年 最低位读写位;-/uchar code read_rtc_addr7 = 0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d; uchar code write_rtc_addr7 = 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c;/-ds1302时钟初始化2016年1月1日星期二12点00分00秒。-/-存储顺序是秒分时日月周年,存储格式是用bcd码-/uchar time7 = 0, 0, 0x12, 0x17, 0x04, 0x02, 0x16;void ds1302write(uchar addr, uchar dat)uchar n;rst = 0;_nop_();sclk = 0;/先将sclk置低电平。_nop_();rst = 1; /然后将rst(ce)置高电平。_nop_();for (n=0; n= 1;sclk = 1;/数据在上升沿时,ds1302读取数据_nop_();sclk = 0;_nop_();for (n=0; n= 1;sclk = 1;/数据在上升沿时,ds1302读取数据_nop_();sclk = 0;_nop_(); rst = 0;/传送数据结束_nop_();uchar ds1302read(uchar addr)uchar n,dat,dat1;rst = 0;_nop_();sclk = 0;/先将sclk置低电平。_nop_();rst = 1;/然后将rst(ce)置高电平。_nop_();for(n=0; n= 1;sclk = 1;/数据在上升沿时,ds1302读取数据_nop_();sclk = 0;/ds1302下降沿时

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论