ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

基于STM32的SD2405ALPI-G代码

2019-05-28 10:40:11  阅读:259  来源: 互联网

标签:SD2405 代码 STM32 InitStructure SDA IIC GPIO void SD2405ALPI


  因项目需要RTC由原来的DS1302(这个芯片的代码还蛮多的,就不挂了)。更改为了SD2405ALPI-G,看网上类似的资源较少,与诸君分享一下,有不足之处也希望诸君指正。

  对于SD2405模块的资料可参见https://wenku.baidu.com/view/cbebaea1b0717fd5360cdc13.html。

  首先是IIC协议(资料也蛮多,但是挂一下代码,这个是自己验证过可以使用的,我也会在代码后面大致写一下为啥还有一些要注意的小小细节),

  

  1 void IIC_For_Init(void)              
  2 {
  3     GPIO_InitTypeDef  GPIO_InitStructure;       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
  4     GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);      
  5     
  6     GPIO_InitStructure.GPIO_Pin=IIC_SCL_PIN;
  7     GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  8     GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
  9     GPIO_Init(RCC_APB2Periph_GPIOB,&GPIO_InitStructure);
 10     
 11     GPIO_InitStructure.GPIO_Pin=IIC_SDA_PIN;
 12     GPIO_Init(RCC_APB2Periph_GPIOB,&GPIO_InitStructure);
 13     
 14     IIC_SCL=1;
 15     IIC_SDA=1;    
 16 }
 17 
 18 
 19 void SDA_OUT_For(void)
 20 {
 21     GPIO_InitTypeDef  GPIO_InitStructure;
 22     
 23     GPIO_InitStructure.GPIO_Pin=IIC_SDA_PIN;
 24     GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
 25     GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
 26     GPIO_Init(IIC_SDA_PORT,&GPIO_InitStructure);
 27 }
 28 
 29 
 30 void SDA_IN_For(void)
 31 {
 32     GPIO_InitTypeDef  GPIO_InitStructure;
 33     
 34     GPIO_InitStructure.GPIO_Pin=IIC_SDA_PIN;
 35     GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
 36     GPIO_Init(IIC_SDA_PORT,&GPIO_InitStructure);
 37 }
 38 
 39 
 40 void IIC_For_Start(void)                
 41 {
 42     
 43     SDA_OUT_For();     
 44     IIC_SDA=1;            
 45     IIC_SCL=1;
 46     delay_us(5);
 47      IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
 48     delay_us(6);
 49     IIC_SCL=0;
 50 }
 51 
 52 void IIC_For_Stop(void)              
 53 {
 54     SDA_OUT_For();
 55     IIC_SCL=0;
 56     IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
 57      IIC_SCL=1; 
 58     delay_us(6); 
 59     IIC_SDA=1;
 60     delay_us(6);                                   
 61 }
 62 
 63 u8 IIC_For_Wait_Ack(void)                 
 64 {
 65     u8 tempTime=0;
 66     
 67     IIC_SDA=1;
 68     delay_us(1);
 69     SDA_IN_For();               
 70     IIC_SCL=1;
 71     delay_us(1);     
 72     while(READ_SDA)
 73     {
 74         tempTime++;
 75         if(tempTime>250)
 76         {
 77             IIC_For_Stop();
 78             return 1;
 79         }
 80     }
 81     IIC_SCL=0;   
 82     return 0;  
 83 }
 84 
 85 void IIC_For_Ack(void)                    
 86 {
 87     IIC_SCL=0;
 88     SDA_OUT_For();
 89     IIC_SDA=0;
 90     delay_us(2);
 91     IIC_SCL=1;
 92     delay_us(5);
 93     IIC_SCL=0;
 94 }
 95 
 96         
 97 void IIC_For_NAck(void)            
 98 {
 99     IIC_SCL=0;
100     SDA_OUT_For();
101     IIC_SDA=1;
102     delay_us(2);
103     IIC_SCL=1;
104     delay_us(5);
105     IIC_SCL=0;
106 }    
107 
108       
109 void IIC_For_Send_Byte(u8 txd)            
110 {                       
111     u8 t;   
112         SDA_OUT_For();         
113     IIC_SCL=0;
114     for(t=0;t<8;t++)
115     {              
116         if((txd&0x80)>0) //0x80  1000 0000
117             IIC_SDA=1;
118         else
119             IIC_SDA=0;
120         txd<<=1;       
121         delay_us(2);  
122         IIC_SCL=1;
123         delay_us(2); 
124         IIC_SCL=0;    
125         delay_us(2);
126     }     
127 } 
128 
129 u8 IIC_For_Read_Byte(u8 ack)
130 {
131     u8 i,receive=0;
132     SDA_IN_For();
133     for(i=0;i<8;i++ )
134     {
135         IIC_SCL=0; 
136         delay_us(2);
137         IIC_SCL=1;
138         receive<<=1;
139         if(READ_SDA)receive++;   
140         delay_us(1); 
141     }                     
142     if (!ack)
143         IIC_For_NAck();
144     else
145         IIC_For_Ack(); 
146     return receive;
147 }

  需要注意的有几点:

  1、IIC_SDA及IIC_SCL,在这里我使用的是位带操作,https://www.cnblogs.com/leo0621/p/9494290.html,这位博友讲的超详细;

  2、关于第一行与第二行的代码:

    

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);    

    当时使用了JTAG的管脚(PB3/JTDO、PB4/JNTRST),而JTAG与SWD在默认情况下是开启的,需要关掉JTAG管脚并使其作为普通的IO口,这也是调试了半天才想到的一个问题,若不是使用JTAG,则只需要对RCC_APB2Periph_GPIOB进行使能即可,以免误伤;

  3、对于SDA_IN_For()和SDA_OUT_For(),首先此处的命名是为了避免重复(因为还有另一个IIC文件来进行AT24C02),初始化采用了分别设置的方法,OUT下为推挽输出,在IN下为上拉输入。在这里值得一提的是,如果在SDA对应的管脚有上拉电阻在,则可以在最开始的IO配置中,将SDA脚配置为浮空输入,不需要再分别设置SDA_IN_For()和SDA_OUT_For()两个函数。

 

  对于SD2405ALPI-G的函数如下:

 1 #include "sd2405_driver.h"
 2 
 3 u8 Time_Register[]={
 4     SD2405_ADDR_YEAR,
 5     SD2405_ADDR_MONTH,
 6     SD2405_ADDR_DAY,
 7     SD2405_ADDR_HOUR,
 8     SD2405_ADDR_MIN,
 9     SD2405_ADDR_SEC,
10     SD2405_ADDR_WEEK
11 };
12 
13 u8 Time_Init[]={
14     0x19,    //year   2019
15     0x05,    //month  5
16     0x27,    //day    27
17     0x12,    //hour   12
18     0x30,    //minute 30
19     0x59,    //second 59
20     0x06     //week   6
21 };
22 
23 void SD2405_Init(void)
24 {
25     IIC_For_Init();
26 }
27 
28 void SD2405_WriteOneByte(u8 WriteAddr , u8 Data)
29 {
30    IIC_For_Start();
31 
32    IIC_For_Send_Byte(0x64);
33    IIC_For_Wait_Ack();
34 
35    IIC_For_Send_Byte(WriteAddr);
36    IIC_For_Wait_Ack();
37 
38    IIC_For_Send_Byte(Data);
39    IIC_For_Wait_Ack();
40 
41    IIC_For_Stop();
42 
43    delay_ms(10);
44 }
45 
46 u8 SD2405_ReadOneByte(u8 ReadAddr)
47 {
48    u8 temp;
49 
50    IIC_For_Start();
51 
52    IIC_For_Send_Byte(0x64);
53    IIC_For_Wait_Ack();
54 
55    IIC_For_Send_Byte(ReadAddr);
56    IIC_For_Wait_Ack();
57 
58    IIC_For_Start();
59 
60    IIC_For_Send_Byte(0x65);
61    IIC_For_Wait_Ack();
62 
63    temp = IIC_For_Read_Byte(0);
64 
65    IIC_For_Stop();
66 
67    return temp;
68 }
69 
70 
71 void Write_On(void)
72 {
73    SD2405_WriteOneByte(SD2405_ADDR_CTR2,0x80);
74    SD2405_WriteOneByte(SD2405_ADDR_CTR1,0x84);
75 }
76 
77 void Write_Off(void)
78 {
79    SD2405_WriteOneByte(SD2405_ADDR_CTR1,0x00);
80    SD2405_WriteOneByte(SD2405_ADDR_CTR2,0x52);
81 }
82 
83 void SD2405_Time_Init(void)
84 {
85     u8 i = 0;
86     Write_On();
87     for(i=0;i<7;i++){
88         SD2405_WriteOneByte(Time_Register[i],Time_Init[i]);
89     }
90     Write_Off();
91 }
92 
93 void SD2405_Read_Time(void)
94 {
95     u8 i = 0;
96     for(i=0;i<7;i++){
97         Time_Init[i]=SD2405_ReadOneByte(Time_Register[i]);
98     }
99 }

  首先对于读写来说,0110001?,前7位为寻址字节,其中?表示可为1或0,当为0时为写,1时为读。当?为0时即为0x64,当?为1时为0x65;对于读写操作只需要符合IIC读写方式即可。需要注意的是,要进行Write_On和Write_Off的切换,即可参见说明书第8页中的说明,对于写允许的操作,先WRTC1为1再使WRTC2和WRTC3为1,故在Write_On中为0x80,0x84(应注意CTR1寄存器中有的是WRTC3位和WRTC2位,CTR2中有的是WRTC1位,两个寄存器是没按常理出牌的,不要写颠倒);而写禁止操作则需要先让WRTC2和WRTC3为0再让WRTC1为0,故分别为0x00和0x52。一定要先Write_On再写再Write_Off。

  在这里只是进行一个简单的写入并且不断读出并在OLED上进行显示的过程(当然OLED显示的代码没挂,主题还是SD2405嘛),对于报警、时间调整等更复杂的功能,还没做但是也期待与诸君有更深入的讨论。

标签:SD2405,代码,STM32,InitStructure,SDA,IIC,GPIO,void,SD2405ALPI
来源: https://www.cnblogs.com/CherylEEPassion19950804/p/10935706.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有