[活动专区] 【AT-START-F405测评】4.I2C应用实现温湿度表

[复制链接]
 楼主| yuyy1989 发表于 2024-4-27 16:03 | 显示全部楼层 |阅读模式
首先来配置I2C,在AT32 Work Bench中开启I2C1,这里可以直接设置I2C的各项参数
微信截图_20240427154453.png
自动分配的IO是PC0和PC1
微信截图_20240427154504.png
生成代码后添加I2C读写方法,可以考i2c_application_library来实现

  1. #include "yuyy_hard_iic.h"

  2. #define AT32I2C_TIMEOUT 0xFFFF

  3. void YUYY_HARDIIC_ResetCtrl2Register(i2c_type *iicx)
  4. {
  5.   iicx->ctrl2_bit.saddr     = 0;
  6.   iicx->ctrl2_bit.readh10   = 0;
  7.   iicx->ctrl2_bit.cnt       = 0;
  8.   iicx->ctrl2_bit.rlden     = 0;
  9.   iicx->ctrl2_bit.dir       = 0;
  10. }

  11. uint8_t YUYY_HARDIIC_WaitFlag(i2c_type *iicx,uint32_t flag,flag_status status)
  12. {
  13.     uint16_t timeout = AT32I2C_TIMEOUT;
  14.     while(i2c_flag_get(iicx, flag) != status)
  15.     {
  16.         timeout -= 1;
  17.         if(timeout == 0)
  18.             return 1;
  19.     }
  20.     return 0;
  21. }

  22. uint8_t YUYY_HARDIIC_MasterSendStop(i2c_type *iicx)
  23. {
  24.     i2c_stop_generate(iicx);
  25.     if(YUYY_HARDIIC_WaitFlag(iicx,I2C_STOPF_FLAG,SET))
  26.         return 6;
  27.     i2c_flag_clear(iicx, I2C_STOPF_FLAG);
  28.     return 0;
  29. }

  30. uint8_t YUYY_HARDIIC_MasterSendStart(i2c_type *iicx,uint8_t devaddr,i2c_start_mode_type startmode,i2c_reload_stop_mode_type stopmode,uint8_t datalen)
  31. {
  32.     if(startmode != I2C_WITHOUT_START && YUYY_HARDIIC_WaitFlag(iicx,I2C_BUSYF_FLAG,RESET))
  33.         return 1;
  34.     i2c_transmit_set(iicx, devaddr<<1, datalen, stopmode, startmode);
  35.     return 0;
  36. }

  37. uint8_t YUYY_HARDIIC_SendDatas(i2c_type *iicx,uint8_t *datas,uint8_t datalen)
  38. {
  39.     uint8_t i=0;
  40.     while(i<datalen)
  41.     {
  42.         if(YUYY_HARDIIC_WaitFlag(iicx,I2C_TDIS_FLAG,SET))
  43.         {
  44.             if(i2c_flag_get(iicx, I2C_ACKFAIL_FLAG) != RESET)
  45.             {
  46.                 i2c_flag_clear(iicx, I2C_ACKFAIL_FLAG);
  47.                 return 3;
  48.             }
  49.             YUYY_HARDIIC_MasterSendStop(iicx);
  50.             return 2;
  51.         }
  52.         if(i2c_flag_get(iicx, I2C_ACKFAIL_FLAG) != RESET)
  53.         {
  54.             i2c_flag_clear(iicx, I2C_ACKFAIL_FLAG);
  55.             return 3;
  56.         }
  57.         i2c_data_send(iicx, datas[i]);
  58.         i += 1;
  59.     }
  60.     return 0;
  61. }

  62. uint8_t YUYY_HARDIIC_ReadDatas(i2c_type *iicx,uint8_t *datas,uint8_t datalen)
  63. {
  64.     uint8_t i=0;
  65.     while(i<datalen)
  66.     {
  67.         if(YUYY_HARDIIC_WaitFlag(iicx,I2C_RDBF_FLAG,SET))
  68.         {
  69.             if(i2c_flag_get(iicx, I2C_ACKFAIL_FLAG) != RESET)
  70.             {
  71.                 i2c_flag_clear(iicx, I2C_ACKFAIL_FLAG);
  72.                 return 3;
  73.             }
  74.             YUYY_HARDIIC_MasterSendStop(iicx);
  75.             return 2;
  76.         }
  77.         datas[i] = i2c_data_receive(iicx);
  78.         i += 1;
  79.     }
  80.     return 0;
  81. }

  82. uint8_t YUYY_HARDIIC_MasterSendDatasWithStartStop(i2c_type *iicx,uint8_t devaddr,uint8_t startstop,uint8_t *datas,uint16_t datalen)
  83. {
  84.     uint8_t err = 0;
  85.     if(!iicx)
  86.         return 1;
  87.     i2c_start_mode_type startmode = I2C_WITHOUT_START;
  88.     i2c_reload_stop_mode_type stopmode = I2C_RELOAD_MODE;
  89.     if(startstop & YUYY_IIC_SEND_START)
  90.         startmode = I2C_GEN_START_WRITE;
  91.     if(startstop & YUYY_IIC_SEND_STOP)
  92.         stopmode = I2C_SOFT_STOP_MODE;
  93.     err = YUYY_HARDIIC_MasterSendStart(iicx,devaddr,startmode,stopmode,datalen);
  94.     if(err == 0)
  95.         err = YUYY_HARDIIC_SendDatas(iicx,datas,datalen);
  96.     if(stopmode == I2C_SOFT_STOP_MODE)
  97.     {
  98.         if(err == 0)
  99.             err = YUYY_HARDIIC_MasterSendStop(iicx);
  100.         if(err != 0)
  101.             YUYY_HARDIIC_ResetCtrl2Register(iicx);
  102.     }
  103.     return err;
  104. }
  105. uint8_t YUYY_HARDIIC_MasterReadDatasWithStartStop(i2c_type *iicx,uint8_t devaddr,uint8_t startstop,uint8_t *datas,uint16_t datalen)
  106. {
  107.     uint8_t err = 0;
  108.     if(!iicx)
  109.         return 1;
  110.     i2c_start_mode_type startmode = I2C_WITHOUT_START;
  111.     i2c_reload_stop_mode_type stopmode = I2C_RELOAD_MODE;
  112.     if(startstop & YUYY_IIC_SEND_START)
  113.         startmode = I2C_GEN_START_READ;
  114.     if(startstop & YUYY_IIC_SEND_STOP)
  115.         stopmode = I2C_SOFT_STOP_MODE;
  116.     err = YUYY_HARDIIC_MasterSendStart(iicx,devaddr,startmode,stopmode,datalen);
  117.     if(err == 0)
  118.         err = YUYY_HARDIIC_ReadDatas(iicx,datas,datalen);
  119.     if(stopmode == I2C_SOFT_STOP_MODE)
  120.     {
  121.         if(err == 0)
  122.             err = YUYY_HARDIIC_MasterSendStop(iicx);
  123.         if(err != 0)
  124.             YUYY_HARDIIC_ResetCtrl2Register(iicx);
  125.     }
  126.     return err;
  127. }

  128. uint8_t YUYY_HARDIIC_MasterSendRegDatas(i2c_type *iicx,uint8_t devaddr,uint8_t *reg,uint8_t reglen,uint8_t *datas,uint16_t datalen)
  129. {
  130.     uint8_t err = 0;
  131.     if(!iicx)
  132.         return 1;
  133.     err = YUYY_HARDIIC_MasterSendStart(iicx,devaddr,I2C_GEN_START_WRITE,I2C_SOFT_STOP_MODE,reglen+datalen);
  134.     err = YUYY_HARDIIC_MasterSendDatasWithStartStop(iicx,devaddr,0,reg,reglen);
  135.     if(err == 0)
  136.         err = YUYY_HARDIIC_MasterSendDatasWithStartStop(iicx,devaddr,YUYY_IIC_SEND_STOP,datas,datalen);
  137.     return err;
  138. }
  139. uint8_t YUYY_HARDIIC_MasterReadRegDatas(i2c_type *iicx,uint8_t devaddr,uint8_t *reg,uint8_t reglen,uint8_t *datas,uint16_t datalen)
  140. {
  141.     uint8_t err = 0;
  142.     if(!iicx)
  143.         return 1;
  144.     if(reglen > 0)
  145.     {
  146.         err = YUYY_HARDIIC_MasterSendStart(iicx,devaddr,I2C_GEN_START_WRITE,I2C_SOFT_STOP_MODE,reglen);
  147.         if(err == 0)
  148.             err = YUYY_HARDIIC_SendDatas(iicx,reg,reglen);
  149.         if(err == 0 && YUYY_HARDIIC_WaitFlag(iicx,I2C_TDC_FLAG,SET))
  150.             err = 4;
  151.     }
  152.     if(err == 0)
  153.         err = YUYY_HARDIIC_MasterReadDatasWithStartStop(iicx,devaddr,YUYY_IIC_SEND_STOP,datas,datalen);
  154.     return err;
  155. }

  156. uint8_t YUYY_HARDIIC_MasterSendDatas(YUYY_IIC_TYPE iicx,uint8_t devaddr,uint8_t *datas,uint16_t datalen)
  157. {
  158.     return YUYY_HARDIIC_MasterSendDatasWithStartStop(iicx,devaddr,YUYY_IIC_SEND_START|YUYY_IIC_SEND_STOP,datas,datalen);
  159. }

  160. uint8_t YUYY_HARDIIC_MasterReadDatas(YUYY_IIC_TYPE iicx,uint8_t devaddr,uint8_t *datas,uint16_t datalen)
  161. {
  162.     return YUYY_HARDIIC_MasterReadDatasWithStartStop(iicx,devaddr,YUYY_IIC_SEND_START|YUYY_IIC_SEND_STOP,datas,datalen);
  163. }

  164. uint8_t YUYY_HARDIIC_MasterSendReg8Datas(YUYY_IIC_TYPE iicx,uint8_t devaddr,uint8_t reg,uint8_t *datas,uint16_t datalen)
  165. {
  166.     return YUYY_HARDIIC_MasterSendRegDatas(iicx,devaddr,®,1,datas,datalen);
  167. }
  168. uint8_t YUYY_HARDIIC_MasterReadReg8Datas(YUYY_IIC_TYPE iicx,uint8_t devaddr,uint8_t reg,uint8_t *datas,uint16_t datalen)
  169. {
  170.     return YUYY_HARDIIC_MasterReadRegDatas(iicx,devaddr,®,1,datas,datalen);
  171. }
  172. uint8_t YUYY_HARDIIC_MasterSendReg16SEDatas(YUYY_IIC_TYPE iicx,uint8_t devaddr,uint16_t reg,uint8_t *datas,uint16_t datalen)
  173. {
  174.     uint8_t regd[2];
  175.     regd[0] = reg&0xFF;
  176.     regd[1] = (reg>>8)&0xFF;
  177.     return YUYY_HARDIIC_MasterSendRegDatas(iicx,devaddr,regd,2,datas,datalen);
  178. }
  179. uint8_t YUYY_HARDIIC_MasterReadReg16SEDatas(YUYY_IIC_TYPE iicx,uint8_t devaddr,uint16_t reg,uint8_t *datas,uint16_t datalen)
  180. {
  181.     uint8_t regd[2];
  182.     regd[0] = reg&0xFF;
  183.     regd[1] = (reg>>8)&0xFF;
  184.     return YUYY_HARDIIC_MasterReadRegDatas(iicx,devaddr,regd,2,datas,datalen);
  185. }
  186. uint8_t YUYY_HARDIIC_MasterSendReg16BEDatas(YUYY_IIC_TYPE iicx,uint8_t devaddr,uint16_t reg,uint8_t *datas,uint16_t datalen)
  187. {
  188.     uint8_t regd[2];
  189.     regd[1] = reg&0xFF;
  190.     regd[0] = (reg>>8)&0xFF;
  191.     return YUYY_HARDIIC_MasterSendRegDatas(iicx,devaddr,regd,2,datas,datalen);
  192. }
  193. uint8_t YUYY_HARDIIC_MasterReadReg16BEDatas(YUYY_IIC_TYPE iicx,uint8_t devaddr,uint16_t reg,uint8_t *datas,uint16_t datalen)
  194. {
  195.     uint8_t regd[2];
  196.     regd[1] = reg&0xFF;
  197.     regd[0] = (reg>>8)&0xFF;
  198.     return YUYY_HARDIIC_MasterReadRegDatas(iicx,devaddr,regd,2,datas,datalen);
  199. }
