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的時序,這個也可以拓展到幾乎所有字符設備吧,首先要理解設備的控制協議,然后開始一步一步操控。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM