共2条
1/1 1 跳转至页
DS1302 【原创】DS1302接口程序
问
#define SCK_HIGH P3OUT |=0x01
#define SCK_LOW P3OUT &=0xfe
#define SCK_OUT P3DIR |=0x1;
#define SD_HIGH P3OUT |=0x02
#define SD_LOW P3OUT &=0xfd
#define SD_IN P3DIR &=0xfd
#define SD_OUT P3DIR |=0x2;
#define SD P3IN & 0x2
#define RST_OUT P3DIR |=0x4
#define RST_LOW P3OUT &=0xfb
#define RST_HIGH P3OUT |=0x4
#define CMD 0x80
#define RDCLK 0x81
#define RDRAM 0xC1
#define WRCLK 0x80
#define WRRAM 0xC0
void wr ( unsigned char cmd )
{
unsigned char i;
SCK_OUT;SD_OUT;
SCK_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
SD_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
for (i=0;i<8;i++)
{ _NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
if ( cmd & 0x1 ) SD_HIGH;
else SD_LOW;
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
SCK_HIGH;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
SCK_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
cmd>>=1;
}
}
unsigned char rd ( void )
{
unsigned char i,tmp,tmp1;
SCK_OUT;
SCK_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
SD_IN;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
tmp=0;tmp1=0x1;
for (i=0;i<8;i++)
{
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
if (SD ) tmp |=tmp1;
else tmp &=(~tmp1);
_NOP();_NOP();_NOP();_NOP();_NOP();
SCK_HIGH;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
SCK_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
tmp1<<=1;
}
return tmp;
}
void set_time(unsigned char adr,unsigned char time)
{
SCK_OUT;SD_OUT;
SCK_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
SD_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
RST_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
RST_HIGH;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
wr( WRCLK | adr);
wr( time);
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
RST_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
}
unsigned char read_time(unsigned char adr)
{
unsigned char tmp;
SCK_OUT;SD_OUT;
SCK_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
SD_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
RST_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
RST_HIGH;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
wr( RDCLK | adr);
tmp=rd( );
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
RST_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
return tmp;
}
void rtc_init(void)
{
unsigned int i,k,l;
unsigned long int time;
RST_OUT;
RST_HIGH;
i=10; while (i--) _NOP();
set_time(CONTROL,0);
i= read_time(SEC);
if ( i&0x80) set_time(SEC,i &0x7f);
set_time(TICK,0xa5);
} 答 1: 唉。怎么没有人支持啊 答 2: 看着太乱了,不敢支持!! 答 3: 谢谢,希望以后继续上传些这样好的资料,和大家共享,只是的确有些看着乱,请整理下方便大家学习。 答 4: 把_NOP()换成延时函数,还有,最好加一个简单的主程序便于调试。附带注释。 答 5: _NOP()换成调用又耗内存,又慢,不好 答 6: 有點亂,看不明白。 答 7: 这个程序可以跑么? 答 8: 太好了,我顶。我的好了到时候也上传给大伙共享 答 9: #include <MSP430x14x.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
#define DS1302_CLK_High P2OUT |=BIT4
#define DS1302_CLK_Low P2OUT &=~BIT4
#define DS1302_IO_High P2OUT |= BIT3
#define DS1302_IO_Low P2OUT &= ~BIT3
#define DS1302_CE_High P2OUT |= BIT2
#define DS1302_CE_Low P2OUT &= ~BIT2
#define DS1302_IO_IN P2DIR &= ~BIT3
#define DS1302_IO_OUT P2DIR |= BIT3
#define SomeNOP() _NOP();_NOP();_NOP();_NOP();_NOP();
char cur_time[7]={0x45,0x18,0x16,0x28,0x03,0x02,0x10};
//sec,min, hour,date,month,week,year//
/*get time from ds1302 related function*/
void spi_write(uchar byte1)
{
char count=8;
do
{
DS1302_CLK_Low;
if(byte1&0x01)
DS1302_IO_High;
else
DS1302_IO_Low;
DS1302_CLK_High;
SomeNOP();
byte1>>=1;
}while(--count);
}
uchar spi_read(void)
{
uchar count=8;
uchar data=0;
DS1302_IO_IN;
do
{
data>>=1;
DS1302_CLK_Low;
SomeNOP();
if(P2IN&BIT3)
data|=0x80;
DS1302_CLK_High;
SomeNOP();
}while(--count);
return(data);
}
void set_time(uchar addr,uchar time)
{
uchar time1=0;
DS1302_CE_High;
spi_write(0x8e);
spi_write(0x00);
DS1302_CLK_Low;
DS1302_CE_Low;
_NOP();
DS1302_CE_High;
_NOP();
spi_write(addr);
spi_write(time);
spi_write(0x8e);
spi_write(0x80);
DS1302_CLK_Low;
DS1302_CE_Low;
}
void init_time(void)//burst write mode
{
uchar i=0;
DS1302_CE_High;
spi_write(0x8e);
spi_write(0x00);
DS1302_CLK_Low;
DS1302_CE_Low;
_NOP();
DS1302_CE_High;
_NOP();
spi_write(0xbe);
for(i=0;i<7;i++)
spi_write(cur_time[i]);
spi_write(0x8e);
spi_write(0x80);
DS1302_CLK_Low;
DS1302_CE_Low;
}
void get_time(void)
{
uchar i=0;
DS1302_CE_High;
SomeNOP();
spi_write(0xbf);
for(i=0;i<7;i++)
cur_time[i]=spi_read();
DS1302_CLK_Low;
DS1302_CE_Low;
DS1302_IO_OUT;
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P2DIR|=0x1c;
P2OUT&=0xe3;
init_time();
get_time();
set_time(0x8c,05);
while(1)
{get_time();}
} 答 10: 以上程序是经本人调试通过的程序,其中的init_time()函数是一次写入所有时间数据,用burst write模式。get_time()函数一次读取所有时间数据即burst read 模式。set_time()函数用来设置某个具体时间数据,你可以通过观察窗口观察Cur_time[7]数组的内容去验证程序的正确性。
顺便说一下,晶体的振荡的确和程序有关,如果你的程序不正确,多半是数据不能写入。因为控制
晶体振荡的控制位是秒寄存器(0x80)的最高位,只有该位清零才能开启晶振。
#define SCK_LOW P3OUT &=0xfe
#define SCK_OUT P3DIR |=0x1;
#define SD_HIGH P3OUT |=0x02
#define SD_LOW P3OUT &=0xfd
#define SD_IN P3DIR &=0xfd
#define SD_OUT P3DIR |=0x2;
#define SD P3IN & 0x2
#define RST_OUT P3DIR |=0x4
#define RST_LOW P3OUT &=0xfb
#define RST_HIGH P3OUT |=0x4
#define CMD 0x80
#define RDCLK 0x81
#define RDRAM 0xC1
#define WRCLK 0x80
#define WRRAM 0xC0
void wr ( unsigned char cmd )
{
unsigned char i;
SCK_OUT;SD_OUT;
SCK_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
SD_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
for (i=0;i<8;i++)
{ _NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
if ( cmd & 0x1 ) SD_HIGH;
else SD_LOW;
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
SCK_HIGH;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
SCK_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
cmd>>=1;
}
}
unsigned char rd ( void )
{
unsigned char i,tmp,tmp1;
SCK_OUT;
SCK_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
SD_IN;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
tmp=0;tmp1=0x1;
for (i=0;i<8;i++)
{
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
if (SD ) tmp |=tmp1;
else tmp &=(~tmp1);
_NOP();_NOP();_NOP();_NOP();_NOP();
SCK_HIGH;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
SCK_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
tmp1<<=1;
}
return tmp;
}
void set_time(unsigned char adr,unsigned char time)
{
SCK_OUT;SD_OUT;
SCK_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
SD_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
RST_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
RST_HIGH;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
wr( WRCLK | adr);
wr( time);
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
RST_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
}
unsigned char read_time(unsigned char adr)
{
unsigned char tmp;
SCK_OUT;SD_OUT;
SCK_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
SD_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
RST_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
RST_HIGH;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
wr( RDCLK | adr);
tmp=rd( );
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
RST_LOW;_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
return tmp;
}
void rtc_init(void)
{
unsigned int i,k,l;
unsigned long int time;
RST_OUT;
RST_HIGH;
i=10; while (i--) _NOP();
set_time(CONTROL,0);
i= read_time(SEC);
if ( i&0x80) set_time(SEC,i &0x7f);
set_time(TICK,0xa5);
} 答 1: 唉。怎么没有人支持啊 答 2: 看着太乱了,不敢支持!! 答 3: 谢谢,希望以后继续上传些这样好的资料,和大家共享,只是的确有些看着乱,请整理下方便大家学习。 答 4: 把_NOP()换成延时函数,还有,最好加一个简单的主程序便于调试。附带注释。 答 5: _NOP()换成调用又耗内存,又慢,不好 答 6: 有點亂,看不明白。 答 7: 这个程序可以跑么? 答 8: 太好了,我顶。我的好了到时候也上传给大伙共享 答 9: #include <MSP430x14x.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
#define DS1302_CLK_High P2OUT |=BIT4
#define DS1302_CLK_Low P2OUT &=~BIT4
#define DS1302_IO_High P2OUT |= BIT3
#define DS1302_IO_Low P2OUT &= ~BIT3
#define DS1302_CE_High P2OUT |= BIT2
#define DS1302_CE_Low P2OUT &= ~BIT2
#define DS1302_IO_IN P2DIR &= ~BIT3
#define DS1302_IO_OUT P2DIR |= BIT3
#define SomeNOP() _NOP();_NOP();_NOP();_NOP();_NOP();
char cur_time[7]={0x45,0x18,0x16,0x28,0x03,0x02,0x10};
//sec,min, hour,date,month,week,year//
/*get time from ds1302 related function*/
void spi_write(uchar byte1)
{
char count=8;
do
{
DS1302_CLK_Low;
if(byte1&0x01)
DS1302_IO_High;
else
DS1302_IO_Low;
DS1302_CLK_High;
SomeNOP();
byte1>>=1;
}while(--count);
}
uchar spi_read(void)
{
uchar count=8;
uchar data=0;
DS1302_IO_IN;
do
{
data>>=1;
DS1302_CLK_Low;
SomeNOP();
if(P2IN&BIT3)
data|=0x80;
DS1302_CLK_High;
SomeNOP();
}while(--count);
return(data);
}
void set_time(uchar addr,uchar time)
{
uchar time1=0;
DS1302_CE_High;
spi_write(0x8e);
spi_write(0x00);
DS1302_CLK_Low;
DS1302_CE_Low;
_NOP();
DS1302_CE_High;
_NOP();
spi_write(addr);
spi_write(time);
spi_write(0x8e);
spi_write(0x80);
DS1302_CLK_Low;
DS1302_CE_Low;
}
void init_time(void)//burst write mode
{
uchar i=0;
DS1302_CE_High;
spi_write(0x8e);
spi_write(0x00);
DS1302_CLK_Low;
DS1302_CE_Low;
_NOP();
DS1302_CE_High;
_NOP();
spi_write(0xbe);
for(i=0;i<7;i++)
spi_write(cur_time[i]);
spi_write(0x8e);
spi_write(0x80);
DS1302_CLK_Low;
DS1302_CE_Low;
}
void get_time(void)
{
uchar i=0;
DS1302_CE_High;
SomeNOP();
spi_write(0xbf);
for(i=0;i<7;i++)
cur_time[i]=spi_read();
DS1302_CLK_Low;
DS1302_CE_Low;
DS1302_IO_OUT;
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P2DIR|=0x1c;
P2OUT&=0xe3;
init_time();
get_time();
set_time(0x8c,05);
while(1)
{get_time();}
} 答 10: 以上程序是经本人调试通过的程序,其中的init_time()函数是一次写入所有时间数据,用burst write模式。get_time()函数一次读取所有时间数据即burst read 模式。set_time()函数用来设置某个具体时间数据,你可以通过观察窗口观察Cur_time[7]数组的内容去验证程序的正确性。
顺便说一下,晶体的振荡的确和程序有关,如果你的程序不正确,多半是数据不能写入。因为控制
晶体振荡的控制位是秒寄存器(0x80)的最高位,只有该位清零才能开启晶振。
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
与电子爱好者谈读图四被打赏50分 | |
与电子爱好者谈读图二被打赏50分 | |
【FRDM-MCXN947评测】Core1适配运行FreeRtos被打赏50分 | |
【FRDM-MCXN947评测】双核调试被打赏50分 | |
【CPKCORRA8D1B评测】---移植CoreMark被打赏50分 | |
【CPKCORRA8D1B评测】---打开硬件定时器被打赏50分 | |
【FRDM-MCXA156评测】4、CAN loopback模式测试被打赏50分 | |
【CPKcorRA8D1评测】--搭建初始环境被打赏50分 | |
【FRDM-MCXA156评测】3、使用FlexIO模拟UART被打赏50分 | |
【FRDM-MCXA156评测】2、rt-thread MCXA156 BSP制作被打赏50分 |