摘 要: 随着现代化工业过程控制领域的飞速发展,以CPU为核心的新型控制仪表得到了广泛的应用,与之配套的二次记录仪表也发展到无纸记录的新阶段。无纸记录仪对于工业现场信号记录与监测提供了相当准确与精确的记录,而实现这一准确与精确的记录与该系统的时钟是紧密联系在一起的。文章介绍用C51来实现DALLAS公司的串行实时钟芯片DS1305在无纸记录仪应用。关键词:C51 串行时钟 无纸记录仪 关于Dallas公司的串行实时钟芯片DS1305工作原理,在参考文献[2]有详细的介绍,本文不再赘述。本文从C51的角度,来详细介绍DS1305在我们所研制的无纸记录仪上的实现。 1 C51的特点 C语言是一种编译型程序设计语言,它兼顾了多种高级语言的特点,并具备汇编语言的功能。C语言有功能丰富的库函数,运算速度快,编译效率高,有良好的可移植性而且可以直接实现对系统硬件的控制。 C语言是一种结构化程序设计语言,它支持由顶向下结构化程序设计技术。 C语言程序具有完善的模块化程序结构,从而为软件开发中采用模块化程序设计方法提供了有力保障。因此,使用C语言进行程序设计来编写目标系统软件会大大缩短开发周期,增加软件的可读性,便于改进和扩充。 本系统采用Keil公司的C51编译器,版本为V6.10a。 2 DS1305与AT89C55WD的连接图 见图1 说明:本系统SERMODE 脚与VCC相连,为MOTOROLA SPI 方式。INT0脚与AT89C55WD的INT0脚相连,对时钟进行每秒中断1次编程,CPU每秒对4个通道进行采样。 3 DS1305引脚定义 根据C51 所提供的定义关键字SBIT,进行如下的定义: SBIT clk_ce=P1^3; /*时钟片选*/ SBIT sclk_bit=P2^4; /*时钟脉冲输入端*/ SBIT sdi_bit=P2^6; /*时钟输入引脚*/ SBIT sdu_bit=P2^7; /*时钟输出引脚*/ 说明:P1^3 等价于汇编语言P1.3的用法,由C51头文件REG51.H定义,形式如下: #include 3 时钟初始化 对DS1305的初始化主要有如下三个写操作: 往控制寄存器写0x05; 往状态寄存器写0x01; 往涓流充电寄存器写0xa5; 对应的C51程序如下,该程序调用了子程序dswr(uchar ac)在其后说明: initclock() /*时钟初始化*/ { sclk_bit=0; dswr(0x8f);/* 往控制寄存器写0x05*/ dswr(0x05); dswr(0x90); /*往状态寄存器写0x01 */ dswr(0x01); dswr(0x91); /*往涓流充电寄存器写0xa5*/ dswr(0xa5); } 函数dswr 中用到参数uchar 是在C51 主程序开始定义的无符号字符: #define unsigned char uchar 有了上述定义,整个程序都可以这样使用。 dswr(uchar ac) /*ACC中的数据从高位开始送入ds1305 */ { uchar i; clk_ce=1; sdu_bit=1; for (i=0;i<8;i++) { sdi_bit=(ac&0x80==0x80)?1:0; sclk_bit=1; sclk_bit=0; ac=ac<<1; } } 4 时钟的读 uchar dsrd() /*读时钟*/ { uchar i,j,ac=0,x; clk_ce=1; for (i=0;i<=7;i++) { sclk_bit=1; j=2; while (j--); sclk_bit=0; x=P2; ac=(x&0x80)>>i|ac;/*高位在前,底位在后*/ } return (ac); clk_ce=0; } 说明:因为DS1305为串行方式,每次输出1位,且高位在前,故上述程序用了向右移位再与原值相或的技巧来实现。 5 时钟的设置 clockset() /*时钟设置*/ { uchar i,j; sclk_bit=0; dswr(0x8f);/* 往控制寄存器写0x05*/ dswr(0x05); clk_ce=0; sclk_bit=0; for (i=0x80,j=0;i<=0x86;i++) if(i!=0x83) { clk_ce=1; dswr(i);/*address*/ dswr(y_m_d_h_m[5-j]);/*data*/ j++; clk_ce=0; } clockwp(); } 函数中用到数组y_m_d_h_m存放的是即将写入时钟的年、月、日、时、分和秒的压缩的BCD码,在主程序中定义为 uchar y_m_d_h_m[6]={0x01,0x05,0x19,0x23,0x10,0x00}; 一旦设置好,就必须调用时钟写保护来防止对时钟的误操作。 clockwp() /*时钟写保护*/ { clk_ce=1; dswr(0x8f); dswr(0x45); clk_ce=0; } 6 时间的显示 在我们所研制的无纸记录仪,显示采用液晶显示器,因为液晶显示器不同,则为液晶显示器所写的驱动程序也不一样,在此不对液晶显示器部分进行详细说明,而仅对于我们所采用的技巧做一说明。 先定义两个数组: 其一: uchar clock[]={0x00,0x00,0x00,0x00,0x00,0x00};/*秒、分、时、日、月、年*/ 该数组把从时钟读来压缩BCD数据暂存于此。 其二: 从BCD码转换为非压缩BCD码。 uchar dispclock[]={0x12,0x10,0x10,0x11,0x0d,0x10,0x17,0x0d,0x11,0x10,0x00,0x11,0x12,0x1a,0x11,0x18,0x1a,0x11,0x18}; /*年、月、日、星期、时、分、秒*/ 例子:2001-07-10 12:18:18 0x10...0x19,0x0d,0x1a分别是液晶显示器内部CG-ROM字符0-9,- 和 :的压缩BCD码。 clockread() /* 读时钟数据送入clock数组*/ { uchar i,ac,j,m=1; for (i=0;i<7;i++) { dswr(i); ac=dsrd() ; switch (i) { case 0: case 1: case 2: clock[i]=ac ;break; case 3: break; default:clock[i-1]=ac; } clk_ce=0; } } clockdisp() /*把时间显示数组中的数据显示*/ { uchar j=DELAY; uchar ac,i; for (i=0;i<=5;i++) /* 把clock 数组中的BCD码转换成clockdisp的非压缩BCD码*/ { ac=clock[i]; ac= ac>>4; ac+=0x10; dispclock[2+3*(5-i)]=ac; ac=clock[i]; ac=ac & 0x0f; ac+=0x10; dispclock[2+3*(5-i)+1]=ac; } /*以下是对液晶进行操作*/ data_wri(0); data_wri(0); com_wri(0x24); com_wri(0xb0); for (i=0;i<19;i++) { wait3(); lcd_ce=0; PLCD_DATA=dispclock[i]; while (j--); lcd_ce=1; j=DELAY; } lcd_ce=0; com_wri(0xb2); lcd_ce=1; }
7 时钟每秒中断一次 clockalarm() { uchar set[]={0x87,0x81,0x88,0x81,0x89,0x80,0x8a, 0x80,0x8f,0x05,0x90,0x01,0x91,0xa5}; uchar i,j; clk_ce=0; sclk_bit=0; i=0; for (j=0;j<7;j++) { dswr(set[i++]); dswr(set[i++]); clk_ce=0; i=2; while (i--); } } 8 结论 我们用C51对DS1305进行编程,可读性强,模块化好,结构清晰,方便今后的系统维护,应用于我们开发的无纸记录仪中,运行稳定,效果良好。该系统已经通过福建省科技庁的鉴定。 参考文献
[1] 马忠梅等 单片机的C语言应用程序设计 北京航空航天大学出版社,2000年 修订版 [2] 王润田等 串行时钟DS1305在野外自容式设备中的应用 电子技术1999年第11期 [3] DALLAS 公司DS1305 Serial Alarm Real Time Clock(RTC) Data Sheet 08/10/99
|