OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 21345|回复: 13

stm32 驱动ds1307的程序问题

[复制链接]

3

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2013-8-20
在线时间
0 小时
发表于 2013-8-20 09:26:13 | 显示全部楼层 |阅读模式
我用1307写入 然后读出  用usart显示出来 但是这个东西能读出但是不能写入 求大神帮忙看看
我用1307写入 然后读出  用usart显示出来 但是这个东西能读出但是不能写入 求大神帮忙看看
不知道什么地方不对 请原子哥和大神指出 谢谢  刚学习不太会   谢谢
iic的头文件
#ifndef __MYIIC_H
#define __MYIIC_H
#include "sys.h"
//IO方向设置
#define SDA_IN()  {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=8<<12;}
#define SDA_OUT() {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=3<<12;}

//IO操作函数  
#define IIC_SCL    Bout(10) //SCL
#define IIC_SDA    Bout(11) //SDA  
#define READ_SDA   PBin(11)  //输入SDA 

//IIC所有操作函数
void IIC_Init(void);                //初始化IIC的IO口  
void IIC_Start(void); //发送IIC开始信号
void IIC_Stop(void);   //发送IIC停止信号
void IIC_Send_Byte(u8 txd); //IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack(void); //IIC等待ACK信号
void IIC_Ack(void); //IIC发送ACK信号
void IIC_NAck(void); //IIC不发送ACK信号

void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);  
#endif




iic.c文件


#include "myiic.h"
#include "delay.h"

void IIC_Init(void)
{     
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );
  
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11); //PG10,PG11 输出高
}
//产生IIC起始信号
void IIC_Start(void)
{
SDA_OUT();     //sda线输出
IIC_SDA=1;    
IIC_SCL=1;
delay_us(4);
  IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
delay_us(4);
IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
}  
//产生IIC停止信号
void IIC_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
  delay_us(4);
IIC_SCL=1; 
IIC_SDA=1;//发送I2C总线结束信号
delay_us(4);  
}
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN();      //SDA设置为输入  
IIC_SDA=1;
delay_us(1);   
IIC_SCL=1;
delay_us(1);  
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//时钟输出0   
return 0;  
//产生ACK应答
void IIC_Ack(void) //IIC_Ack();
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//不产生ACK应答    
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}     
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答  
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
SDA_OUT();    
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        //IIC_SDA=(txd&0x80)>>7;
if((txd&0x80)>>7)
IIC_SDA=1;
else
IIC_SDA=0;
txd<<=1;  
delay_us(2);     //对TEA5767这三个延时都是必须的
IIC_SCL=1;
delay_us(2); 
IIC_SCL=0;
delay_us(2);
    }  
}    
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
{
        IIC_SCL=0; 
        delay_us(2);
IIC_SCL=1;
        receive<<=1;
        if(READ_SDA)receive++;   
delay_us(1); 
    }  
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}

1307的头文件

#ifndef __shizhong_H
#define __shizhong_H
#include "sys.h"
void shizhong_init(void);
void shizhong_WriteOneByte(u8 WriteAddr,u8 DataToWrite);
u8 shizhong_ReadOneByte(u8 ReadAddr);
#endif
 


1307的c文件
#include "sys.h"
#include "myiic.h"
#include "delay.h" 
#include "shizhong.h"
#include "usart.h"
void shizhong_init(void)
{
IIC_Init();
}

