#include "ang_sensor.h" #include "core_cmInstr.h" #include "gd32c10x_gpio.h" #include "gd32c10x_spi.h" #include "stdbool.h" #include "systick.h" #include #define SPI_CS_ENABLE() gpio_bit_reset(GPIOA, GPIO_PIN_15) #define SPI_CS_DISABLE() gpio_bit_set(GPIOA, GPIO_PIN_15) constexpr float ANGLE_FACTOR = 1.0f / 65536.0f * 360.0f; /** * @brief Send or read half word through SPI * * @param[in] spi_periph SPI peripheral * @param[in] i_HalfWord data */ uint16_t spi_rw_half_word(uint32_t spi_periph, const uint16_t i_HalfWord) { uint32_t to; uint16_t data = 0xFFFF; bool ok = true; /* ---------- Send data ---------- */ to = 200; while ((RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE)) && --to) ; if (to == 0) ok = false; if (ok) { if (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE)) { (void)spi_i2s_data_receive(spi_periph); /* throw Dummy */ } spi_i2s_data_transmit(spi_periph, i_HalfWord); /* wait rx succ*/ to = 200; while ((RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE)) && --to) ; if (to == 0) ok = false; else data = spi_i2s_data_receive(spi_periph); /* throw Dummy */ } /* ---------- wait bsu idle ---------- */ if (ok) { to = 200; while ((SET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TRANS)) && SET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE) && --to) ; if (to == 0) ok = false; } return ok ? data : 0xFFFF; } void KHT7823_gpio_init(void) { rcu_periph_clock_enable(RCU_GPIOA); rcu_periph_clock_enable(RCU_GPIOB); rcu_periph_clock_enable(RCU_SPI0); rcu_periph_clock_enable(RCU_AF); /* 关闭 JTAG,仅保留 SWD(释放 PA15、PB3、PB4) */ gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE); /* -------- SPI0 全 remap:PB3/4/5 + PA15 -------- */ gpio_pin_remap_config(GPIO_SPI0_REMAP, ENABLE); /* PA15 → NSS, 推挽输出 */ gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15); /* PB3 → SCK, PB5 → MOSI, 推挽输出 */ gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3 | GPIO_PIN_5); /* PB4 → MISO, 浮空输入 */ gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_4 | GPIO_PIN_10 | GPIO_PIN_11); } /** * @brief Initialize SPI module * * @details Configures SPI hardware and initializes necessary settings */ void KHT7823_spi_init(void) { spi_parameter_struct spi_init_str; spi_struct_para_init(&spi_init_str); /* SPI参数:16bit, 主机, 全双工, CPOL=1 CPHA=1, MSB first */ spi_init_str.device_mode = SPI_MASTER; spi_init_str.trans_mode = SPI_TRANSMODE_FULLDUPLEX; spi_init_str.frame_size = SPI_FRAMESIZE_16BIT; spi_init_str.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE; spi_init_str.nss = SPI_NSS_SOFT; spi_init_str.endian = SPI_ENDIAN_MSB; spi_init_str.prescale = 24; /* 5MHz @ 120MHz */ spi_init(SPI0, &spi_init_str); spi_nss_output_enable(SPI0); spi_nssp_mode_enable(SPI0); spi_enable(SPI0); } void KHT7823_init(void) { KHT7823_gpio_init(); KHT7823_spi_init(); } float KHT7823_readAngle() { u16 u16Command = 0x0000; // 读取角度命令 float ang = 0; SPI_CS_ENABLE(); // 发送命令1,同时接收回答1 u16 u16data = spi_rw_half_word(SPI0, u16Command); SPI_CS_DISABLE(); ang = u16data * ANGLE_FACTOR; return ang; }