现象是读的数据始终是0;
能够确认数据是以某种时序发出去了(当SDI 与SDO端口连在一起并且SDI为输入、SDO为输出的时候,SDI能够接收SDO发出的值)
在我的代码中,SDO发送给DS1302数据(writebyte)的时候,我将SDI设置为输出,防止直接接收了SDO发出的值;在读取数据的时候(readbyte),重新将SDI设置为输入。
另外,因为读取一次ds1302中的数据同时设计到了读操作和写操作(要先写入一个命令),所以我在readbyte和writebyte的刚开始,分别为这两种时序设置了不同的CKE。
不知这样处理是否妥当?
#include
typedef unsigned char uchar;
typedef unsigned int uint;
uint sec = 0 ,sec1 = 0 ,sec2 = 0;
const unsigned char table[10] = {0B00111111,
0B00110000,
0B01011011,
0B01111001,
0B01110100,
0B01101101,
0B01101111,
0B00111000,
0B01111111,
0B01111101};
void WriteByte(uint address); //写一个字节
uchar ReadByte(); //读一个字节
uchar ReadDS1302(uint address); //读取ds1302中的数据
void WriteCommand(uint address , uint data);//往ds1302中写数据
void InitDS1302(); //ds1302的初始化
void interrupt Display(); //中断并显示
void Init(); //端口初始化
void Spi_Init(); //spi的初始化
void main()
{
Init();
Spi_Init();
InitDS1302();
INTCON = 0b11100000;
while(1)
{
sec = ReadDS1302(0x81); //读取秒钟的时间
sec1 = sec & 0X0f;
sec2 = sec >> 4;
}
}
void WriteByte(uint address)
{
SSPSTAT = 0b10000000; //cke = 0
RC0 = 1; //RC0被用来接CE线
SSPBUF = address;
while(0 == SSPIF);
SSPIF = 0;
RC0 = 0;
}
uchar ReadByte()
{
TRISC4 = 1;
SSPSTAT = 0b11000000;
RC0 = 1;
uchar data = 0;
while(0 == BF);
data = SSPBUF;
RC0 = 0;
TRISC4 = 0;
return data;
}
uchar ReadDS1302(uint address)
{
uint tmp = 0 ,data;
uint i;
WriteByte(address); //写入addr
data = ReadByte(); //读取
for(i = 0; i < 8; i++) //将数据顺序矫正
{
tmp = data & 0X01;
data >>= 1;
tmp << =7;
data = data | tmp;
}
return data;
}
void WriteCommand(uint address , uint data)
{
WriteByte(address);
WriteByte(data);
}
void InitDS1302() //ds1302的数据顺序和spi的顺序是反的,所以设置的数据也反着来
{
WriteCommand(0Xe1 , 0X00); //写保护寄存器关闭
WriteCommand(0X01 , 0X80); //秒为1,同时开启时钟;
WriteCommand(0X41 , 0X2C); //分为1;
WriteCommand(0X21 , 0X48); //时为1;
WriteCommand(0X61 , 0X80); //日为1;
WriteCommand(0X11 , 0X80); //月为1;
WriteCommand(0X51 , 0X80); //星期1;
WriteCommand(0X31 , 0X80); //年份1;
WriteCommand(0X01 , 0X80); //秒为1,同时开启时钟;
WriteCommand(0Xe1 , 0X01); //写保护寄存器开启;
}
void interrupt Display()
{
PORTB = 0Xfe;
PORTA = table[sec2];
_delay(50);
PORTA = 0X00;
PORTB = 0Xfd;
PORTA = table[sec1];
_delay(50);
PORTA = 0X00;
TMR0 = 0Xea;
T0IF = 0;
}
void Init()
{
ANSEL = 0X00;
ANSELH = 0X00;
TRISA = 0X00;
TRISB = 0X00;
PORTB = 0Xff;
INTCON = 0;
OSCCON = 0b01010001; //2M时钟
OPtiON_REG= 0b01010010 ; //预分频8
}
void Spi_Init()
{
TRISC = 0X00;
SSPCON = 0b00100000;
SSPSTAT = 0b11000000;
ADCON1 = 0b00000110;
}
|