STM8S驱动DS1302

2019-07-19 20:32发布

代码是自己参考普中科技51驱动写的,时序什么检查了很多遍,基本上都是一样的,但是在oled上显示总是数据全是0,下面是我的代码,大神帮帮忙,找找问题在哪。
头文件代码
#ifndef __DS1302_H_
#define __DS1302_H_
#include "stm8s.h"
extern unsigned char TIME[7]; //加入全局变量
#define DS1302_RST  GPIO_PIN_1 //定
#define DS1302_SCLK GPIO_PIN_2 //定
#define DS1302_DSIO GPIO_PIN_3
#define GPIO_DS1302 GPIOA    //定义要使用的端口A
#define DS1302_RST_OUT   GPIO_Init(GPIO_DS1302, DS1302_RST, GPIO_MODE_OUT_PP_HIGH_SLOW)
#define DS1302_DSIO_OUT  GPIO_Init(GPIO_DS1302, DS1302_DSIO, GPIO_MODE_OUT_PP_HIGH_SLOW) //高速推挽输出高电平
#define DS1302_DSIO_IN   GPIO_Init(GPIO_DS1302, DS1302_DSIO, GPIO_MODE_IN_PU_NO_IT) //上拉输入无中断功能
#define DS1302_SCLK_OUT  GPIO_Init(GPIO_DS1302, DS1302_SCLK, GPIO_MODE_OUT_PP_HIGH_SLOW) //高速推挽输出高电平
#define DS1302_RST_H GPIO_WriteHigh(GPIO_DS1302,DS1302_RST)  //置指定端口位为高电平,该端口必须配置为输出
#define DS1302_RST_L GPIO_WriteLow(GPIO_DS1302,DS1302_RST)   //置指定端口位为低电平,该端口必须配置为输出
#define DS1302_SCLK_H GPIO_WriteHigh(GPIO_DS1302,DS1302_SCLK)  //置指定端口位为高电平,该端口必须配置为输出
#define DS1302_SCLK_L GPIO_WriteLow(GPIO_DS1302,DS1302_SCLK)   //置指定端口位为低电平,该端口必须配置为输出
#define DS1302_DSIO_H GPIO_WriteHigh(GPIO_DS1302,DS1302_DSIO)  //置指定端口位为高电平,该端口必须配置为输出
#define DS1302_DSIO_L GPIO_WriteLow(GPIO_DS1302,DS1302_DSIO)   //置指定端口位为低电平,该端口必须配置为输出
//---定义全局函数---//
void Ds1302Write_byte(unsigned char dat);
//void Ds1302_Init(void);
void Ds1302Write(unsigned char addr, unsigned char dat);
unsigned char Ds1302Read(unsigned char addr);
void Ds1302Init();
void Ds1302ReadTime();
//---加入全局变量--//
#endif


