电子钟下位机.docx

上传人:b****1 文档编号:20130334 上传时间:2023-04-25 格式:DOCX 页数:19 大小:84.69KB
下载 相关 举报
电子钟下位机.docx_第1页
第1页 / 共19页
电子钟下位机.docx_第2页
第2页 / 共19页
电子钟下位机.docx_第3页
第3页 / 共19页
电子钟下位机.docx_第4页
第4页 / 共19页
电子钟下位机.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

电子钟下位机.docx

《电子钟下位机.docx》由会员分享,可在线阅读,更多相关《电子钟下位机.docx(19页珍藏版)》请在冰豆网上搜索。

电子钟下位机.docx

电子钟下位机

课程设计报告

 

设计课题:

电子钟下位机

 

专业班级:

学生姓名:

指导教师:

设计时间:

 

电子钟下位机

一课程设计目的:

通过对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,杨振江,《智能仪器与数据采集系统中的新器件及应用》,西安电子科技大学出版社

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > 司法考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1