从ds1302芯片读取时间,固定显示5454545454,代码如下:
unsigned char number = '0';
unsigned char data[2] = {0};
unsigned char l_tmpdate[7]={0x0,0x0,0x12,0x1,0x4,0x1,0x18};//秒分时日月周年2018-04-18 12:00:00 (年为两位 2011)
unsigned char out_time[14]={0};//,0,0,0,2,1,8,1,4,0,8,1,0,2};
char write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月年 最低位读写位
char read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; //读地址与写地址不一样?????读比写大1
//写一个字节函数
void Write_Ds1302_Byte(unsigned char temp)
{
char i;
for (i=0;i<8;i++) //循环8次 写入数据
{
//SCK=0;
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1,0);
SysCtlDelay((SysCtlClockGet() / 3000));
//SDA=temp&0x01; //每次传输低字节 //temp和0x01作与运算值传给SDA
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_2,temp&0x01);
//SCK=1;
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1,GPIO_PIN_1);
SysCtlDelay((SysCtlClockGet() / 3000));
temp>>=1; //右移一位
}
}
//写函数
void Write_Ds1302( char address,char dat )
{
//SCK=0;
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1,0);
SysCtlDelay((SysCtlClockGet() / 3000));
//RST=0;
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_3,0);
SysCtlDelay((SysCtlClockGet() / 3000));
//RST=1;
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_3,GPIO_PIN_3);
SysCtlDelay((SysCtlClockGet() / 3000));
SysCtlDelay((SysCtlClockGet() / 3000)); //启动
address = address & 0xFE;
Write_Ds1302_Byte(address); //发送地址
Write_Ds1302_Byte(dat); //发送数据
//RST=0; //恢复
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_3,0);
}
//读出ds1302
char Read_Ds1302 ( char address )
{
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_2,GPIO_PIN_2);
char i,temp=0;
//SCK=0;
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1,0);
SysCtlDelay((SysCtlClockGet() / 3000));
//RST=0;
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_3,0);
SysCtlDelay((SysCtlClockGet() / 3000));
//RST=1;
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_3,GPIO_PIN_3);
SysCtlDelay((SysCtlClockGet() / 3000));
SysCtlDelay((SysCtlClockGet() / 3000));
address = address | 0x01;
Write_Ds1302_Byte(address);
SysCtlDelay((SysCtlClockGet() / 3000));
GPIOPinTypeGPIOInput(GPIO_PORTE_BASE,GPIO_PIN_2);//sda
SysCtlDelay((SysCtlClockGet() / 3000));
for (i=0;i<7;i++) //循环8次 读取数据 //RData=GPIOPinRead( GPIO_PORTB_BASE,0xff)
{
//SCK=1;
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1,GPIO_PIN_1);
SysCtlDelay((SysCtlClockGet() / 3000));
temp=temp>>1; //右移一位
//SCK=0;
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1,0);
SysCtlDelay((SysCtlClockGet() / 3000));
//if(GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_2) == 0xff) //while (GPIOPinRead(GPIO_PORTC_BASE, GPIO_PIN_7) == 0x00);
temp=GPIOPinRead( GPIO_PORTE_BASE,0xff);
temp|=0x80; //每次传输低字节
}
//SCK=1;
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1,GPIO_PIN_1);
SysCtlDelay((SysCtlClockGet() / 3000));
temp>>=1; //右移一位
if(GPIOPinRead(GPIO_PORTE_BASE, GPIO_PIN_2) == 0xff) //while (GPIOPinRead(GPIO_PORTC_BASE, GPIO_PIN_7) == 0x00);
temp|=0x80; //每次传输低字节
//SCK=0;
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1,0);
SysCtlDelay((SysCtlClockGet() / 3000));
GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE,GPIO_PIN_2);
//RST=0;
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_3,0);
SysCtlDelay((SysCtlClockGet() / 3000)); //以下为DS1302复位的稳定时间
//SCK=1;
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1,GPIO_PIN_1);
SysCtlDelay((SysCtlClockGet() / 3000));
//SDA=0;
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_2,0);
SysCtlDelay((SysCtlClockGet() / 3000));
//SDA=1;
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_2,GPIO_PIN_2);
SysCtlDelay((SysCtlClockGet() / 3000));
return (temp); //返回
}
//读时钟函数
void Read_RTC(void) //读取 日历
{
char i,j,k,m;
//SDA=1;
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_2,GPIO_PIN_2);
SysCtlDelay((SysCtlClockGet() / 3000));
//p=read_rtc_address; //地址传递
for(i=0;i<7;i++) //分7次读取 秒分时日月周年
{
l_tmpdate[i]=Read_Ds1302(read_rtc_address[i]);//Read_Ds1302(*p);
//p++;
/*j=l_tmpdate[i]>>4; //右移4位,将高4位取出,得到十位数
k=l_tmpdate[i]&0x0f; //舍去高位保留低4位,得到个位数*/
l_tmpdate[i]=l_tmpdate[i]/16*10+l_tmpdate[i]%16; //这个是网上看到的,对吗?
//return m;
}
}
//写时钟函数
void Set_RTC(void) //设定 日历
{
char i,tmp;//,*p;
Write_Ds1302(0x8E,0X00); //地址0x8E为控制字节 www.21ic.com/…/185861.html
/*for(i=0;i<7;i++) //char l_tmpdate[7]={0,0,12,6,12,11,20};//秒分时日月周年2011-07-14 12:00:00
{ //BCD处理
tmp=l_tmpdate[i]/10;
l_tmpdate[i]=l_tmpdate[i]%10;
l_tmpdate[i]=l_tmpdate[i]+tmp*16;
} //将每位l_tmpdate[i]的10进制数转化为16进制*/
//p=write_rtc_address; //传地址
for(i=0;i<7;i++) //7次写入 秒分时日月周年
{
Write_Ds1302(write_rtc_address[i],l_tmpdate[i]);
//p++;
}
Write_Ds1302(0x8E,0x80); //控制字节写完
}
// 初始化DS1302
void init_ds1302()
{
//RST=0;GPIO_PIN_3 均是E口
//SCK=0;GPIO_PIN_1
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1|GPIO_PIN_3,0);
Write_Ds1302(0x80,0x00);
Write_Ds1302(0x90,0x5c); //禁止充电
Write_Ds1302(0x8e,0x80); //写保护控制字,禁止写
}
main()
{init_ds1302();
Set_RTC();
while(1)
{
Read_RTC();
int i,j,k,l;
/*for(i=0;i<7;i++)
{
out_time[j]=l_tmpdate[i]/10;
j++;
out_time[j]=l_tmpdate[i]%10;
}*/
out_time[0]=l_tmpdate[0]%10; //将读出的数据转化为显示的数据
out_time[1]=l_tmpdate[0]/10;
out_time[2]=l_tmpdate[1]%10;
out_time[3]=l_tmpdate[1]/10;
out_time[4]=l_tmpdate[2]%10;
out_time[5]=l_tmpdate[2]/10;
out_time[6]=l_tmpdate[3]%10;
out_time[7]=l_tmpdate[3]/10;
out_time[8]=l_tmpdate[4]%10;
out_time[9]=l_tmpdate[4]/10;
for(k=9;k>=0;k–)
{
LCD_Draw_Char(number + out_time[k], 1, 10*(9-k));
}
}
}
}
xyz549040622:
固定显示5454545454,这是我以前碰到问题时的笔记,你可以修改下这两处
STC15W操作DS1302出现数值85的情况的解决办法
一般是两种情况引起的
1.DS1302_IO引脚的驱动能力不够。设置为准双向IO是不够的,需要加个上拉电阻到VCC,103就够了。DS1302_SCLK和DS1302_RST设置为推挽输出。
2.秒位的问题引起的,给秒位写数据0就好了。
unsigned char Second=Read1302(DS1302_SECOND);
if(Second&0x80) {DS1302_SetProtect(0); Write1302(DS1302_SECOND,0); }
JiaBo Chen:
回复 xyz549040622:
我在while函数中试了第二种方法,还是不行,一直显示54这个,第一个方法我在main函数中加了GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_1|GPIO_PIN_3,GPIO_STRENGTH_4MA,GPIO_PIN_TYPE_STD);现在就变成显示50了,至于加上拉电阻到vcc,这个能用软件实现吗?我不太懂这个,你能不能将详细代码写一下
JiaBo Chen:
回复 xyz549040622:
unsigned char hour=11,min=55,sec=55;
unsigned char number = '0';
unsigned char out_time[6]={0};
//奇数为读操作,偶数为写操作//写函数
void Write_Ds1302( char addr,char dat )
{char i,temp;//RST=0;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_4,0);SysCtlDelay((SysCtlClockGet() / 3000));//SCK=0;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,0);SysCtlDelay((SysCtlClockGet() / 3000));//RST=1;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_4,GPIO_PIN_4);SysCtlDelay((SysCtlClockGet() / 3000)*2);//启动for(i=8;i>0;i–){//SCLK=0;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,0);SysCtlDelay((SysCtlClockGet() / 3000));temp=addr;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_3,(temp&0x01));addr=addr<<1;//SCLK=1;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,GPIO_PIN_2);SysCtlDelay((SysCtlClockGet() / 3000));}for(i=8;i>0;i–){//SCLK=0;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,0);SysCtlDelay((SysCtlClockGet() / 3000));temp=dat;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_3,(temp&0x01));dat=dat<<1;//SCLK=1;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,GPIO_PIN_2);SysCtlDelay((SysCtlClockGet() / 3000));}//RST=0;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_4,0);
}//读出ds1302
char Read_Ds1302 ( char addr )
{unsigned char data_0 = 0;//最小位uint8_t temp,i,dat1,dat2;//RST=0;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_4,0);SysCtlDelay((SysCtlClockGet() / 3000));//SCK=0;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,0);SysCtlDelay((SysCtlClockGet() / 3000));//RST=1;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_4,GPIO_PIN_4);SysCtlDelay((SysCtlClockGet() / 3000)*2);GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,GPIO_PIN_3);for(i=8;i>0;i–){//SCK=0;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,0);SysCtlDelay((SysCtlClockGet() / 3000));temp=addr;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_3,(temp&0x01));addr=addr<<1;//SCK=1;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,GPIO_PIN_2);SysCtlDelay((SysCtlClockGet() / 3000));}GPIODirModeSet(GPIO_PORTB_BASE, GPIO_PIN_3,GPIO_DIR_MODE_HW);for(i=8;i>1;i–){data_0=GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_3);//SCLK=0;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,0);SysCtlDelay((SysCtlClockGet() / 3000));temp=data_0;temp=temp<<1;//SCLK=1;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,GPIO_PIN_2);SysCtlDelay((SysCtlClockGet() / 3000));}
//RST=0;GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_3,0);SysCtlDelay((SysCtlClockGet() / 3000));dat1=temp;dat2=dat1/16;dat1=dat1%16;dat1=dat1+dat2*10;return dat1;
}// 初始化DS1302
void init_ds1302()
{Write_Ds1302(0x8e,0x00); //不保护指令Write_Ds1302(0x80,0x55); //秒Write_Ds1302(0x82,0x55);//分Write_Ds1302(0x84,0x23);//时Write_Ds1302(0x90,0xa5); //打开充电Write_Ds1302(0x8e,0x80); //写保护控制字,禁止写
}
int main(void)
{SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_2|GPIO_PIN_4,GPIO_STRENGTH_8MA,GPIO_PIN_TYPE_STD);GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,GPIO_PIN_3);//初始化时钟模块init_ds1302();
// 使能LCDLCD_Enable();
// 初始化LCDLCD_Init();
// 清屏LCD_ScreenClr();
LCD_Draw_Char('T', 0, 0);LCD_Draw_Char('i', 0, 8);LCD_Draw_Char('m', 0, 16);LCD_Draw_Char('e', 0, 24);LCD_Draw_Char(':', 0, 32);
LCD_Draw_Char('S', 2, 0);LCD_Draw_Char('t', 2, 8);LCD_Draw_Char('e', 2, 16);LCD_Draw_Char('p', 2, 24);LCD_Draw_Char(':', 2, 32);
LCD_Draw_Char('0', 3, 0);LCD_Draw_Char('0', 3, 8);LCD_Draw_Char('0', 3, 16);LCD_Draw_Char('1', 3, 24);
while(1){unsigned char sec=Read_Ds1302(0x81);if(sec&0x80){Write_Ds1302(0x8e,0x00);Write_Ds1302(0x80,0);}sec = Read_Ds1302(0x81);min = Read_Ds1302(0x83);hour = Read_Ds1302(0x85);out_time[0]=hour/10; //将读出的数据转化为显示的数据out_time[1]=hour%10;out_time[2]=min/10;out_time[3]=min%10;out_time[4]=sec/10;out_time[5]=sec%10;LCD_Draw_Char(number + out_time[0], 1, 0);LCD_Draw_Char(number + out_time[1], 1, 8);LCD_Draw_Char(':', 1, 16);LCD_Draw_Char(number + out_time[2], 1, 24);LCD_Draw_Char(number + out_time[3], 1, 32);LCD_Draw_Char(':', 1, 40);LCD_Draw_Char(number + out_time[4], 1,48);LCD_Draw_Char(number + out_time[5], 1,56);}
}
我感觉那个代码有问题,这是我重新写的代码,但老是读出为0,我感觉函数还是有问题,就是不知道哪里错了,你能帮我看看吗