[研电赛技术支持] gd32通过spi1读取ADCS7476数据

[复制链接]
1075|1
观海 发表于 2025-8-12 13:49 | 显示全部楼层 |阅读模式




在实习过程中,我已完成 COS4426SE 芯片与线圈的初始化配置。当将碳棒伸入线圈时,会产生电压变化。此时,产生的电压信号会被输送至 ADCS7476 的 VIN 引脚。ADCS7476 会将该模拟电压信号与VDD的比值转换为十六位二进制数据,随后这些数据通过 SPI1 接口传输至 GD32 单片机中。下面是我初始化spi1,以及对收到的数据进行解码得到电压的程序。

(1)查阅ADCS7476的数据手册






上面是我查阅ADCS7476的数据手册,可以看出它的spi工作模式是:当CS被拉低时,SCLK开始产生时钟信号,SDATA在SCLK的驱动下传输数据。数据在SCLK的第一个边沿进行采样。根据上述特征,可以判断该SPI接口的工作模式为CPOL = 1,CPHA = 0。根据这个去初始化gd32的spi模块。此外该数据手册规定了spi的时钟频率。

(2)gd32的spi初始化

void spi1_config(void)
{
      spi_parameter_struct spi_init_struct;
    /* 使能GPIOA和复用功能时钟 */
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_SPI1);
      gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
    gpio_bit_set(GPIOB, GPIO_PIN_12);  // 初始状态:CS高电平
    gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13);
        gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_14);

    spi_struct_para_init(&spi_init_struct);

    spi_init_struct.trans_mode           = SPI_TRANSMODE_FULLDUPLEX;
    spi_init_struct.device_mode          = SPI_MASTER;
    spi_init_struct.frame_size           = SPI_FRAMESIZE_16BIT;
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE ; // 模式1
    spi_init_struct.nss                  = SPI_NSS_SOFT;            // 软件NSS控制
    spi_init_struct.prescale             = SPI_PSC_8;               
    spi_init_struct.endian               = SPI_ENDIAN_MSB;

    spi_init(SPI1, &spi_init_struct);
    spi_enable(SPI1);
    /* PA1默认复用功能就是TIMER1_CH1,无需重映射 */
}
(3)spi读取ADCS7476的数据 [注意传回来的数据是低12位是有效数据,前四位为0]

uint16_t ADCS7476_Read(void) {
    uint16_t adc_value = 0;
    gpio_bit_reset(GPIOB, GPIO_PIN_12);
    while (spi_i2s_flag_get(SPI1, SPI_FLAG_TBE) == RESET);
    spi_i2s_data_transmit(SPI1, 0x0000); // 发送哑数据触发时钟

    while (spi_i2s_flag_get(SPI1, SPI_FLAG_RBNE) == RESET);
    adc_value = spi_i2s_data_receive(SPI1);
    gpio_bit_set(GPIOB, GPIO_PIN_12);
    return (adc_value & 0x0FFF); // 提取低12位

}
(4)将读取的数据转化为电压信号

float ADC_To_Voltage(uint16_t adc) {
    return (adc * 5.0f) / 4095.0f;               // 12位ADC满量程4095
}
(5)调试程序







在主程序中调用封装好的函数,将单片机收到的数据与电压表测量的数据相比,发现数据在百分位上有一些误差,功能实现完成。


————————————————
版权声明:本文为CSDN博主「嵌入式新人一枚」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_65863078/article/details/149208314

海滨消消 发表于 2025-8-28 16:10 | 显示全部楼层
还说啥
您需要登录后才可以回帖 登录 | 注册

本版积分规则

153

主题

4385

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部