TI中文支持网
TI专业的中文技术问题搜集分享网站

TM4C123GXL与ds1302芯片

从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,我感觉函数还是有问题,就是不知道哪里错了,你能帮我看看吗

赞(0)
未经允许不得转载:TI中文支持网 » TM4C123GXL与ds1302芯片
分享到: 更多 (0)