先来驱动这个OLED显示屏
微信图片_20231107193320.jpg
这个屏幕之前评测423时介绍了驱动方法,代码可以直接拿过来用,帖子地址https://bbs.21ic.com/icview-3338910-1-1.html
使用的时候只要修改i2c的指针和写方法就好了
  1. YUYY_OLED_SSD1315_DEV_Type oled_dev;
  2. void oled_init()
  3. {
  4.     oled_dev.iicx = I2C1;
  5.     oled_dev.iic_senddatas_func = (YUYY_OLED_SSD1315_IICSendDatasFunc_Type)YUYY_HARDIIC_MasterSendReg8Datas;
  6.     YUYY_OLED_SSD1315_Init(&oled_dev);
  7.     YUYY_OLED_SSD1315_ClearScreen(&oled_dev);
  8.     YUYY_OLED_SSD1315_DisplayString8x16(&oled_dev,0,0,0," AT32F405 TEST");
  9.     YUYY_OLED_SSD1315_DisplayString8x16(&oled_dev,0,2,0,"    I2C OLED");
  10.     YUYY_OLED_SSD1315_DisplayString8x16(&oled_dev,0,4,0,"  bbs.21ic.com");
  11.     YUYY_OLED_SSD1315_DisplayString8x16(&oled_dev,0,6,0,"Code by yuyy1989");
  12. }
