Files
hm b49c9ab0c6 Initial commit: PY32MD530H28U7TR步进电机控制器项目
完整实现了以下模块:
- 系统数据总线(sys_data_bus)模块间通信
- UART/USART/LPUART驱动 + RS485半双工
- I2C驱动(AS5600角度传感器 + AT24C02 EEPROM)
- Modbus RTU从站协议
- 步进电机微步进控制(正弦/余弦换相+S曲线加减速)
- 到位开关驱动(DI_MIN/DI_MAX)
- PGA+ADC电流检测
- 系统监控任务(内存/串口/传感器/任务状态)
- LED/Key外设驱动
- 基于CMake + arm-none-eabi-gcc构建系统
2026-05-11 19:55:43 +08:00

156 lines
3.3 KiB
C

#include "i2c_driver.h"
#include "py32md530.h"
#include "system_py32md530.h"
#include "config.h"
#define I2C_TIMEOUT 10000
static void i2c_wait_flag(uint32_t flag)
{
uint32_t timeout = I2C_TIMEOUT;
while (!(I2C1->ISR & flag)) {
if (--timeout == 0) break;
}
}
ret_code_t i2c_init(uint32_t speed)
{
uint32_t timing;
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
I2C1->CR1 &= ~I2C_CR1_PE_Msk;
timing = (SystemCoreClock / speed) - 1;
if (timing > 0x3F) timing = 0x3F;
I2C1->TIMINGR = timing;
I2C1->CR1 = I2C_CR1_PE_Msk;
return RET_OK;
}
ret_code_t i2c_deinit(void)
{
I2C1->CR1 &= ~I2C_CR1_PE_Msk;
RCC->APB1ENR &= ~RCC_APB1ENR_I2C1EN;
return RET_OK;
}
ret_code_t i2c_master_write(uint8_t dev_addr, const uint8_t *data, uint32_t len)
{
uint32_t i;
I2C1->CR2 = (dev_addr << 1)
| (len << 16)
| (1UL << 13);
I2C1->CR2 |= (1UL << 14);
i2c_wait_flag(I2C_ISR_TXIS_Msk);
for (i = 0; i < len; i++) {
I2C1->TXDR = data[i];
if (i < len - 1) {
i2c_wait_flag(I2C_ISR_TXIS_Msk);
}
}
i2c_wait_flag(I2C_ISR_STOPF_Msk);
I2C1->ICR |= I2C_ISR_STOPF_Msk;
return RET_OK;
}
ret_code_t i2c_master_read(uint8_t dev_addr, uint8_t *data, uint32_t len)
{
uint32_t i;
I2C1->CR2 = (dev_addr << 1)
| (len << 16)
| (1UL << 13);
I2C1->CR2 |= (1UL << 14);
for (i = 0; i < len; i++) {
i2c_wait_flag(I2C_ISR_RXNE_Msk);
data[i] = (uint8_t)I2C1->RXDR;
}
i2c_wait_flag(I2C_ISR_STOPF_Msk);
I2C1->ICR |= I2C_ISR_STOPF_Msk;
return RET_OK;
}
ret_code_t i2c_mem_write(uint8_t dev_addr, uint16_t mem_addr, uint8_t mem_addr_size, const uint8_t *data, uint32_t len)
{
uint8_t buf[len + 2];
uint32_t i;
if (mem_addr_size == 1) {
buf[0] = (uint8_t)(mem_addr & 0xFF);
} else {
buf[0] = (uint8_t)((mem_addr >> 8) & 0xFF);
buf[1] = (uint8_t)(mem_addr & 0xFF);
}
for (i = 0; i < len; i++) {
buf[mem_addr_size + i] = data[i];
}
return i2c_master_write(dev_addr, buf, len + mem_addr_size);
}
ret_code_t i2c_mem_read(uint8_t dev_addr, uint16_t mem_addr, uint8_t mem_addr_size, uint8_t *data, uint32_t len)
{
uint8_t addr_buf[2];
if (mem_addr_size == 1) {
addr_buf[0] = (uint8_t)(mem_addr & 0xFF);
} else {
addr_buf[0] = (uint8_t)((mem_addr >> 8) & 0xFF);
addr_buf[1] = (uint8_t)(mem_addr & 0xFF);
}
I2C1->CR2 = (dev_addr << 1)
| (mem_addr_size << 16)
| (1UL << 13);
I2C1->CR2 |= (1UL << 14);
if (mem_addr_size == 1) {
i2c_wait_flag(I2C_ISR_TXIS_Msk);
I2C1->TXDR = addr_buf[0];
} else {
i2c_wait_flag(I2C_ISR_TXIS_Msk);
I2C1->TXDR = addr_buf[0];
i2c_wait_flag(I2C_ISR_TXIS_Msk);
I2C1->TXDR = addr_buf[1];
}
i2c_wait_flag(I2C_ISR_STOPF_Msk);
I2C1->ICR |= I2C_ISR_STOPF_Msk;
return i2c_master_read(dev_addr, data, len);
}
ret_code_t i2c_check_device(uint8_t dev_addr)
{
I2C1->CR2 = (dev_addr << 1)
| (0 << 16)
| (1UL << 13);
I2C1->CR2 |= (1UL << 14);
i2c_wait_flag(I2C_ISR_STOPF_Msk);
I2C1->ICR |= I2C_ISR_STOPF_Msk;
if (I2C1->ISR & I2C_ISR_NACKF_Msk) {
I2C1->ICR |= I2C_ISR_NACKF_Msk;
return RET_ERROR;
}
return RET_OK;
}