切换到宽版
  • 34047阅读
  • 35回复

[STM]《菜鸟练习》:STM32F103C8T6 + DS3231 + IIC OLED 时钟程序 [复制链接]

上一主题 下一主题
离线shenlan121
 

发帖
8833
M币
5400
专家
1
粉丝
29
只看楼主 倒序阅读 我要置顶 楼主  发表于: 2017-11-30
前段时间在公司找出几块PCB板,做工还是很精致的,是原来一款产品上的红外原理触摸控制板,就是下图这块板子。现在这款产品早就不做了,就剩这几块板子,寻思着这板子有没有可以利用的剩余价值。

然后经过研究对比发现中间的48脚芯片其实就是一个STM32F103C8T6的单片机,而且上面有USB接口,USB的左边是SWD 下载接口,板子的反面有几个测试点是引出的GPIO 口。于是拿了一块板子经过一番改造变成下面这样子

连上DS3231模块和OLED 屏,用来练习写一个时钟程序。这两个模块都是I2C连接,挂在I2C总线上,两个GPIO 口就行了,I2C通信协议使用软件模拟。



程序主要参考抄写网上的,有自己的理解、整理,主要是整理成模块化,方便调试,以及以后的移植。以下贴出部分程序以及工程文件



i2c_soft.h
  1. #ifndef __I2C_SOFT_H  
  2. #define __I2C_SOFT_H  
  3. #include "sys.h"    
  4. #define SCL_PIN        GPIO_Pin_10  //板上第11针
  5. #define SDA_PIN        GPIO_Pin_12  //板上第17针
  6. #define SCL_PORT       GPIOB  
  7. #define SDA_PORT       GPIOB  
  8. #define SCL_RCC_CLOCK  RCC_APB2Periph_GPIOB  
  9. #define SDA_RCC_CLOCK  RCC_APB2Periph_GPIOB  
  10.       
  11. #define SCL_H         GPIOB->BSRR = GPIO_Pin_10  
  12. #define SCL_L         GPIOB->BRR  = GPIO_Pin_10  
  13.         
  14. #define SDA_H         GPIOB->BSRR = GPIO_Pin_12  
  15. #define SDA_L         GPIOB->BRR  = GPIO_Pin_12  
  16.       
  17. #define SCL_read      GPIOB->IDR  & GPIO_Pin_10  
  18. #define SDA_read      GPIOB->IDR  & GPIO_Pin_12  
  19.       
  20. //#define I2C_PageSize  8  //24C02每页8字节  
  21. void I2C_GPIO_Config(void);
  22. void I2C_Start(void);
  23. void I2C_Stop(void);
  24. void I2C_Ack(void);
  25. void I2C_NoAck(void);
  26. u8       I2C_WaitAck(void);
  27. void I2C_SendByte(u8 SendByte);
  28. u8    I2C_ReceiveByte(void);
  29. //bool I2C_WriteByte(u8 SendByte, u16 WriteAddress, u8 DeviceAddress);  
  30. //bool I2C_BufferWrite(u8* pBuffer, u8 length, u16 WriteAddress, u8 DeviceAddress);  
  31. //void I2C_PageWrite(u8* pBuffer, u8 length, u16 WriteAddress, u8 DeviceAddress);  
  32. //bool I2C_ReadByte(u8* pBuffer, u8 length, u16 ReadAddress, u8 DeviceAddress);  
  33. //void I2C_Test(void);  
  34.       
  35. #endif


i2c_soft.c
  1. #include "i2c_soft.h"
  2. void I2C_GPIO_Config(void)  
  3. {  
  4.     GPIO_InitTypeDef  GPIO_InitStructure;  
  5.           
  6.     RCC_APB2PeriphClockCmd(SCL_RCC_CLOCK | SDA_RCC_CLOCK ,ENABLE);  
  7.           
  8.     //初始化SCL管脚  
  9.     GPIO_InitStructure.GPIO_Pin =  SCL_PIN;  
  10.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  11.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;    
  12.     GPIO_Init(SCL_PORT, &GPIO_InitStructure);  
  13.           
  14.     //初始化SDA管脚  
  15.     GPIO_InitStructure.GPIO_Pin =  SDA_PIN;  
  16.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  17.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  
  18.     GPIO_Init(SDA_PORT, &GPIO_InitStructure);  
  19. }
  20. /**************************************************************************  
  21. * 函数名: void I2C_delay(void)
  22. * 描述  : 短暂延时
  23. * 输入  : 无
  24. * 输出  : 无
  25. * 说明  : 内部定义的i可以优化速度,经测试最低到5还能写入
  26. ***************************************************************************/  
  27. static void I2C_delay(void)  
  28. {    
  29.     u8 i=5;  
  30.     while(i)  
  31.     {  
  32.         i--;  
  33.     }  
  34. }
  35. /**************************************************************************
  36. * 函数名: void I2C_Start(void)
  37. * 描述  : 起始信号
  38. * 输入  : 无
  39. * 输出  : 无
  40. * 说明  :  
  41. ***************************************************************************/
  42. void I2C_Start(void)
  43. {
  44.     SCL_H;    I2C_delay();
  45.     SDA_H;    I2C_delay();
  46.     SDA_L;    I2C_delay();
  47.     SCL_L;    I2C_delay();
  48. }
  49. /**************************************************************************
  50. * 函数名: I2C_Stop(void)
  51. * 描述  : 终止信号
  52. * 输入  : 无
  53. * 输出  : 无
  54. * 说明  :  
  55. ***************************************************************************/
  56. void I2C_Stop(void)
  57. {
  58.     SDA_L;    I2C_delay();
  59.     SCL_H;    I2C_delay();
  60.     SDA_H;    I2C_delay();
  61. }
  62. /**************************************************************************
  63. * 函数名: void I2C_Ack(void)
  64. * 描述  : 应答信号
  65. * 输入  : 无
  66. * 输出  : 无
  67. * 说明  :  
  68. ***************************************************************************/
  69. void I2C_Ack(void)  
  70. {    
  71.     SCL_L;  I2C_delay();  
  72.     SDA_L;  I2C_delay();  
  73.     SCL_H;  I2C_delay();  
  74.     SCL_L;  I2C_delay();  
  75. }
  76. /**************************************************************************
  77. * 函数名: void I2C_NoAck(void)
  78. * 描述  : 无应答信号
  79. * 输入  : 无
  80. * 输出  : 无
  81. * 说明  :  
  82. ***************************************************************************/
  83. void I2C_NoAck(void)  
  84. {    
  85.     SCL_L;  I2C_delay();  
  86.     SDA_H;  I2C_delay();  
  87.     SCL_H;  I2C_delay();  
  88.     SCL_L;  I2C_delay();  
  89. }  
  90. /**************************************************************************
  91. * 函数名: u8 I2C_WaitAck(void)
  92. * 描述  : 等待应答信号
  93. * 输入  : 无
  94. * 输出  : TRUE : 有应答
  95.            FALSE : 无应答
  96. * 说明  :  
  97. ***************************************************************************/
  98. u8 I2C_WaitAck(void)    
  99. {  
  100.     u8 ucErrTime=0;
  101.     SCL_L;  I2C_delay();  
  102.     SDA_H;  I2C_delay();  
  103.     SCL_H;  I2C_delay();  
  104.     while(SDA_read)  
  105.     {  
  106.         ucErrTime++;
  107.         if(ucErrTime>250)
  108.         {
  109.             I2C_Stop();
  110.             return 0;
  111.         }
  112.     }  
  113.     SCL_L;  
  114.     return 1;  
  115. }  
  116. /**************************************************************************  
  117. * 函数名: void I2C_SendByte(u8 SendByte)  
  118. * 描述  : 发送一个字节
  119. * 输入  : SendByte : 字节数据
  120. * 输出  : 无
  121. * 说明  : 数据从高位到低位
  122. ***************************************************************************/
  123. void I2C_SendByte(u8 SendByte)  
  124. {  
  125.     u8 i=8;  
  126.     while(i--)  
  127.     {  
  128.         SCL_L;  
  129.         I2C_delay();
  130.         
  131.         if(SendByte & 0x80)  
  132.             SDA_H;    
  133.         else  
  134.             SDA_L;    
  135.         SendByte<<=1;  
  136.         I2C_delay();
  137.         
  138.         SCL_H;  
  139.         I2C_delay();  
  140.     }  
  141.     SCL_L;  
  142. }
  143. /**************************************************************************
  144. * 函数名: u8 I2C_ReceiveByte(void)  
  145. * 描述  : 读取一个字节
  146. * 输入  : 无  
  147. * 输出  : 字节数据
  148. * 说明  : ReceiveByte : 数据从高位到低位
  149. ***************************************************************************/
  150. u8 I2C_ReceiveByte(void)    
  151. {  
  152.     u8 i=8;  
  153.     u8 ReceiveByte=0;  
  154.           
  155.     SDA_H;                
  156.     while(i--)  
  157.     {  
  158.         ReceiveByte<<=1;        
  159.         SCL_L;  
  160.         I2C_delay();  
  161.         SCL_H;
  162.         I2C_delay();      
  163.         if(SDA_read)  
  164.         {  
  165.             ReceiveByte|=0x01;  
  166.         }  
  167.     }  
  168.     SCL_L;  
  169.     return ReceiveByte;  
  170. }


DS3231.h
  1. #ifndef __DS3231_H__
  2. #define __DS3231_H__
  3. #include "sys.h"
  4. typedef struct
  5. {
  6.     u8    hour;
  7.     u8    min;
  8.     u8    sec;            
  9.     u32 w_year;
  10.     u8  w_month;
  11.     u8  w_date;
  12.     u8  week;        
  13.     u8    temper_H;
  14.     u8    temper_L;
  15. }Calendar_OBJ;
  16. extern Calendar_OBJ calendar;    //日历结构体
  17. extern u8 const mon_table[12];    //月份日期数据表
  18. void DS3231_Init(void);
  19. void Get_DS3231_Time(void);      
  20. //u8 RTC_Get_Week(u16 year,u8 month,u8 day);
  21. void Set_DS3231_Time(u8 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec,u8 week);//设置时间    
  22. #endif


DS3231.c
  1. #include "DS3231.h"
  2. #include "i2c_soft.h"
  3. #include "delay.h"
  4. Calendar_OBJ calendar;
  5. #define DS3231_WriteAddress        0xD0  
  6. #define DS3231_ReadAddress        0xD1
  7. u8 BCD2HEX(u8 val)
  8. {
  9.     u8 i;
  10.     i= val&0x0f;
  11.     val >>= 4;
  12.     val &= 0x0f;
  13.     val *= 10;
  14.     i += val;
  15.     
  16.     return i;
  17. }
  18. u16 B_BCD(u8 val)
  19. {
  20.     u8 i,j,k;
  21.     i=val/10;
  22.     j=val%10;
  23.     k=j+(i<<4);
  24.     return k;
  25. }
  26. void DS3231_WR_Byte(u8 addr,u8 bytedata)
  27. {
  28.     I2C_Start();
  29.     I2C_SendByte(DS3231_WriteAddress);
  30.     I2C_WaitAck();
  31.     I2C_SendByte(addr);
  32.     I2C_WaitAck();
  33.     I2C_SendByte(bytedata);
  34.     I2C_WaitAck();
  35.     I2C_Stop();
  36. }    
  37. u8 DS3231_RD_Byte(u8 addr)
  38. {
  39.     u8 Dat=0;
  40.   
  41.     I2C_Start();
  42.     I2C_SendByte(DS3231_WriteAddress);
  43.     I2C_WaitAck();
  44.     I2C_SendByte(addr);
  45.     I2C_WaitAck();
  46.     I2C_Start();
  47.     I2C_SendByte(DS3231_ReadAddress);
  48.     I2C_WaitAck();
  49.     Dat=I2C_ReceiveByte();
  50.     I2C_Stop();
  51.     
  52.     return Dat;
  53. }
  54. void DS3231_Init(void)
  55. {
  56.     I2C_GPIO_Config();
  57.     DS3231_WR_Byte(0x0e,0);
  58.     delay_ms(2);
  59.     DS3231_WR_Byte(0x0f,0x0);
  60.     delay_ms(2);
  61. }
  62. void Set_DS3231_Time(u8 yea,u8 mon,u8 da,u8 hou,u8 min,u8 sec,u8 week)
  63. {
  64.     u8 temp=0;
  65.   
  66.     temp=B_BCD(yea);
  67.     DS3231_WR_Byte(0x06,temp);
  68.   
  69.     temp=B_BCD(mon);
  70.     DS3231_WR_Byte(0x05,temp);
  71.   
  72.     temp=B_BCD(da);
  73.     DS3231_WR_Byte(0x04,temp);
  74.   
  75.     temp=B_BCD(hou);
  76.     DS3231_WR_Byte(0x02,temp);
  77.   
  78.     temp=B_BCD(min);
  79.     DS3231_WR_Byte(0x01,temp);
  80.   
  81.     temp=B_BCD(sec);
  82.     DS3231_WR_Byte(0x00,temp);
  83.     
  84.     temp=B_BCD(week);
  85.     DS3231_WR_Byte(0x03,temp);
  86. }
  87. void Get_DS3231_Time(void)
  88. {
  89.     calendar.w_year=DS3231_RD_Byte(0x06);  
  90.     calendar.w_year=BCD2HEX(calendar.w_year);
  91.     calendar.w_month=DS3231_RD_Byte(0x05);
  92.     calendar.w_month=BCD2HEX(calendar.w_month);
  93.     calendar.w_date=DS3231_RD_Byte(0x04);  
  94.     calendar.w_date=BCD2HEX(calendar.w_date);
  95.     
  96.     calendar.hour=DS3231_RD_Byte(0x02);
  97.     calendar.hour&=0x3f;                  
  98.     calendar.hour=BCD2HEX(calendar.hour);
  99.     calendar.min=DS3231_RD_Byte(0x01);
  100.     calendar.min=BCD2HEX(calendar.min);
  101.     calendar.sec=DS3231_RD_Byte(0x00);
  102.     calendar.sec=BCD2HEX(calendar.sec);
  103.     
  104.     calendar.week=DS3231_RD_Byte(0x03);
  105.     calendar.week=BCD2HEX(calendar.week);
  106.     
  107.     DS3231_WR_Byte(0x0e,0x20);
  108.     calendar.temper_H=DS3231_RD_Byte(0x11);
  109.     calendar.temper_L=(DS3231_RD_Byte(0x12)>>6)*25;
  110. }






