MAX6902 RTC于8051微控制器的接口

摘要:该应用笔记提供了max6902与8051微控制器接口的硬件和软件设计实例。
max6902引脚配置
概述该应用笔记演示了max6902实时时钟与8051微控制器的接口方式,并提供了基本接口程序的例程。文中采用的微控制器为ds2250,软件用c语言编写。 工作原理该程序通过微控制器的四个通用端口控制spi总线,微控制器向max6902发送一个控制/地址指令,启动数据传输;随后,微控制器向max6902发送其它数据或提供sclk,根据命令字节发送或接收数据。
电路原理图如图1所示,软件如图2所示。
图1. 子卡原理图(pdf下载)
图2. 代码列表 /***************************************************************************/ /* demo6902.c this program is for example only and is not supported by */ /* dallas semiconductor maxim */ /***************************************************************************/ #include /* prototypes for i/o functions */ #include /* register declarations for ds5000 */ /***************************** defines ********************************/ sbit cs = p0^0; sbit sclk = p0^1; sbit din = p0^2; sbit dout = p0^3; /*********************** function prototypes **************************/ void writebyte(); void initialize(); void disp_clk_regs(); void burstramread(); void burstramwrt(); /************************* global variables ***************************/ uchar cy, yr, mn, dt, dy, hr, min, sec, msec, cpol = 1; void set_spi() /* ----- enable dut with sclk preset based upon cpol ----- */ { if(cpol) { cs = 1; /* make sure cs is high */ sclk = 1; /* set sclk for cpol=1 */ cs = 0; /* enable dut */ } else { cs = 1; /* make sure cs is high */ sclk = 0; /* set sclk for cpol=0 */ cs = 0; /* enable dut */ } } void reset_spi() /* ----- reset dut using spi protocol ----- */ { if(cpol) { cs = 1; sclk = 1; } else { cs = 1; sclk = 0; } } void wbyte_spi(uchar w_byte) /* ----- write one byte to dut ----- */ { uchar i; cs = 0; if(cpol) { for(i = 0; i < 8; ++i) { din = 0; if(w_byte & 0x80) { din = 1; } sclk = 0; sclk = 1; w_byte <<= 1; } } else { for(i = 0; i < 8; ++i) { din = 0; if(w_byte & 0x80) { din = 1; } sclk = 1; sclk = 0; w_byte <<= 1; } } } uchar rbyte_spi(void) /* ----- read one byte from dut ----- */ { uchar i; uchar r_byte; uchar tmpbyte; r_byte = 0x00; dout = 1; /* set up port for read */ cs = 0; if(cpol) { for(i=0; i<8; ++i) { sclk = 0; tmpbyte = (uchar)dout; sclk = 1; r_byte <<= 1; r_byte |= tmpbyte; } } else { for(i=0; i<8; ++i) { sclk = 1; tmpbyte = (uchar)dout; sclk = 0; r_byte <<= 1; r_byte |= tmpbyte; } } return r_byte; } void writebyte() /* ----- write one byte, prompt for address and data ------ */ { uchar add; uchar dat; /* get address & data */ printf( enter the read address address (1,2,3...):); scanf(%bx, &add); printf( data (0-ff):); scanf(%bx, &dat); set_spi(); wbyte_spi(add); wbyte_spi(dat); reset_spi(); } void initialize() /* ----- init clock data using user entries ----- */ /* note: no error checking is done on the user entries! */ { set_spi(); wbyte_spi(0x0f); /* control register write address */ wbyte_spi(0x00); /* clear write protect */ reset_spi(); printf( enter the year (0-99): ); scanf(%bx, &yr); printf(enter the month (1-12): ); scanf(%bx, &mn); printf(enter the date (1-31): ); scanf(%bx, &dt); printf(enter the day (1-7): ); scanf(%bx, &dy); printf(enter the hour (1-23): ); scanf(%bx, &hr); hr = hr & 0x3f; /* force clock to 24 hour mode */ printf(enter the minute (0-59): ); scanf(%bx, &min); printf(enter the second (0-59): ); scanf(%bx, &sec); set_spi(); wbyte_spi(0x3f); /* clock burst write */ wbyte_spi(sec); wbyte_spi(min); wbyte_spi(hr); wbyte_spi(dt); wbyte_spi(mn); wbyte_spi(dy); wbyte_spi(yr); wbyte_spi(0); /* control */ reset_spi(); set_spi(); wbyte_spi(0x13); wbyte_spi(0x20); /* century data */ reset_spi(); } void disp_clk_regs() /* --- loop reading clock, display when secs change --- */ { uchar mil, pm, prv_sec = 99; while(!ri) /* read & display clock registers */ { set_spi(); wbyte_spi(0xbf); /* clock burst read */ sec = rbyte_spi(); min = rbyte_spi(); hr = rbyte_spi(); dt = rbyte_spi(); mn = rbyte_spi(); dy = rbyte_spi(); yr = rbyte_spi(); cy = rbyte_spi(); /* dummy read of control register */ reset_spi(); set_spi(); wbyte_spi(0x93); /* century byte read address */ cy = rbyte_spi(); reset_spi(); if(hr & 0x80) mil = 0; else mil = 1; if(sec != prv_sec) /* display every time seconds change */ { if(mil) { printf( %02bx%02bx/%02bx/%02bx %01bx, cy, yr, mn, dt, dy); printf( %02bx:%02bx:%02bx, hr, min, sec); } else { if(hr & 0x20) pm = 'p'; else pm = 'a'; hr &= 0x1f; /* strip mode and am/pm bits */ printf( %02bx%02bx/%02bx/%02bx %02bx, cy, yr, (mn & 0x1f), dt, dy); printf( %02bx:%02bx:%02bx %cm, hr, min, sec, pm); } } prv_sec = sec; } ri = 0; /* swallow keypress to exit loop */ } void burstramread() /* ------ read ram using burst mode ----- */ { uchar k; printf( max6901 ram contents: ); set_spi(); wbyte_spi(0xff); /* ram burst read */ for (k = 0; k < 31; k++) { if(!(k % 8) ) printf( ); printf(%02.bx , rbyte_spi() ); } reset_spi(); } void burstramwrt(uchar data) /* ------ write ram using burst mode ------- */ { uchar k; set_spi(); wbyte_spi(0x7f); /* ram burst write */ for (k=0; k < 31; k++) { wbyte_spi(data); } reset_spi(); } main (void) /* ----------------------------------------------------- */ { uchar i, m, m1; while (1) { printf( max6902 build %s , __date__); printf(ci. initialize max6902 ); printf(cw. write byte ); printf(cr. read time ); printf(rw. write ram ); printf(rr. read ram ); printf(enter menu selection: ); m = _getkey(); switch(m) { case 'c': case 'c': printf(\renter clock routine to run:c); m1 = _getkey(); switch(m1) { case 'i': case 'i': initialize(); break; case 'r': case 'r': disp_clk_regs(); break; case 'w': case 'w': writebyte(); break; } break; case 'r': case 'r': printf(\renter ram routine to run:r); m1 = _getkey(); switch(m1) { case 'r': case 'r': burstramread(); break; case 'w': case 'w': printf( enter the data to write: ); scanf(%bx, &i); burstramwrt(i); break; } break; } } }
lcd和led屏幕的区别哪个好
物联网企业竞争日益激烈,到底谁能从激烈的竞争中脱颖而出?
2010年新春值得入手3G智能手机推荐(二)
WT588F02B-8S语音芯片在水波炉中的应用:提升用户体验与安全性
2020 OPPO开发者大会,致力打造多终端、跨场景的智能化生活
MAX6902 RTC于8051微控制器的接口
基于51与STM32单片机架构
腾讯TM将像MSN用Email登陆并能互通
如何降低UPS电源故障率电池组寿命
兽药残留含量快速检测仪怎么样
湿度卡的特性_湿度卡的分类
OPPO、vivo能否超越华为?国产机一哥花落谁家
“缺芯”全球蔓延凸显国产芯片之殇
自动驾驶实现后,会带来哪些变化?
案例分享第九期:氮化铝陶瓷切割实例
我的个神!小米笔记本Air三月销售22万台
传言苹果MacBook Air本应配备AMD处理器
手机APP定位的基本原理分析
电路的识别和电路的连接方法
Linux系统下的安装与使用