摘要:该应用笔记提供了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系统下的安装与使用