[ 此帖被shenlan121在2017-12-01 19:42重新编辑 ]
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共1条打赏M币+20
q562379863 M币 +20 写的很好,参考了 2019-03-06
离线kygggg

发帖
8912
M币
6577
专家
9
粉丝
50
只看该作者 1楼 发表于: 2017-12-01
请登录后查看
离线德西电子

发帖
76
M币
-356
专家
1
粉丝
6
只看该作者 2楼 发表于: 2017-12-01
离线cao57508

发帖
2265
M币
3657
专家
9
粉丝
85
只看该作者 3楼 发表于: 2017-12-01
请登录后查看
离线shenlan121

发帖
8833
M币
5400
专家
1
粉丝
29
只看该作者 4楼 发表于: 2017-12-01
回 德西电子 的帖子
请登录后查看
离线2545889167

发帖
13268
M币
20754
专家
302
粉丝
4860
只看该作者 5楼 发表于: 2017-12-01
请登录后查看
离线shenlan121

发帖
8833
M币
5400
专家
1
粉丝
29
只看该作者 6楼 发表于: 2017-12-01
回 2545889167 的帖子
请登录后查看
离线清泥
发帖
6
M币
423
专家
0
粉丝
1
只看该作者 7楼 发表于: 2017-12-18
请登录后查看
离线清泥
发帖
6
M币
423
专家
0
粉丝
1
只看该作者 8楼 发表于: 2017-12-26
请登录后查看
离线清泥
发帖
6
M币
423
专家
0
粉丝
1
只看该作者 9楼 发表于: 2017-12-26
请登录后查看
快速回复
限80 字节
温馨提示:所有技术区严禁灌水,“沙发”“顶”字样;禁止广告贴;以免被删除
 
上一个 下一个