最近用到 STM32H743 的 IIC 功能,配置一个数字电位计,采用硬件 IIC 实现了此功能,而非软件模拟 IIC 的方法,记录一下实现过程。
参考资料:
一、数字电位计介绍
以 MCP4551 为例,MCP4551 为 8 位分辨率(spec page99)、SRAM 类型(spec page2)的数字电位计。另外,其 SDA 引脚为 Open-drain 端口(spec page34),因此需要外部上拉。
2.1 数字电位计地址帧结构
MCP4551 的地址帧结构,如图 1 所示。
MCP4551 地址帧结构是由如下几个部分组成:A6-A3 由固定的 0101 组成,A2-A0 由数字电位计引脚的状态决定,这些引脚在数字电位计内部拉高,也可以通过外部拉高、拉低或者由 IIC 主机的 I/O 控制,如图 2 所示。
部分型号的数字电位计不具有 A2-A1 管脚,则其由内部上拉,即固定的高电平:
The A7:A4 address bits are fixed to “0101” and the device appends the value of following three address pins (A2, A1, A0). Address pins that are not present on the device are pulled up (a bit value of ‘1’).
page46
2.2 数字电位计寄存器命令帧结构
数字电位计的内部寄存器映射和支持的命令如图 3 所示。
可以看到其内部的寄存器还是很少的,其中,地址 00h 对应的功能是设置 Wiper0 的数据,可读写。其对应的帧结构如图 7-1 所示。
AD3-AD0 为寄存器地址的低 4 位;C1 和 C0 配置读写命令;D9 和 D8 为要读写的数据,对于 8 位分辨率的器件,D9 位忽略,对于 7 位分辨率的器件,D8 位忽略。
分别介绍完数字电位计地址和寄存器地址的帧结构后,接下来就看一下怎么读写该寄存器。
2.3 IIC 写寄存器
IIC 写数字电位计的命令和数据顺序,如图 5 所示。
以寄存器地址 00h 为例,具体写命令如下:
2.4 IIC 读寄存器
IIC 读数字电位计的命令和数据顺序,如图 7 所示。
MCP4551 的 IIC 读命令,是在目标寄存器地址访问的基础上再读,所以前面会先有一帧写命令。以寄存器地址 00h 为例,具体读命令如下:
以上就是数字电位计 MCP4551 的简单介绍,接下来看 STM32H743 如何实现。
三、STM32H743 实现硬件 IIC 配置数字电位计
3.1 STM32CubeMX 配置
参数设置,默认设置,标准的 100KHz 传输速率。
GPIO 设置,SDA 要外部上拉,如果电路中没有上拉电阻,则可以将 GPIO 设置为 Pull-up。
另外,配置时钟,中断可以根据需要勾上。
配置完之后,生成初始代码。
3.2 修改代码
初始化代码:
/** * @brief Initializes the I2C1 peripheral. * @param void * @retval void */ void I2C1_init(void) { MX_I2C1_Init(); HAL_I2C_MspInit(&hi2c1); }
写寄存器代码:
/** * @brief write_MCP4551 register value, write data: 0000 000D8 D7-D0 * @param void * @retval HAL status */ uint8_t write_mcp4551(uint8_t *write_Buffer) { uint8_t MCP4551_WRBytes = 1; if(I2C1_Write_NBytes(MCP4551_adr, MCP4551_WIPER0_write, 1, write_Buffer, MCP4551_WRBytes) == I2C_FAIL ) { return I2C_FAIL; } return I2C_OK; }
读寄存器代码:
/** * @brief read_MCP4551 register value, read data: 0000 000D8 D7-D0 * @param void * @retval HAL status */ uint8_t read_mcp4551(void) { uint8_t i = 0; uint8_t MCP4551_RdBytes = 2; if(I2C1_Read_NBytes(MCP4551_adr, MCP4551_WIPER0_read, 1, MCP4551_Data_Buffer, MCP4551_RdBytes) == I2C_FAIL) { return I2C_FAIL; } for(i = 0; i < MCP4551_RdBytes; i++){ usb_printf("read byte i = 0x%2x\r\n", MCP4551_Data_Buffer[i]); HAL_Delay(10); } return I2C_OK; }
主函数中增加读写寄存器功能:
write_mcp4551(&mcp4551_config_data[0]); HAL_Delay(5); read_mcp4551(); HAL_Delay(5);
下载工程,程序可以正常运行,数字电位计能够设定预期的阻值。
3.3 测试结果
下面是通过示波器抓取的写寄存器波形和读寄存器波形,仔细观察,可以发现和上述分析的完全吻合。
扫码关注尚为网微信公众号
原创文章,作者:sunev,如若转载,请注明出处:https://www.sunev.cn/embedded/945.html