TA的每日心情 | 慵懒 2025-8-6 21:07 |
|---|
签到天数: 313 天 连续签到: 1 天 [LV.8]以坛为家I
状元
- 积分
- 5300
|
本帖最后由 stm1024 于 2025-6-30 00:06 编辑
I2C总线应该是嵌入式开发中芯片之间相互通讯很常见的一种总线,最开始由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。
主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件.在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件.然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下.主机负责产生定时时钟和终止数据传送。
今天测试一下I2C总线的通讯,本次进行通讯的设备是AHT11,是一个很小巧的温湿度传感器。
1. 硬件连接
设备端没啥好说的,就4根线,电源正负极,然后就是SCL和SDA,开发板的I2C总线选哪个呢?看schematic,SCL和SDA分别对应了开发板上的PB13和PB12,直接和设备之间进行连接:
2. 软件环境
CH585的库中I2C头文件及源文件仅提供了基本的定义和函数,但是在测试样例中,还提供了应用级别的头文件和源文件,亦即app_i2c.h和app_i2c.c,拿来吧你。
然后就是我们的代码:
贴个代码:
- #include "CH58x_common.h"
- #include "app_i2c.h"
- uint8_t TxBuff[100];
- #define SIZE 6
- #define MASTER_ADDR 0x66
- #define AHT11 0x38 //AHT11的地址
- uint8_t TxData[]={0xac,0x33,0x00};//AHT11读取数据的命令
- uint8_t RxData[SIZE];
- void i2c_config()
- {
- //配置i2c
- GPIOB_ModeCfg(GPIO_Pin_12 | GPIO_Pin_13, GPIO_ModeIN_PU);
- I2C_Init(
- I2C_Mode_I2C,
- 400000,
- I2C_DutyCycle_16_9,
- I2C_Ack_Enable,
- I2C_AckAddr_7bit,
- MASTER_ADDR);
- // while(I2C_GetFlagStatus(I2C_FLAG_BUSY) != RESET);
- // I2C_GenerateSTART(ENABLE);
- // while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
- // I2C_Send7bitAddress(0x70, I2C_Direction_Transmitter);
- // while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
- // I2C_SendData(0x00);
- // while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
- // I2C_GenerateSTOP(ENABLE);
- DelayMs(100);
- i2c_app_init(MASTER_ADDR);
- }
- void uart1_config()
- {
- //配置串口1
- GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
- GPIOA_SetBits(GPIO_Pin_9);
- GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
- UART1_DefInit();
- }
- int main()
- {
- float humidity,temperature;
- int ret;
- HSECFG_Capacitance(HSECap_18p);
- SetSysClock(CLK_SOURCE_HSE_PLL_62_4MHz);
-
- uart1_config();
- memset(TxBuff,0x00,100);
- sprintf((char*)TxBuff,"CH585M IIC Test\n");
- UART1_SendString(TxBuff, strlen((const char *)TxBuff));
-
- i2c_config();
-
- while(1)
- {
- ret = i2c_write_to(AHT11, TxData, sizeof(TxData), true, true);
- // memset(TxBuff,0x00,100);
- // sprintf((char*)TxBuff,"write to %#x %s\n",AHT11, ret ? "failed" : "success");
- // UART1_SendString(TxBuff, strlen((const char *)TxBuff));
- DelayMs(100);
- ret = i2c_read_from(AHT11, RxData, 6, true, 1000);
- // memset(TxBuff,0x00,100);
- // sprintf((char*)TxBuff,"read %d byte(s) from %#x\n", ret, AHT11);
- // UART1_SendString(TxBuff, strlen((const char *)TxBuff));
- DelayMs(100);
- //parser raw data
- humidity=(RxData[1]<<12)+(RxData[2]<<4)+(RxData[3]>>4);
- humidity=humidity/1024/1024*100;
- temperature=((RxData[3] & 0x0f)<<16)+(RxData[4]<<8)+RxData[5];
- temperature=temperature/1024/1024*200-50;
-
- memset(TxBuff,0x00,100);
- sprintf((char*)TxBuff,"H=%5.2f%% T=%5.2f℃\n",humidity,temperature);
- UART1_SendString(TxBuff, strlen((const char *)TxBuff));
- DelayMs(800);
- }
- return 0;
- }
- /*
- uint8_t TxBuff[100];
- uint8_t cycle=0;
- void uart1_config()
- {
- //配置串口1
- GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);// RXD-上拉输入
- GPIOA_SetBits(GPIO_Pin_9);
- GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA); // TXD-推挽输出,注意先让IO口输出高电平
- UART1_DefInit();
- }
- */
- /*
- uart1_config();
- memset(TxBuff,0x00,100);
- sprintf(TxBuff,"CH585M Basic PWM Test, FREQ_SYS=%ld\n",FREQ_SYS);
- UART1_SendString(TxBuff, strlen(TxBuff));
- */
复制代码
接下来就是简单的编译,下载,运行效果如下:
对了,如果不能正常显示浮点数,则应该在工程选项中打开浮点数支持,然后清理工程,完全重新编译一下:
之后再下载。
不得不说,mounriver studio这个集成做的还是可以的,尤其是和WCH-link组合使用,调试下载,串口打印都能一口气搞定。
好了,今日关于I2C的评测就是这样。
|
|