应用笔记 3313

DS1390/DS1391 RTC与Motorola SPI接口DSP的连接


摘要 : 本应用笔记说明了DS1390与内置SPI™接口的Motorola DSP的连接方式,该电路使用了Motorola DSP56F800DEMO开发板和CodeWarrior® IDE。

说明

DS1390实时时钟(RTC)可以通过SPI接口与微控制器(µC)或数字信号处理器(DSP)单元连接,本应用笔记给出了DS1390与内置SPI接口的Motorola DSP的连接方式。该电路使用了Motorola DSP56F800DEMO开发板和CodeWarrior IDE。

使用例程

本例程从新建空白项目开始,详细资料请参考Motorola工具包安装指南指南:创建CodeWarrior项目。本应用笔记的增加代码在main.c中。

操作过程

该程序通过GPIO口控制DS1390的CS。由软件初始化SPI控制器,DSP向DS1390内部写入时间和日期。然后,该软件可以循环读取时间和日期。DS1390和DS1391支持SPI模式1和模式3。

原理图如图1所示,该电路包含一个子卡,附有Motorola开发板。请注意,图1电路中包括几款带有SPI接口的RTC。每次只需使用一款RTC,本文给出了程序仅支持DS1390。程序清单如图2所示。

图1.
图1.

图2. 子卡原理图
详细电路图
(PDF, 138kB)
图2. 子卡原理图

图3. 程序清单
/* File: DS1390.c */
/* This example program was developed using the Motorola
56F800 Demo Board Kit.  Follow the kit instalation guide
for creating a CodeWarrior Project.  Use the shell of the
new project for this example.  Note: This program is for
example only and is not supported by Dallas Semiconductor
Maxim. */

#include "port.h"
#include "stdio.h"
#include "stdlib.h"

/*******************************************************
* Main program for use with Embedded SDK
*******************************************************/

extern sampleASM (void);

void reset_spi(void);
void wbyte_spi(unsigned char);
void init_sci0(Word16);
tx_sci0(unsigned char);
void bcd2ascii(unsigned char);
unsigned char  rbyte_spi(void);

#define REG_BASE 0x0000
#define SCI0_BASE 0x0F00
#define SPI_BASE 0x0F20
#define GPIOA_BASE 0x0FB0
#define GPIOB_BASE 0x0FC0

#define SCI0_SCIBR *(volatile UWord16 *)(SCI0_BASE + 0)
#define SCI0_SCICR *(volatile UWord16 *)(SCI0_BASE + 1)
#define SCI0_SCISR *(volatile UWord16 *)(SCI0_BASE + 2)
#define SCI0_SCIDR *(volatile UWord16 *)(SCI0_BASE + 3)

#define SPSCR *(volatile UWord16 *)(SPI_BASE + 0)
#define SPDSR *(volatile UWord16 *)(SPI_BASE + 1)
#define SPDRR *(volatile UWord16 *)(SPI_BASE + 2)
#define SPDTR *(volatile UWord16 *)(SPI_BASE + 3)

#define GPIO_A_PUR *(volatile UWord16 *)(GPIOA_BASE + 0)
#define GPIO_A_DR *(volatile UWord16 *)(GPIOA_BASE + 1)
#define GPIO_A_DDR *(volatile UWord16 *)(GPIOA_BASE + 2)
#define GPIO_A_PER *(volatile UWord16 *)(GPIOA_BASE + 3)

#define GPIO_B_PUR *(volatile UWord16 *)(GPIOB_BASE + 0)
#define GPIO_B_DR *(volatile UWord16 *)(GPIOB_BASE + 1)
#define GPIO_B_DDR *(volatile UWord16 *)(GPIOB_BASE + 2)
#define GPIO_B_PER *(volatile UWord16 *)(GPIOB_BASE + 3)

