电子钟下位机Word格式.docx
《电子钟下位机Word格式.docx》由会员分享,可在线阅读,更多相关《电子钟下位机Word格式.docx(19页珍藏版)》请在冰点文库上搜索。
#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
SBUF=Saddr;
while(TI!
=1);
TI=0;
//发送地址
TB8=0;
myc+=Saddr;
SBUF=data_type;
while(TI!
myc+=data_type;
//发送数据类型
SBUF=data_num;
myc+=data_num;
//发送数据长度
for(m=0;
m<
data_num;
m++)
SBUF=Send_data_buff[m];
while(TI!
//发送数据
myc+=Send_data_buff[m];
}
SBUF=myc;
/***************************************************************************
PCF8563程序段
****************************************************************************/
#definePCF8563_W0xa2//pcf8563从地址(写)
#definePCF8563_R0xa3//pcf8563从地址(读)
#defineWRADDR0x00//定义写单元首地址
#defineRDADDR0x02//定义读单元首地址
#define_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;
ucharcodeCLKOUT[4]={0x80,//CLKOUT有效,32.768KHz。
0x81,//CLKOUT有效,1024Hz。
0x82,//CLKOUT有效,32KHz。
0x83};
//CLKOUT有效,1KHz。
//定义端口/
sbitSDA=P3^5;
//将P3.5与IIC总线连接,传输数据
sbitSCL=P3^4;
//pcf8563驱动函数。
bitack;
//起动IIC
voidStart_I2c()//8563启动子程序
SDA=1;
/*发送起始条件的数据信号*/
_Nop();
SCL=1;
/*起始条件建立时间大于4.7us,延时*/
SDA=0;
/*发送起始信号*/
/*起始条件锁定时间大于4μs*/
SCL=0;
/*钳住I2C总线,准备发送或接收数据*/
//停止IIC
voidStop_I2c()
/*发送结束条件的数据信号*/
/*发送结束条件的时钟信号*/
/*结束条件建立时间大于4μs*/
/*发送I2C总线结束信号*/
//写1BYTE数据(上传数据、释放IIC、ack确认)
voidSendByte(ucharc)
{ucharidataBitCnt;
for(BitCnt=0;
BitCnt<
8;
BitCnt++)/*要传送的数据长度为8位*/
{if((c<
<
BitCnt)&
0x80)SDA=1;
/*判断发送位*/
elseSDA=0;
/*置时钟线为高,通知被控器开始接收数据位*/
/*保证时钟高电平周期大于4μs*/
}_Nop();
/*8位发送完后释放数据线,准备接收应答位*/
if(SDA==1)ack=0;
elseack=1;
/*判断是否接收到应答信号*/
//读1BYTE数据(置输入状态、读数据)
ucharRcvByte(){
ucharidataretc=0;
ucharidataBitCnt;
/*置数据线为输入方式*/
BitCnt++)
/*置时钟线为低,准备接收数据位*/
/*时钟低电平周期大于4.7μs*/
/*置时钟线为高使数据线上数据有效*/
retc=retc<
1;
if(SDA==1)retc=retc+1;
/*读数据位,接收的数据位放入retc中*/
return(retc);
//确认IIC(输入参数为0表示确认、1表示不确认)
voidAck_I2c(bita)
{if(a==0)SDA=0;
/*在此发出应答或非应答信号*/
elseSDA=1;
/*时钟低电平周期大于4μs*/
/*清时钟线,钳住I2C总线以便继续接收*/
//指定地址写命令/数据(ack==0-->
失败)
/*bitISendByte(ucharsla,ucharc)
{Start_I2c();
//启动总线
SendByte(sla);
//发送器件地址
if(ack==0)return(0);
SendByte(c);
//发送数据
Stop_I2c();
//结束总线
return
(1);
}*/
//指定地址写命令/数据(地址=从地址+子地址,no为从指针*s的个数)
bitISendStr(ucharsla,ucharsuba,uchar*s,ucharno)
ucharidatai;
Start_I2c();
/*启动总线*/
/*发送器件地址*/
SendByte(suba);
/*发送器件子地址*/
for(i=0;
i<
no;
i++)
{SendByte(*s);
/*发送数据*/
s++;
/*结束总线*/
}//指定地址读状态/数据(地址=从地址+子地址,no为从指针*s的个数)
bitIRcvStr(ucharsla,ucharsuba,uchar*s,ucharno)
{ucharidatai;
/*reset_wdt();
*/
SendByte(sla+1);
no-1;
{*s=RcvByte();
Ack_I2c(0);
/*发送就答位*/
*s=RcvByte();
Ack_I2c
(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<
m;
n++)//控制显示字符的个数
{
for(i=8;
i!
=0;
i--)//8位数据显示一个字符
LCD_DATA=(bit)(display_buff[n]&
0x01);
//显示字符应先送低位
LCD_CLOCK=0;
//产生下降沿触发LED
display_buff[n]>
>
=1;
//右移一位
main()//主函数
intk;
ucharidataSendAddr=0xff,SendType=0xaa,SendNum=7;
//传输数据的地址,类型,长度设置初值
for(k=0;
k<
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]&
//发送分数据位
read_timer_buf[2]=read_timer_buf[2]&
0x3f;
//发送时计数据位
read_timer_buf[3]=read_timer_buf[3]&
//发送日计数据位
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;
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,杨振江,《智能仪器与数据采集系统中的新器件及应用》,西安电子科技大学出版社