摘要:该应用笔记提供了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;
}
}
}
我们期待您的反馈! 喜欢?不喜欢?有待改善?或为我们提供建议?请与我们联系 — 我们将根据您的意见或建议改善我们的工作。
网页评价或提供建议
自动更新
需要自动接收最新发布的应用笔记吗?请订阅EE-Mail™ (English only)。
| 更多信息 | |
APP 3392: May 01, 2008
|
|
|
|
下载,PDF格式 (48kB)
AN3392,
AN 3392,
APP3392,
Appnote3392,
Appnote 3392
|
|