//在时钟指定地址写入一个数据
//WriteAddr :写入数据的目的地址    
//DataToWrite:要写入的数据
void shizhong_WriteOneByte(u8 WriteAddr,u8 DataToWrite)
{
    u8 temp;
     //转BCD码再写入1307
    temp=(DataToWrite/10*16)+(DataToWrite%10); //十六进制数转换成BCD码数据          
    IIC_Start();  
    IIC_Send_Byte(0XD0);            //发送器件地址
    IIC_Wait_Ack();
    IIC_Send_Byte(WriteAddr);    //发送从地址的某个地址   
    IIC_Wait_Ack();     
    IIC_Send_Byte(temp);            //发送字节   
   // IIC_Wait_Ack();       
    IIC_Stop();             //产生一个停止条件 
    delay_ms(10);  



//在shizhong指定地址读出一个数据
//ReadAddr:开始读数的地址  
//返回值 :读到的数据
u8 shizhong_ReadOneByte(u8 ReadAddr)
{  
u8 temp,dat;        
    IIC_Start();  
IIC_Send_Byte(0XD0);   //发送从器件的地址
    IIC_Wait_Ack();     
IIC_Start();     
IIC_Send_Byte(0XD1);        //进入接收模式   
IIC_Wait_Ack();  
    temp=IIC_Read_Byte(ReadAddr);
    IIC_NAck();                //非应答
    IIC_Stop();                 //产生一个停止条件
                                // BCD转为16进制
    dat=(temp/16*10)+(temp%16);//BCD码转换成十六进制数   
return dat;
}


我用1307写入 然后读出  用usart显示出来 但是这个东西能读出但是不能写入 求大神帮忙看看

 
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "sys.h" 
#include "myiic.h"
   
u8 month,date,day,hour,minutes,seconds;
void paopao(void)
{
   
shizhong_WriteOneByte(0x00,0x02); 
        shizhong_WriteOneByte(0x01,0x04);
  shizhong_WriteOneByte(0x02,0x04);
shizhong_WriteOneByte(0x03,0x02);
        shizhong_WriteOneByte(0x04,0x04);
shizhong_WriteOneByte(0x05,0x04);    

 
  seconds=shizhong_ReadOneByte(0x00);
minutes=shizhong_ReadOneByte(0x01);
    hour=shizhong_ReadOneByte(0x02);
day=shizhong_ReadOneByte(0x03);
date=shizhong_ReadOneByte(0x04);
month=shizhong_ReadOneByte(0x05);  
}
 int main(void)
 {
 
delay_init();     //延时函数初始化  
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(9600);     //串口初始化为9600       
shizhong_init();  //时钟初始化
paopao();
  while(1)
{     
printf("month=%d\n",month); 
delay_ms(1000);
printf("date=%d\n",date);
delay_ms(5000); 
    printf("day=%d\n",day); 
delay_ms(5000);
printf("hour=%d\n",hour); 
delay_ms(5000);  
printf("minutes=%d\n",minutes);  
  delay_ms(5000);  
  printf("seconds=%d\n",seconds);
     delay_ms(5000);
 
  
   }
 }

我用1307写入 然后读出  用usart显示出来 但是这个东西能读出但是不能写入 求大神帮忙看看
谢谢大家啦  



 









































只要路对?不怕路远
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
2
金钱
2
注册时间
2019-5-17
在线时间
0 小时
发表于 2019-5-17 19:27:39 | 显示全部楼层
本帖最后由 q1319545092 于 2019-5-17 19:36 编辑

这段程序有问题
u8 shizhong_ReadOneByte(u8 ReadAddr)
{                                 
        u8 temp,dat;                                                                                                                                                            
    IIC_Start();  
        IIC_Send_Byte(0XD0);          //发送从器件的地址
    IIC_Wait_Ack();     
        IIC_Start();                    
        IIC_Send_Byte(0XD1);        //进入接收模式                          
        IIC_Wait_Ack();         
    temp=IIC_Read_Byte(ReadAddr);
    IIC_NAck();                       //非应答
    IIC_Stop();                 //产生一个停止条件
                                // BCD转为16进制
    dat=(temp/16*10)+(temp%16);//BCD码转换成十六进制数   
        return dat;
}

temp=IIC_Read_Byte(ReadAddr);这行错了,参数不是地址,看IIC_Read_Byte的定义
u8 IIC_Read_Byte(unsigned char ack)//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
改成这样:
        IIC_Start();
        IIC_Send_Byte(0xd0);
        IIC_Wait_Ack();
        IIC_Send_Byte(ReadAddr);
        IIC_Wait_Ack();
        IIC_Stop();
        delay_ms(2);//延时时间可以改短些
        IIC_Start();
        IIC_Send_Byte(0xd1);
        IIC_Wait_Ack();        
        temp = IIC_Read_Byte(0);
        IIC_Stop();
读取数据流程如下

回复 支持 1 反对 0

使用道具 举报

3

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2013-8-20
在线时间
0 小时
 楼主| 发表于 2013-8-20 10:34:14 | 显示全部楼层
大家帮帮忙 给看看呗 急用啊
只要路对?不怕路远
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2013-8-20 10:47:28 | 显示全部楼层
 
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
SDA_OUT();    
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        //IIC_SDA=(txd&0x80)>>7;
if((txd&0x80)>>7)
IIC_SDA=1;
else
IIC_SDA=0;
txd<<=1;  
delay_us(2);     //对TEA5767这三个延时都是必须的
IIC_SCL=1;
delay_us(2); 
IIC_SCL=0;
delay_us(2);
    }  
}
看了下别人的代码,这里貌似改为了8us延时。
你试试。