运行效果
微信图片_20240427154037.jpg
再来用I2C读取DHTC12的温湿度数据,这个在之前评测423时也介绍过驱动方法,帖子地址https://bbs.21ic.com/icview-3338286-1-1.html
同样修改i2c的指针和写方法就好,和OLED用同一路I2C
  1. YUYY_DHTC12_DEV_Type dhtc12_dev;
  2. void detc12_init()
  3. {
  4.     dhtc12_dev.iicx = I2C1;
  5.     dhtc12_dev.delayms_func = YUYY_DelayMs;
  6.     dhtc12_dev.iic_readdatas_func = YUYY_HARDIIC_MasterReadDatas;
  7.     dhtc12_dev.iic_readregdatas_func = YUYY_HARDIIC_MasterReadReg16BEDatas;
  8.     dhtc12_dev.iic_sendregdatas_func = YUYY_HARDIIC_MasterSendReg16BEDatas;
  9.     YUYY_DHTC12_Init(&dhtc12_dev);
  10. }
在OLED屏幕上显示温湿度,在主循环中添加
  1. YUYY_DelayMs(1000);
  2.       if(!YUYY_DHTC12_ReadHT(&dhtc12_dev,&temp,&humi))
  3.       {
  4.           sprintf(out,"T:%03.1f  H:%03.1f%%",temp,humi/);
  5.           YUYY_OLED_SSD1315_DisplayString8x16(&oled_dev,0,4,0,out);
  6.       }
运行效果
微信图片_20240427154047.jpg





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

本版积分规则

认证:同飞软件研发工程师
简介:制冷系统单片机软件开发,使用PID控制温度

161

主题

815

帖子

10

粉丝
快速回复 在线客服 返回列表 返回顶部