This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

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));
        }

    }
}
}

  • 固定显示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); }
  • 我在while函数中试了第二种方法,还是不行,一直显示54这个,第一个方法我在main函数中加了GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_1|GPIO_PIN_3,GPIO_STRENGTH_4MA,GPIO_PIN_TYPE_STD);现在就变成显示50了,至于加上拉电阻到vcc,这个能用软件实现吗?我不太懂这个,你能不能将详细代码写一下
  • 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();

    // 使能LCD
    LCD_Enable();

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