2025-10-31 01:17:52 +08:00
|
|
|
|
#include "ang_sensor.h"
|
2025-10-09 21:09:33 +08:00
|
|
|
|
#include "gd32c10x_gpio.h"
|
2025-10-14 00:49:58 +08:00
|
|
|
|
#include "gd32c10x_spi.h"
|
2025-09-23 00:27:51 +08:00
|
|
|
|
|
2025-10-30 20:20:14 +08:00
|
|
|
|
#define SPI_CS_ENABLE() gpio_bit_reset(GPIOA, GPIO_PIN_15)
|
2025-09-23 00:27:51 +08:00
|
|
|
|
#define SPI_CS_DISABLE() gpio_bit_set(GPIOA, GPIO_PIN_15)
|
2025-10-31 01:17:52 +08:00
|
|
|
|
constexpr float ANGLE_FACTOR = 1.0f / 65536.0f * 360.0f;
|
2025-09-23 00:27:51 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief Send or read half word through SPI
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param[in] spi_periph SPI peripheral
|
|
|
|
|
|
* @param[in] i_HalfWord data
|
|
|
|
|
|
*/
|
2025-10-30 20:20:14 +08:00
|
|
|
|
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;
|
2025-09-23 00:27:51 +08:00
|
|
|
|
|
2025-10-30 20:20:14 +08:00
|
|
|
|
/* ---------- Send data ---------- */
|
|
|
|
|
|
to = 200;
|
|
|
|
|
|
while ((RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE)) && --to)
|
|
|
|
|
|
;
|
|
|
|
|
|
if (to == 0)
|
|
|
|
|
|
ok = false;
|
2025-09-23 00:27:51 +08:00
|
|
|
|
|
2025-10-30 20:20:14 +08:00
|
|
|
|
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 */
|
|
|
|
|
|
}
|
2025-09-23 00:27:51 +08:00
|
|
|
|
|
2025-10-30 20:20:14 +08:00
|
|
|
|
/* ---------- 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;
|
|
|
|
|
|
}
|
2025-09-23 00:27:51 +08:00
|
|
|
|
|
2025-10-30 20:20:14 +08:00
|
|
|
|
return ok ? data : 0xFFFF;
|
2025-09-23 00:27:51 +08:00
|
|
|
|
}
|
2025-10-14 00:49:58 +08:00
|
|
|
|
|
2025-10-30 20:20:14 +08:00
|
|
|
|
void KHT7823_gpio_init(void) {
|
2025-10-09 21:09:33 +08:00
|
|
|
|
rcu_periph_clock_enable(RCU_GPIOA);
|
2025-10-30 20:20:14 +08:00
|
|
|
|
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);
|
2025-09-23 00:27:51 +08:00
|
|
|
|
|
2025-10-30 20:20:14 +08:00
|
|
|
|
/* -------- 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,
|
2025-10-31 01:17:52 +08:00
|
|
|
|
GPIO_PIN_4 | GPIO_PIN_10 | GPIO_PIN_11);
|
2025-09-23 00:27:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief Initialize SPI module
|
|
|
|
|
|
*
|
|
|
|
|
|
* @details Configures SPI hardware and initializes necessary settings
|
|
|
|
|
|
*/
|
2025-10-30 20:20:14 +08:00
|
|
|
|
void KHT7823_spi_init(void) {
|
|
|
|
|
|
spi_parameter_struct spi_init_str;
|
|
|
|
|
|
spi_struct_para_init(&spi_init_str);
|
2025-09-23 00:27:51 +08:00
|
|
|
|
|
2025-10-31 01:17:52 +08:00
|
|
|
|
/* SPI参数:16bit, 主机, 全双工, CPOL=1 CPHA=1, MSB first */
|
2025-10-30 20:20:14 +08:00
|
|
|
|
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;
|
2025-10-31 01:17:52 +08:00
|
|
|
|
|
|
|
|
|
|
spi_init_str.prescale = 24; /* 5MHz @ 120MHz */
|
2025-10-30 20:20:14 +08:00
|
|
|
|
spi_init(SPI0, &spi_init_str);
|
|
|
|
|
|
spi_nss_output_enable(SPI0);
|
|
|
|
|
|
spi_nssp_mode_enable(SPI0);
|
|
|
|
|
|
spi_enable(SPI0);
|
2025-09-23 00:27:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-30 20:20:14 +08:00
|
|
|
|
void KHT7823_init(void) {
|
|
|
|
|
|
KHT7823_gpio_init();
|
|
|
|
|
|
KHT7823_spi_init();
|
|
|
|
|
|
}
|
2025-09-23 00:27:51 +08:00
|
|
|
|
|
2025-10-30 20:20:14 +08:00
|
|
|
|
float KHT7823_readAngle() {
|
2025-10-31 01:17:52 +08:00
|
|
|
|
u16 u16Command = 0x0000; // 读取角度命令
|
2025-09-23 00:27:51 +08:00
|
|
|
|
|
2025-10-30 20:20:14 +08:00
|
|
|
|
float ang = 0;
|
|
|
|
|
|
SPI_CS_ENABLE();
|
2025-10-31 01:17:52 +08:00
|
|
|
|
// 发送命令1,同时接收回答1
|
|
|
|
|
|
u16 u16data = spi_rw_half_word(SPI0, u16Command);
|
2025-10-30 20:20:14 +08:00
|
|
|
|
SPI_CS_DISABLE();
|
|
|
|
|
|
|
2025-10-31 01:17:52 +08:00
|
|
|
|
ang = u16data * ANGLE_FACTOR;
|
2025-10-30 20:20:14 +08:00
|
|
|
|
|
|
|
|
|
|
return ang;
|
2025-10-14 00:49:58 +08:00
|
|
|
|
}
|