void main (void)
{
unsigned char   msec=0, min=0x26, sec=0x00, hr=0x17, dow=0x06,
                                date=0x26, mon=0x12, yr=0x03, write = 0;

        reset_spi();
        init_sci0(195);                 // 30MHz / 195 = 9600 baud

        GPIO_B_DR = 0x0008;             // disable RTC - CS high

        GPIO_B_DR = 0;                  // enable RTC - CS low
        wbyte_spi(0x8d);                // control register write address
        rbyte_spi();                    // dummy read
        wbyte_spi(0x18);                // enable osc, 32kHz sqw
        rbyte_spi();
        GPIO_B_DR = 0x0008;             // disable RTC - CS high

        if(write)
        {
                GPIO_B_DR = 0;                  // enable RTC - CS low
                wbyte_spi(0x80);                // select seconds register write address
                rbyte_spi();                    // dummy read
                wbyte_spi(msec);                // milliseconds register data
                rbyte_spi();
                wbyte_spi(sec);                 // seconds register data
                rbyte_spi();
                wbyte_spi(min);                 // minutes register
                rbyte_spi();
                wbyte_spi(hr);                  // hours register
                rbyte_spi();
                wbyte_spi(dow);                 // day of week register
                rbyte_spi();
                wbyte_spi(date);                // date register
                rbyte_spi();
                wbyte_spi(mon);                 // month register
                rbyte_spi();
                wbyte_spi(yr);                  // year register
                rbyte_spi();
                GPIO_B_DR = 0x0008;             // disable RTC - CS high
        }
        while(1)
        {
                GPIO_B_DR = 0u;                 // enable RTC - CS low

                wbyte_spi(0);                   // seconds register read address
                rbyte_spi();                    // dummy read
                wbyte_spi(0);
                msec = rbyte_spi();             // read milliseconds register
                wbyte_spi(0);
                sec = rbyte_spi();              // read seconds register
                wbyte_spi(0);
                min = rbyte_spi();              // ditto minutes
                wbyte_spi(0);
                hr = rbyte_spi();               // and so on
                wbyte_spi(0);
                dow = rbyte_spi();
                wbyte_spi(0);
                date = rbyte_spi();
                wbyte_spi(0);
                mon = rbyte_spi();
                wbyte_spi(0);
                yr = rbyte_spi();

                GPIO_B_DR = 0x0008;             // disable RTC - CS high

                tx_sci0(0x0d);                  // sequence to print time & date
                tx_sci0(0x0a);
                bcd2ascii(yr);
                tx_sci0('/');
                bcd2ascii(mon);
                tx_sci0('/');
                bcd2ascii(date);
                tx_sci0(' ');
                bcd2ascii(hr);
                tx_sci0(':');
                bcd2ascii(min);
                tx_sci0(':');
                bcd2ascii(sec);
        }

        return;
}

//SPSCR
//15 14  13   12     11   10    9     8    7       6       5    4        3    2    1    0
// r MSB SPRF ERRIE  ovrf modf spte modfen spr1   spr0   sprie spmstr   cpol cpha spe  spite

void reset_spi()
{
int     val;
        SPSCR = 0x0056; // SPR0, SPMSTR, CPHA, SPE
        SPDSR = 0x0007; // 8-bit size

        SPSCR &= 0xfffd;        // clear spe, resets SPI (partial)
        SPSCR |= 0x0002;        // set spe, new values take effect

        GPIO_B_PER = 0x00f3;    // use GPIOB3 as CS for RTC
        GPIO_B_DDR = 0x000d;    // direction is output

        GPIO_A_PER = 0x00f9;    // enable/disable per function (1=enable)
        GPIO_A_DDR = 0x0006;    // direction is output (1=output)
        GPIO_A_DR  = 0;                 // write bits low (0=low)
}

void  wbyte_spi( unsigned char  wbyte)  // ------ write one byte -------
{
        while (!(SPSCR & 0x0200));  // wait for transmitter empty flag

        SPDTR = wbyte;
}

void    bcd2ascii(unsigned char dat)    // ----- convert bcd to ascii and send to sci ----
{
        tx_sci0( (dat >> 4) + 0x30);
        tx_sci0( (dat & 0x0f) + 0x30);
}
unsigned char rbyte_spi(void)   // -------- read one byte ----------
{
        while (!(SPSCR & 0x2000));  // wait for receiver full flag

        return(SPDRR);

}

void    init_sci0(Word16 baud)
{
        GPIO_B_PER = 0x00f3;    // set up
        GPIO_B_DDR = 0x000d;    // direction is output

        SCI0_SCIBR = baud;              // baud rate
        SCI0_SCICR = 0x2000;    // control reg
}
tx_sci0(unsigned char val)
{
UWord16 reg;

        SCI0_SCICR &= 0xfffb;   // turn receiver off
        SCI0_SCICR |= 8;                // turn transmitter on
        do
        {
                reg = SCI0_SCISR;               // clear flag by reading
        }       while( (reg & 0x8000) == 0);    // wait until RDRF is false

        SCI0_SCIDR = (unsigned int) (val);
}


下一步
EE-Mail 订阅EE-Mail,接收关于您感兴趣的新文档的自动通知。
© , Maxim Integrated Products, Inc.
The content on this webpage is protected by copyright laws of the United States and of foreign countries. For requests to copy this content, contact us.
APP 3313:
应用笔记 3313,AN3313, AN 3313, APP3313, Appnote3313, Appnote 3313