打印

GD32F103模拟3线SPI通信问题

[复制链接]
85|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zyftank|  楼主 | 2024-11-21 10:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zyftank 于 2024-11-21 10:38 编辑

最近用GD32F103CBT6读一个3线SPI接口的ADC——芯海的CS1239,因为把连接画错了,只能用IO模拟SPI进行通信,但是在读取ADC芯片寄存器值的时候,一直返回0x00,我用万用表量了一下ADC的CS和SCK的PIN脚,都是高电平,SDA一直是低电平,不知道是什么原因,求大佬位帮忙看一下程序。
#include "cs_1239.h"
#include "systick.h"
#include <stdio.h>

void SDA_OUTPUT(void)
{
        //rcu_periph_clock_enable(RCU_GPIOB);
        gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,  GPIO_PIN_14);
}

void SDA_INPUT(void)
{
        //rcu_periph_clock_enable(RCU_GPIOB);
        gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ,  GPIO_PIN_14);
}

void cs1239_pin_init(void)
{
    rcu_periph_clock_enable(RCU_GPIOB);

          /* PB13--I2C0_SCL  PB14--I2C0_SDA  PB15--TestA_CS  PB12--TestB_CS*/
        gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13 | GPIO_PIN_15 | GPIO_PIN_12 |GPIO_PIN_14);
        //gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_14);
    //gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ,  GPIO_PIN_14);

    /* chip select invalid*/
        TestA_CS_HIGH;
        TestB_CS_HIGH;
        SPI_SCK_HIGH;
        gpio_bit_set(GPIOB, GPIO_PIN_14);
}



void cs1239_cs_low(uint8_t ch)
{
        if(ch == TestA)
                TestA_CS_LOW;
        if(ch == TestB)
                TestB_CS_LOW;
}

void cs1239_cs_high(uint8_t ch)
{
        if(ch == TestA)
                TestA_CS_HIGH;
        if(ch == TestB)
                TestB_CS_HIGH;
}

void cs1239_sendbyte(uint8_t _data)
{
        uint8_t  j;
    //delay_1us(10);
    for(j=0;j<8;j++)
    {
        SPI_SCK_LOW;
        if(_data&0x80)
            gpio_bit_set(GPIOB, GPIO_PIN_14);
        else
                        gpio_bit_reset(GPIOB, GPIO_PIN_14);
        delay_1us(10);
                SPI_SCK_HIGH;
                delay_1us(10);
        _data<<=1;
    }
        SPI_SCK_LOW;
        delay_1us(2);
}

uint8_t cs1239_readbyte(void)
{
    uint8_t  i,read=0;
    //delay_1us(10);
    for(i=0;i<8;i++)
    {
        SPI_SCK_LOW;
        delay_1us(10);
        SPI_SCK_HIGH;
        read<<=1;
        if(gpio_input_bit_get(GPIOB,GPIO_PIN_14) ==SET)
        {
            read++;
        }
                delay_1us(10);
    }
        SPI_SCK_LOW;
        delay_1us(10);
        
    return read;
}

void cs1239_write_reg(uint8_t ch, unsigned char regaddr,unsigned char databyte)
{
        regaddr |= 0x80;
        SDA_OUTPUT();
        SPI_SCK_HIGH;
        delay_1us(2);
        SPI_SCK_LOW;
        delay_1us(2);
    cs1239_cs_low(ch);
        delay_1us(2);
               
    cs1239_sendbyte(regaddr);
    cs1239_sendbyte(databyte);
               
    cs1239_cs_high(ch);
        delay_1us(2);
        SPI_SCK_HIGH;
}

uint8_t cs1239_read_reg(uint8_t ch, unsigned char regaddr)
{
        regaddr &= 0x7f ;
    uint8_t temp = 0;
        
        SDA_OUTPUT();
        SPI_SCK_HIGH;
        delay_1us(2);
        SPI_SCK_LOW;
        delay_1us(2);
    cs1239_cs_low(ch);
    cs1239_sendbyte(regaddr);
    //delay_1us(10);
        SDA_INPUT();
        delay_1us(200);
    temp = cs1239_readbyte();
    cs1239_cs_high(ch);
        delay_1us(2);
        SPI_SCK_HIGH;

    return temp;
}


unsigned int cs1239_read_data(uint8_t ch)
{
    unsigned int sum=0;
               
        SDA_OUTPUT();
        delay_1us(100);
        SPI_SCK_HIGH;
        delay_1us(2);
        SPI_SCK_LOW;
        delay_1us(2);
    cs1239_cs_low(ch);
    //while(ADS1256_DRDY);
    //ADS1256WriteREG(REG_MUX,channel);
    cs1239_sendbyte(0x09);delay_1us(50);
    //ADS1256_SendByte(CMD_WAKEUP);delay_us(50);
    //ADS1256_SendByte(CMD_RDATA);delay_us(50);
        SDA_INPUT();
        delay_1us(700);
    sum|=(cs1239_readbyte()<<16);
    sum|=(cs1239_readbyte()<<8);
    sum|=(cs1239_readbyte());
    cs1239_cs_high(ch);
        delay_1us(2);
        SPI_SCK_HIGH;
        
    return sum;
}

使用特权

评论回复
沙发
LcwSwust| | 2024-11-21 10:41 | 只看该作者
要想用万用表测,那得把每一步的延时加到特别大(比如1秒)才行.
建议准备一个示波器.
cs1239_read_reg就有问题,在读数据前怎么有个SDA_OUTPUT,不应是SDA_INPUT吗?

使用特权

评论回复
板凳
zyftank|  楼主 | 2024-11-21 10:48 | 只看该作者
LcwSwust 发表于 2024-11-21 10:41
要想用万用表测,那得把每一步的延时加到特别大(比如1秒)才行.
建议准备一个示波器.
cs1239_read_reg就有问 ...

cs1239_read_reg读寄存器值的时候,要先发读指令和地址,所以先是SDA_OUTPUT,发送指令后再改成SDA_INPUT。

使用特权

评论回复
地板
LcwSwust| | 2024-11-21 10:58 | 只看该作者
zyftank 发表于 2024-11-21 10:48
cs1239_read_reg读寄存器值的时候,要先发读指令和地址,所以先是SDA_OUTPUT,发送指令后再改成SDA_INPUT ...

哦,是我没看仔细.
最好是用示波器看看波形,
如果没示波器,就用利用单片机的ADC造一个示波器.

使用特权

评论回复
5
xionghaoyun| | 2024-11-21 11:38 | 只看该作者
学习一下

使用特权

评论回复
6
两只袜子| | 2024-11-21 15:21 | 只看该作者
GPIO引脚连接是否正确

使用特权

评论回复
7
elephant00| | 2024-11-21 15:23 | 只看该作者
参考GD32F103CBT6和CS1239的数据手册

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

9

帖子

0

粉丝