STM32上移植ds1307笔记

PS:网上关于ds1307的资料最多还是基于51等单片机的,和stm32上还是略有差别,代码是参考了http://www.openedv.com/posts/list/20167.htm 但是他的代码有一定错误,在我的设备上读不了数据,更别谈写数据了。

说明:此程序是控制IO口模拟i2c控制ds1307

关于ds1302的资料这里就不多说了,主要分析下代码。让各位入门的新手参考一下,附上代码的下载链接:http://download.csdn.net/detail/u012062785/8966015   为什么是csdn的下载链接呢?前段时间由于校园网的问题,好像把csdn给墙掉了,不得已搬家到博客园,虽然csdn好用一些,但是还是不准备再搬回去了,麻烦。。。额,废话太多了,下面进入正题

配置:

1 #define SDA_IN()  {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=8<<12;}
2 #define SDA_OUT() {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=3<<12;}
3 
4  
5 #define IIC_SCL    PBout(10) //SCL
6 #define IIC_SDA    PBout(11) //SDA     
7 #define READ_SDA   PBin(11)  //ÊäÈëSDA 

所以SCL线连接到stm32上的PB10,SDA线连接到stm32上的PB11上。注意上拉电阻什么的,这个请看ds1307的数据手册

读ds1307:

 1 u8 ds1307_Read(u8 ReadAddr)
 2 {                  
 3         u8 temp,dat;          
 4         int k;
 5         IIC_Start();  
 6         IIC_Send_Byte(0xd0);                   
 7         IIC_Send_Byte(ReadAddr);            
 8         IIC_Stop();                      //这里一定要重启IIC总线,否则会读错误               
 9     
10         IIC_Start(); 
11         IIC_Send_Byte(0xd1);       
12         if (IIC_Wait_Ack())
13                 return 0xff;
14         
15     temp = IIC_Read_Byte();                   
16     IIC_NAck();                       
17     IIC_Stop();                
18    
19         return temp;
20 }

读寄存器:

 1 u8 IIC_Read_Byte()
 2 {
 3         unsigned char i,receive=0;
 4         SDA_IN();
 5     for(i=0;i<7;i++)        //这里修改为7次,不然秒时针会一次递增2个单位
 6         {
 7       IIC_SCL=0;
 8       delay_us(2);
 9             IIC_SCL=1;
10       receive = receive<<1;
11       if(READ_SDA){
12                 receive++;
13             }
14             delay_us(1); 
15     }
16     return (receive);
17 }

写ds1307

 1 void ds1307_Write(u8 WriteAddr,u8 Data)
 2 {    
 3     u8 temp;
 4     
 5     temp=(Data/10*16)+(Data%10); //16进制转BCD    
 6     
 7     IIC_Start();  
 8     IIC_Send_Byte(0xd0);                9     //IIC_Wait_Ack();
10     IIC_Send_Byte(WriteAddr);        11     //IIC_Wait_Ack();                                                          
12     IIC_Send_Byte(temp);            13     //IIC_Wait_Ack();                   
14     IIC_Stop();                        
15     delay_us(10);     
16     
17 }
PS:这里理论上是需要加上应答位的,但是我加上就会超时得不到应答,如果不要,反而成功了!!这个问题有大神知道的话,希望您能给我留言,不甚感激

写寄存器:
 1 u8 IIC_Send_Byte(u8 txd)
 2 {                        
 3     u8 t;   
 4         SDA_OUT();
 5     for(t=0;t<8;t++)
 6     {              
 7             if((txd&0x80)>>7)
 8                 IIC_SDA=1;
 9             else
10                 IIC_SDA=0;
11             txd<<=1;       
12             delay_us(2);
13             IIC_SCL=1;
14             delay_us(4); 
15             IIC_SCL=0;
16     }     
17        
18         
19         SDA_IN();
20         delay_us(4);
21         IIC_SDA=1; 
22         //delay_us(2);
23         IIC_SCL=1;
24         delay_us(2); 
25         if (READ_SDA==1)
26         {
27             IIC_SCL=0; 
28             return 1;
29         }
30         else
31         {
32             IIC_SCL=0;
33             return 0;
34         }
35 }         

主要代码就差不多是这些了,如果还不太懂原理,可以下载完整源码参考。有大神觉得哪些写的不对的地方,还希望指导一下,谢谢~

总结:模拟i2c总线控制ds1307总的来说就是要注意ds1307的时序,这个也可以拓展到几乎所有字符设备吧,首先要理解设备的控制协议,然后开始一步一步操控。

原文地址:https://www.cnblogs.com/pngcui/p/4707113.html