源文件代码
#include "pbdata.h"
unsigned char time_data[7]={14,6,5,31,8,00,00};
unsigned char write_add[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};
unsigned char read_add[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};
unsigned char TIME[7] = {0x13, 0x02, 0x01, 0x01, 0x12, 0, 0};
/********************
DS1302 写字节函数
******************/
void Ds1302Write_byte(unsigned char dat)
{
  unsigned char i;
  DS1302_DSIO_OUT;
  for(i=0;i<8;i++)
  {
        
       if((dat&0x01)>0) //0x01  0000 0001
          DS1302_DSIO_H;
       else
          DS1302_DSIO_L;
        dat>>=1;
        DS1302_SCLK_H;
        delay_us(5);
        DS1302_SCLK_L;
        delay_us(5);
  }
  
}
/*******************************************************************************
* 函 数 名         : Ds1302Write
* 函数功能         : 向DS1302命令(地址+数据)
* 输    入         : addr,dat
* 输    出         : 无
*******************************************************************************/
void Ds1302Write(unsigned char addr, unsigned char dat)
{
        DS1302_DSIO_OUT;
DS1302_RST_L;
  delay_us(1);
DS1302_SCLK_L;//先将SCLK置低电平。
delay_us(1);
DS1302_RST_H; //然后将RST(CE)置高电平。
delay_us(1);
        Ds1302Write_byte(addr);
        Ds1302Write_byte(dat);
        DS1302_RST_L;
        delay_us(1);
      //  DS1302_DSIO_H;
      // DS1302_SCLK_H;
}
/*******************************************************************************
* 函 数 名         : Ds1302Read
* 函数功能     : 读取一个地址的数据
* 输    入         : addr
* 输    出         : dat
*******************************************************************************/
unsigned char Ds1302Read(unsigned char addr)
{
  unsigned char n,dat1,dat=0;
  DS1302_RST_L;
  delay_us(1);
  DS1302_SCLK_L;
  delay_us(1);
  DS1302_RST_H;
  delay_us(1);
  Ds1302Write_byte(addr);
  delay_us(1);
  DS1302_DSIO_IN;
  for(n=0;n<8;n++)
  {
   // DS1302_SCLK_L;
     if(GPIO_ReadInputPin(GPIO_DS1302, DS1302_DSIO)==1)
       dat1=1;//从最低位开始接收
     else
       dat1=0;
     dat = (dat>>1) | (dat1<<7);
     DS1302_SCLK_H;
     delay_us(1);
     DS1302_SCLK_L;
     delay_us(1);
  }
DS1302_RST_L;
delay_us(1); //以下为DS1302复位的稳定时间,必须的。
DS1302_SCLK_H;
delay_us(1);
      //  DS1302_SCLK_H;
        DS1302_DSIO_OUT;
DS1302_DSIO_H;
        delay_us(1);
return dat;
}
/*******************************************************************************
* 函 数 名         : Ds1302Init
* 函数功能     : 初始化DS1302.
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Ds1302Init()
{
unsigned char i,j;
        DS1302_RST_OUT;
        DS1302_DSIO_OUT;
        DS1302_SCLK_OUT;
      //  Ds1302_Init();
         for(i=0;i<7;i++)
          {
            j=time_data[i]/10;
            time_data[i]=time_data[i]%10;
            time_data[i]=time_data[i]+j*16;
           }
Ds1302Write(0x8E,0X00);   //禁止写保护,就是关闭写保护功能
  for(i=0;i<7;i++)
          {
            Ds1302Write(write_add[i],time_data[i]);
           }
Ds1302Write(0x8E,0x80);   //打开写保护功能
}
/*******************************************************************************
* 函 数 名         : Ds1302ReadTime
* 函数功能     : 读取时钟信息
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Ds1302ReadTime()
{
unsigned char n;
for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年
{
  TIME[n] = Ds1302Read(read_add[n]);
}
  
}
主函数
#include "pbdata.h"
//unsigned char TIME[7]; //加入全局变量
void BSP_Configuration(void);
int main(void)
{
  BSP_Configuration();
  OLED_CLS();
  while(1)
  {
      Ds1302ReadTime();
      OLED_ShowNum(2,2,TIME[0]/16);          //分
      OLED_ShowNum(10,2,TIME[0]%16/10);
      OLED_ShowNum(18,2,TIME[0]%16%10);
      
      OLED_ShowNum(2+26,2,TIME[1]/16);          //分
      OLED_ShowNum(10+26,2,TIME[1]%16/10);
      OLED_ShowNum(18+26,2,TIME[1]%16%10);

      OLED_ShowNum(2+26+26,2,TIME[2]/16);          //分
      OLED_ShowNum(10+26+26,2,TIME[2]%16/10);
      OLED_ShowNum(18+26+26,2,TIME[2]%16%10);
      delay_ms(100);
  }
}
void BSP_Configuration(void)
{
  //开启内部始终1分频 16mhz
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
  I2C_Config();
  OLED_Init();
  Ds1302Init();
}
/*断言函数:再编程过程中为程序提供参数检查*/
#ifdef USE_FULL_ASSERT
void assert_failed(u8*file,u32 line)
{
  while(1)
  {
  }
}
#endif
内容大概就是这些,感觉都是对的啊

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
9条回答
正点原子
1楼-- · 2019-07-20 12:19
帮顶
东方三毒
2楼-- · 2019-07-20 15:12
读一个字节的时序写错了
东方三毒
3楼-- · 2019-07-20 17:45
 精彩回答 2  元偷偷看……

一周热门 更多>