ds1307.rar

1.91 KB, 下载次数: 2051

我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

3

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2013-8-20
在线时间
0 小时
 楼主| 发表于 2013-8-20 11:45:55 | 显示全部楼层
还是不行那
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2013-8-20 12:43:26 | 显示全部楼层
回复【4楼】小布的梦:
---------------------------------
那你直接移植附件那个代码,这个代码别人说好用的。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

3

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2013-8-20
在线时间
0 小时
 楼主| 发表于 2013-8-20 14:03:27 | 显示全部楼层
奥 我移植一下试试 谢谢原子哥
只要路对?不怕路远
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
23
金钱
23
注册时间
2014-9-25
在线时间
0 小时
发表于 2015-1-20 09:38:09 | 显示全部楼层
{GPIOB->CRH&=0XFFFF0FFF;GPIO->CRH|=8<<12;}
线路检测、微机保护等。。。
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
23
金钱
23
注册时间
2014-9-25
在线时间
0 小时
发表于 2015-1-20 09:38:32 | 显示全部楼层
{GPIOB->CRH&=0XFFFF0FFF;GPIO->CRH|=8<<12;}该剧是何意
线路检测、微机保护等。。。
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
23
金钱
23
注册时间
2014-9-25
在线时间
0 小时
发表于 2015-1-20 09:39:23 | 显示全部楼层
求原子哥帮忙解释一下
线路检测、微机保护等。。。
回复 支持 反对

使用道具 举报

3

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
103
金钱
103
注册时间
2017-7-26
在线时间
29 小时
发表于 2017-8-22 15:11:42 | 显示全部楼层
小布的梦 发表于 2013-8-20 10:34
大家帮帮忙&nbsp;给看看呗&nbsp;急用啊

现在调试出来了吗?能不能分享一下代码,我最近在找相关资料。谢谢了!!!!!!!!!!
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2019-5-2
在线时间
4 小时
发表于 2019-8-9 11:04:27 | 显示全部楼层
程序上传分享一下呢,亲!
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2020-9-24
在线时间
9 小时
发表于 2020-9-25 21:55:09 | 显示全部楼层
志在四方 发表于 2015-1-20 09:38
**** 作者被禁止或删除 内容自动屏蔽 ****

可以查看STM32的不完全手册,首先GPIO->CRH&=0XFFFF0FFF,将要设置的位置零,然后GPIO->CRH|=8<<12;设置相应的模式。8<<12=1000(二进制)<<12=1000 0000 0000 0000
将PB11模式设置为1000,即为上拉/下拉输入
回复 支持 反对

使用道具 举报

4

主题

17

帖子

0

精华

新手上路

积分
43
金钱
43
注册时间
2022-4-21
在线时间
4 小时
发表于 2023-3-26 22:03:04 | 显示全部楼层
搞了一个1307 测试一下
看到 有人贴了一个 8<<12 位

我也有疑惑

顺便查了一下
没有错 捕获.PNG

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 13:38

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表