电子钟下位机.docx
- 文档编号:659292
- 上传时间:2023-04-29
- 格式:DOCX
- 页数:19
- 大小:84.69KB
电子钟下位机.docx
《电子钟下位机.docx》由会员分享,可在线阅读,更多相关《电子钟下位机.docx(19页珍藏版)》请在冰点文库上搜索。
电子钟下位机
课程设计报告
设计课题:
电子钟下位机
专业班级:
学生姓名:
指导教师:
设计时间:
电子钟下位机
一课程设计目的:
通过对89C51和8563芯片编程实现电子钟系统
二课程设计题目的要求:
通过应用时钟芯片8563和串口液晶,实现电子钟。
然后将时钟数据经过232串行通信传送的上位机PC机上,应用串口助手显示所传送的数据,要求数据按照帧格式显示。
三系统分析与设计:
1:
系统总体设计
本实验所用模块主要有:
89C51模块,8563模块,MAX232芯片等,89C51模块8563模块启动后读取时间数据和向232电缆线传送当前时间数据,89C51芯片与8563芯片构成电子钟的电路图如图1
图1电子钟的电路图
8563的主要功能是在接收89C51的数据后,完成时钟的功能,模块内的数据有秒,分,时,日,周,月,年。
然后通过I2C总线先89C51传送数据。
8563芯片的如图2:
图28563芯片
MAX232芯片的作用是接收89C51的数据,通过串口线向PC机传送数据。
MAX232的芯片如图3
图3MAX232芯片
2:
系统详细设计总体框架、系统流程图如下:
在完成对89C51和8563的初始化后,通过I2C总线对8563赋初值,然后反复对8563读当前始终数值,发现数据有变化则发送到232电缆传送到PC机上。
系统流程图如下:
程序流程图
源程序如下
#include
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineulongunsignedlong
#defineMyAddrCode0xa0//本机地址
#defineSend_data_buff_num7//发送和接收缓冲区的
ucharidataSend_data_buff[Send_data_buff_num]={0};
ucharidataFlag_SBUF0=0;//通讯标志位。
1-通讯完成;0-无通讯信息。
#defineSBUF0Delay2000
init_timer_sbuf()//串行口初始化.
{
TMOD=0X21;//设置定时器工作方式
TH1=0Xfd;TL1=0Xfd;
PCON=0X00;
SCON=0XE0;//设置串口工方式
TB8=1;//发送8位数据SM2=1;//允许多机通信
EA=1;//开中断
TR1=1;//开定时器1
}
Send_data(ucharSaddr,uchardata_type,uchardata_num)//设置发送数据变量
{ucharidatam,myc=0;//校验和初值为0
TB8=1;
SBUF=Saddr;while(TI!
=1);TI=0;//发送地址
TB8=0;
myc+=Saddr;
SBUF=data_type;while(TI!
=1);TI=0;
myc+=data_type;//发送数据类型
SBUF=data_num;while(TI!
=1);TI=0;
myc+=data_num;//发送数据长度
for(m=0;m { SBUF=Send_data_buff[m];while(TI! =1);TI=0;//发送数据 myc+=Send_data_buff[m]; } SBUF=myc;while(TI! =1);TI=0; } /*************************************************************************** PCF8563程序段 ****************************************************************************/ #definePCF8563_W0xa2//pcf8563从地址(写) #definePCF8563_R0xa3//pcf8563从地址(读) #defineWRADDR0x00//定义写单元首地址 #defineRDADDR0x02//定义读单元首地址 #define_Nop()_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_()//设置延迟时间 ///////////////////////////////////////////////////////////////////////////// //定义地址 #definePCF8563_CONTROL_STATE00x00//控制状态寄存器1 #definePCF8563_CONTROL_STATE10x01//控制状态寄存器2 #definePCF8563_CLKOUT0x0d//CLKOUT频率寄存器 #definePCF8563_TIMER_CONTROL0x0e//定时器控制寄存器 #definePCF8563_TIMER_DATA0x0f//定时器倒计数数值寄存器 #definePCF8563_MINUTE0x02//秒 #definePCF8563_SECOND0x03//分 #definePCF8563_HOUR0x04//时 #definePCF8563_DATE0x05//日 #definePCF8563_WEEK0x06//星期 #definePCF8563_MONTH0x07//月/世纪 #definePCF8563_YEAR0x08//年 #definePCF8563_MINUTE_ALARM0x09//分钟报警 #definePCF8563_SECOND_ALARM0x0a//小时报警 #definePCF8563_YEAR_ALARM0x0b//日报警 #definePCF8563_WEEK_ALARM0x0c//星期报警 //定义寄存器初始化 ucharcodeCS1[2]={0x00,//普通模式 0x28};//时钟停止运行,电源复位有效 ucharcodeCS2[2]={0x12,//INT有效,AF=0;TF=0;报警中断有效;定时中断清除。 0x02};//INT受TF控制,AF=0;TF=0;报警中断有效;定时中断清除。 ucharcodeCLKOUT[4]={0x80,//CLKOUT有效,32.768KHz。 0x81,//CLKOUT有效,1024Hz。 0x82,//CLKOUT有效,32KHz。 0x83};//CLKOUT有效,1KHz。 //定义端口/ sbitSDA=P3^5;//将P3.5与IIC总线连接,传输数据 sbitSCL=P3^4;//将P3.5与IIC总线连接,传输数据 //pcf8563驱动函数。 bitack; //起动IIC voidStart_I2c()//8563启动子程序 { SDA=1;/*发送起始条件的数据信号*/ _Nop(); SCL=1; _Nop();/*起始条件建立时间大于4.7us,延时*/ _Nop(); _Nop(); _Nop(); _Nop(); SDA=0;/*发送起始信号*/ _Nop();/*起始条件锁定时间大于4μs*/ _Nop(); _Nop(); _Nop(); _Nop(); SCL=0;/*钳住I2C总线,准备发送或接收数据*/ _Nop(); _Nop(); } //停止IIC voidStop_I2c() { SDA=0;/*发送结束条件的数据信号*/ _Nop();/*发送结束条件的时钟信号*/ SCL=1;/*结束条件建立时间大于4μs*/ _Nop(); _Nop(); _Nop(); _Nop(); _Nop(); SDA=1;/*发送I2C总线结束信号*/ _Nop(); _Nop(); _Nop(); _Nop(); } //写1BYTE数据(上传数据、释放IIC、ack确认) voidSendByte(ucharc) {ucharidataBitCnt; for(BitCnt=0;BitCnt<8;BitCnt++)/*要传送的数据长度为8位*/ {if((c< elseSDA=0; _Nop(); SCL=1;/*置时钟线为高,通知被控器开始接收数据位*/ _Nop();/*保证时钟高电平周期大于4μs*/ _Nop(); _Nop(); _Nop(); SCL=0; }_Nop(); _Nop(); SDA=1;/*8位发送完后释放数据线,准备接收应答位*/ _Nop(); _Nop(); SCL=1; _Nop(); _Nop(); _Nop(); if(SDA==1)ack=0; elseack=1;/*判断是否接收到应答信号*/ SCL=0; _Nop(); _Nop(); } //读1BYTE数据(置输入状态、读数据) ucharRcvByte(){ ucharidataretc=0; ucharidataBitCnt; SDA=1;/*置数据线为输入方式*/ for(BitCnt=0;BitCnt<8;BitCnt++) { _Nop(); SCL=0;/*置时钟线为低,准备接收数据位*/ _Nop(); _Nop();/*时钟低电平周期大于4.7μs*/ _Nop(); _Nop(); _Nop(); SCL=1;/*置时钟线为高使数据线上数据有效*/ _Nop(); _Nop(); retc=retc<<1; if(SDA==1)retc=retc+1;/*读数据位,接收的数据位放入retc中*/ _Nop(); _Nop(); } SCL=0; _Nop(); _Nop(); return(retc); } //确认IIC(输入参数为0表示确认、1表示不确认) voidAck_I2c(bita) {if(a==0)SDA=0;/*在此发出应答或非应答信号*/ elseSDA=1; _Nop(); _Nop(); _Nop(); SCL=1; _Nop(); _Nop();/*时钟低电平周期大于4μs*/ _Nop(); _Nop(); _Nop(); SCL=0;/*清时钟线,钳住I2C总线以便继续接收*/ _Nop(); _Nop(); } //指定地址写命令/数据(ack==0-->失败) /*bitISendByte(ucharsla,ucharc) {Start_I2c();//启动总线 SendByte(sla);//发送器件地址 if(ack==0)return(0); SendByte(c);//发送数据 if(ack==0)return(0); Stop_I2c();//结束总线 return (1); }*/ //指定地址写命令/数据(地址=从地址+子地址,no为从指针*s的个数) bitISendStr(ucharsla,ucharsuba,uchar*s,ucharno) { ucharidatai; Start_I2c();/*启动总线*/ SendByte(sla);/*发送器件地址*/ if(ack==0)return(0); SendByte(suba);/*发送器件子地址*/ if(ack==0)return(0); for(i=0;i {SendByte(*s);/*发送数据*/ if(ack==0)return(0); s++; } Stop_I2c();/*结束总线*/ return (1); }//指定地址读状态/数据(地址=从地址+子地址,no为从指针*s的个数) bitIRcvStr(ucharsla,ucharsuba,uchar*s,ucharno) {ucharidatai; Start_I2c();/*启动总线*/ SendByte(sla);/*发送器件地址*/ if(ack==0)return(0); SendByte(suba);/*发送器件子地址*/ if(ack==0)return(0); /*reset_wdt();*/ Start_I2c(); SendByte(sla+1); if(ack==0)return(0); for(i=0;i {*s=RcvByte();/*发送数据*/ Ack_I2c(0);/*发送就答位*/ s++; } *s=RcvByte(); Ack_I2c (1);/*发送非应位*/ Stop_I2c();/*结束总线*/ return (1); } //初始化模式 voidinit8563() { ucharidatainit_mod_buf[2]; init_mod_buf[0]=CS1[0]; init_mod_buf[1]=CS2[0]; ISendStr(PCF8563_W,WRADDR,init_mod_buf,0x02); } ucharinit_timer_buf[7]={0x00,0x52,0x14,0x21,0x04,0x07,0x06};//数据初值依次为(秒,分,时,日,周,月,年) ucharread_timer_buf[7];//定义数组读数 voidinit_timer() { ISendStr(PCF8563_W,RDADDR,init_timer_buf,0x07); } //读时钟秒分时日周月年 voidread_timer() { IRcvStr(PCF8563_W,RDADDR,read_timer_buf,0x07); } /*********************************************************************/ //串行LED显示模块 //适用型号: 串行LED和串行连接的数码管 //程序设计: Cn //日期: 2009-07-15 /*********************************************************************/ sbitLCD_DATA=P3^5;//串行LED数据线引脚 sbitLCD_CLOCK=P3^4;//串行LED时钟线引脚 sbitLCD_VCC=P1^0;//串行LED时电源引脚 sbitLCD_GND=P1^3;//串行LED时地线引脚 ucharidatadisplay_buff[8]={0,0,0,0,0,0,0,0};//预留的8字节显示缓冲区 /*********************************************************************/ //标准串口7段码LED编码 ucharcodemem[44]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6, 0xee,0x3e,0x9c,0x7a,0x9e,0x8e, 0xfd,0x61,0xdb,0xf3,0x67,0xb7,0xbd,0xe1,0xff,0xf7, 0xef,0x3f,0x9e,0x7b,0x9f,0x8f, 0x6F,0x2A,0x02,0xCA,0xCF,0x01,0x00, 0xce,0xee,0xb6,0x1c,0x1e}; /*DB0FCH,060H,0DAH,0F2H,066H,0B6H,0BEH,0E0H,0FEH,0F6H 0123456789 DB0EEH,03EH,09CH,07AH,09EH,08EH AbCdEF DB0FDH,061H,0DBH,0F3H,067H,0B7H,0BFH,0E1H,0FFH,0F7H 0.1.2.3.4.5.6.7.8.9. DB0EFH,03FH,09DH,07BH,09FH,08FH A.b.C.d.E.F. DB06FH,02AH,02H,0CAH,0CFH,01H,0H H.n-? P.."" DB0CEH,0EEH,0B6H,01CH,01EH PRSLT*/ /*********************************************************************/ //名称: display_slcd //说明: //功能: 由串行LED中显示m个字符 //调用: //输入: m-显示字符的个数;display_buff[i]-显示的字符 //返回值: 无 /*********************************************************************/ voiddisplay_slcd(ucharm) { ucharn,i; LCD_VCC=1; LCD_GND=0; LCD_CLOCK=1;//初始化LED时钟引脚 for(n=0;n { for(i=8;i! =0;i--)//8位数据显示一个字符 { LCD_DATA=(bit)(display_buff[n]&0x01);//显示字符应先送低位 LCD_CLOCK=0; LCD_CLOCK=1;//产生下降沿触发LED display_buff[n]>>=1;//右移一位 } } } main()//主函数 { intk; ucharidataSendAddr=0xff,SendType=0xaa,SendNum=7;//传输数据的地址,类型,长度设置初值 for(k=0;k<8;k++) { display_buff[k]=mem[k]; } init_timer_sbuf();//调串口初始化程序 init8563();//调8563初始化程序 init_timer();//调时钟初始化程序 while (1){//循环发送数据 loop: read_timer(); read_timer_buf[0]=read_timer_buf[0]&0x7f;//发送秒数据位 display_buff[6]=mem[read_timer_buf[0]>>4]; display_buff[7]=mem[read_timer_buf[0]&0x0f]; read_timer_buf[1]=read_timer_buf[1]&0x7f;//发送分数据位 read_timer_buf[2]=read_timer_buf[2]&0x3f;//发送时计数据位 read_timer_buf[3]=read_timer_buf[3]&0x3f;//发送日计数据位 read_timer_buf[4]=read_timer_buf[4]&0x07;//发送周计数据位 read_timer_buf[5]=read_timer_buf[5]&0x9f;//发送月计数据位 read_timer_buf[6]=read_timer_buf[6]&0xff;//发送年计数据位 display_slcd(8); if(read_timer_buf[0]==Send_data_buff[0])//读取数据与发送数据是否相等 gotoloop;//相等循环到LOOP else{for(k=0;k<7;k++)//不相等则按位发送 {Send_data_buff[k]=read_timer_buf[k];}} Send_data(SendAddr,SendType,SendNum); } } 四.系统调试过程中出现的主要问题: 1.由于在RcvStr子程序中的看门狗电路导致程序不能进行编译,在删除reset_wdt();后程序可以进行。 2.由于在主程序中没有对数据的读取设置程序控制,导致在显示时数据没有变化。 3.由于在串口初始化是对TH1,L1,赋值错误导致波特率错误而不能正确显示时钟数值。 五.系统运行报告与结论: 本实验的系统有89C51,MAX232,8563等芯片构成完成一个时钟电路,电路启动后,系统将自动始终功能每秒加1,本系统记时准确,程序较简单;主要存在的问题是记时系统的功能单一,修正错误时间麻烦,需要在程序中改正;主要还须改进的问题是,需要增加键盘控制功能,使修改时间变的简单。 六.总结 1.设计中遇到的问题及解决过程: 对程序结构和器件的认识不深,不知道如何下手设计程序,通过对器件文档的查阅后,明白了设计的流程。 编写程序时,对子函数的意义和作用不太了解,在反复读子函数的过程中明白了子函数的作用。 不明白如何使用串口助手,在老师的帮助下懂得了使用方法。 2、设计中产生的错误及原因分析 : 在设计程序时,由于开始时对时间寄存器中的数据全部选取导致数据传输错误,在阅读PDF文档后,设置了时间的秒,分,时,日,周,月,年,的位数正确的选取后,能够显示正确的数据。 3、设计体会和收获: 通过本次实验,主要的收获是,明白了8563芯片的使用和工作原理,其次是在编程的过程中,加深了自己对程序的理解和应用能力以及自己在硬件焊接,和软件编程中的不足之处。 七.参考书目: 4.马忠梅,《单片机的c语言应用程序设计》,北京航空航天大学出版社 5.王福瑞,《单片微机测控系统设计大全》,北京航空航天大学出版社 6.徐爱钧,《单片机高级语言C51应用程序设计》,电子工业出版社 4,杨振江,《智能仪器与数据采集系统中的新器件及应用》,西安电子科技大学出版社
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 电子钟 下位
![提示](https://static.bingdoc.com/images/bang_tan.gif)