2012 — 2013 学年
实训报告
名 称: 单片机应用综合实训 地 点: 实A407 时 间: 6.3~~~6.7 系 部: 电子系 班 级: 1101电信 姓名学号: 指导老师: 王平
实 习 实 训 评 语 成 绩 评 语 指导老师: 年 月 日
DS1302串口更新时间实时时钟设计
一、 实训任务与计划
任务主要内容:
采用AT89S51单片机的I/O口,选用串行实时时钟DS1302和LED数码显示管,采用C语言编程,设计串口自动更新实时时钟,显示年月日时分钞及学号。 工作学习过程要求:
显示两个屏时分秒,学号。PC的时间通过串口传送到时钟
二、 方案与电路设计
电
利用单片机开发板!ds1302以及两个锁存器和五个个按键,来设计时钟路。并自动更新时间显示。电路如图
电路原理图
仿真电路图
三、 程序设计
#include #define KeyPort P3 #define DataPort P0 sbit LATCH1=P2^2;//定义锁存使能端口 段锁存 sbit LATCH2=P2^3;// 位锁存 bit ReadTimeFlag;//定义读时间标志 bit SetFlag; //更新时间标志位 unsigned char time_buf2[16]; unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9 unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码 unsigned char TempData[8]; //存储显示值的全局变量 void DelayUs2x(unsigned char t);//us级延时函数声明 void DelayMs(unsigned char t); //ms级延时 void Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数 unsigned char KeyScan(void);//键盘扫描 void Init_Timer0(void);//定时器初始化 void UART_Init(void); void main (void) { unsigned char i,num,displaynum; Init_Timer0(); Ds1302_Init(); UART_Init(); while (1) //主循环 { if(SetFlag) //如果接收到串口信息则更新时钟 { for(i=0;i<8;i++) { time_buf1[i]=time_buf2[2*i]*10+time_buf2[2*i+1]; }//数据整合,如2个数 1和5整合成15 Ds1302_Write_Time(); SetFlag=0; //时钟信息更新后标志位清零 } num=KeyScan(); if(num==1) { displaynum++; if(displaynum==2) displaynum=0; } if(ReadTimeFlag==1) { ReadTimeFlag=0; Ds1302_Read_Time(); if(displaynum==0) //显示时间 { TempData[0]=dofly_DuanMa[time_buf1[4]/10];//时 TempData[1]=dofly_DuanMa[time_buf1[4]%10]; TempData[2]=0x40; TempData[3]=dofly_DuanMa[time_buf1[5]/10];//分 TempData[4]=dofly_DuanMa[time_buf1[5]%10]; TempData[5]=0x40; TempData[6]=dofly_DuanMa[time_buf1[6]/10];//秒 TempData[7]=dofly_DuanMa[time_buf1[6]%10]; } else if(displaynum==1)//显示日期 { TempData[0]=dofly_DuanMa[time_buf1[2]/10]; TempData[1]=dofly_DuanMa[time_buf1[2]%10]; TempData[2]=0x40; //加入\"-\" TempData[3]=dofly_DuanMa[time_buf1[3]/10]; TempData[4]=dofly_DuanMa[time_buf1[3]%10]; TempData[5]=0x40; TempData[6]=dofly_DuanMa[1]; TempData[7]=dofly_DuanMa[9]; } } } } void UART_Init(void) { SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收 TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装 TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz TR1 = 1; // TR1: timer 1 打开 EA = 1; //打开总中断 ES = 1; //打开串口中断 } void DelayUs2x(unsigned char t) { while(--t); } void DelayMs(unsigned char t) { while(t--) { //大致延时1mS DelayUs2x(245); DelayUs2x(245); } } void Display(unsigned char FirstBit,unsigned char Num) { static unsigned char i=0; DataPort=0; //清空数据,防止有交替重影 LATCH1=1; //段锁存 LATCH1=0; DataPort=dofly_WeiMa[i+FirstBit]; //取位码 LATCH2=1; //位锁存 LATCH2=0; DataPort=TempData[i]; //取显示数据,段码 LATCH1=1; //段锁存 LATCH1=0; i++; if(i==Num) i=0; } void Init_Timer0(void) { TMOD |= 0x01; EA=1; //总中断打开 ET0=1; //定时器中断打开 TR0=1; //定时器开关打开 } void Timer0_isr(void) interrupt 1 { static unsigned int num; TH0=(65536-2000)/256; //重新赋值 2ms TL0=(65536-2000)%256; Display(0,8); // 调用数码管扫描 num++; if(num==50) //大致100ms { num=0; ReadTimeFlag=1; //读标志位置1 } } unsigned char KeyScan(void) { unsigned char keyvalue; if(KeyPort!=0xff) { DelayMs(10); if(KeyPort!=0xff) { keyvalue=KeyPort; while(KeyPort!=0xff); switch(keyvalue) { case 0xfe:return 1;break; case 0xfd:return 2;break; case 0xfb:return 3;break; case 0xf7:return 4;break; case 0xef:return 5;break; case 0xdf:return 6;break; case 0xbf:return 7;break; case 0x7f:return 8;break; default:return 0;break; } } } return 0; } void UART_SER (void) interrupt 4 //串行中断服务程序 { unsigned char Temp; //定义临时变量 unsigned char i; if(RI) //判断是接收中断产生 { RI=0; //标志位清零 Temp=SBUF; //读入缓冲区的值 time_buf2[i]=Temp&0x0F; i++; if(i==16) //连续接收16个字符信息 { i=0; SetFlag=1; //接收完成标志位置1 } SBUF=Temp; //把接收到的值再发回电脑端 } if(TI) //如果是发送标志位,清零 TI=0; } 四、 安装与调试 更新之前的时间 更新之后的时间 显示的月、日、学号 五、 小结 通过这一周的实训我的收获很多,知道了单片机开发板的很多用途,时钟芯片的各种功能,锁存器的的基本使用,以及发现问题解决问题!提高了解决问题的能力。增长了知识,提高了认识。加深了对问题的剖析能力、夯实了基础。为以后的更加深入的学习埋下浓厚的兴趣。 因篇幅问题不能全部显示,请点此查看更多更全内容