打印
[STM32F1]

各位大神,我的SPI主从通信,为什么收不到从设备的数据

[复制链接]
13993|51
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
感知新生|  楼主 | 2015-5-21 18:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 感知新生 于 2015-5-21 19:34 编辑

大神,很郁闷的一个问题就是收不到从设备的数据。不知道发生这种现象会是什么原因呢?目前我测试了MOSI信号线上的信号显示正常,时钟信号正常,但MISO信号线一直处于低信号。我将MOSI信号短接到MISO信号线上面 ,可以测试到MISO信号线上出现了和MOSI一样的信号,但是主设备还是接收不到数据。目前这种情况,各位大神觉得会是什么原因呢?下面是部分程序代码的配置:
/****************************************************************************
* 名    称:int main(void)
* 功    能:主函数
* 入口参数:无
* 出口参数:无
* 说    明:
* 调用方法:无
****************************************************************************/
int main(void)
{        
        RCC_Configuration();
        delay_init(72);                                                                                                                                 //延时函数初始化
        RTC_Configuration();
    ADS1299_Communication(440000);
        delay_ms(150);
        GPIO_ResetBits(GPIOB, GPIO_Pin_12);                                        //CS拉低
        delay_us(1);
        ADS1299_RREG(0x00,13,cache);

        delay_us(2);
        GPIO_SetBits(GPIOB, GPIO_Pin_12);                                        //CS拉低
        delay_us(2);       
        while(1){}


/****************************************************************************
* 名    称:void ADS1299_RREG(uint8_t add,uint8_t num,uint8_t *cache)
* 功    能:ADS1299命令配置函数:读寄存器命令;
* 入口参数:add表示寄存器的地址,num表示读取寄存器的个数,cache为缓存地址;
* 出口参数:
* 说    明:该函数的返回值与寄存器地址是反序的;
* 调用方法:无
****************************************************************************/
void ADS1299_RREG(uint8_t add,uint8_t num,uint8_t *cache){
        uint8_t Command_RREG_mid,count;

        Command_RREG_mid = add+Command_RREG;
        SPI2_ReadWriteByte(Command_RREG_mid);
        delay_us(2);
        SPI2_ReadWriteByte(num-1);
        delay_us(2);

        for(count = 0; count < num; count ++)
        {
                *(cache + count) = SPI2_ReadWriteByte(0x00);
                delay_us(2);
        }
}


/****************************************************************************
* 名    称:uint8_t SPI2_ReadWriteByte(uint8_t TxData)
* 功    能:
* 入口参数: 无
* 出口参数:返回spi2接收值
* 说    明:
* 调用方法:无
****************************************************************************/
uint8_t SPI2_ReadWriteByte(uint8_t TxData){
        uint8_t RxData;
        while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);//等待发送区空       
    SPI_I2S_SendData(SPI2, TxData);//发送一个byte
    while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);//等待接收完一个byte
    RxData = SPI_I2S_ReceiveData(SPI2); //返回收到的数据
        return RxData;
}


/****************************************************************************
* 名    称:void SPI2_Configuration(uint16_t SPI_BaudRatePrescaler_X)
* 功    能:SPI2通信的配置函数
* 入口参数:分频数
* 出口参数:无
* 说    明:
* 调用方法:无
****************************************************************************/
void SPI2_Configuration(uint16_t SPI_BaudRatePrescaler_X){
        GPIO_InitTypeDef GPIO_InitStructure;
        SPI_InitTypeDef   SPI_InitStructure;

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   //PB13/14/15 复用推挽输出  
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化 GPIOB

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 ;                                     //CS片选信号
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
         
        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;   //双线双向全双工
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;          //主
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;  // SPI 发送接收 8 位帧结构
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;             //串行同步时钟的空闲状态为低电平
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;           //第二个跳变沿数据被采样
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;              //NSS 信号由软件控制
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_X; //预分频 256
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;     //数据传输从 MSB 位开始
        SPI_InitStructure.SPI_CRCPolynomial = 7;               //CRC 值计算的多项式
        SPI_Init(SPI2, &SPI_InitStructure);                   //根据指定的参数初始化外设 SPIx 寄存器
        SPI_Cmd(SPI2, ENABLE);                                //使能 SPI 外设

//        SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);          //开启SPI2接收中断

}

沙发
luofeng2g| | 2015-5-21 18:17 | 只看该作者
你的意思是有波形,没有数据么?你可以换个接口试试

使用特权

评论回复
板凳
感知新生|  楼主 | 2015-5-21 18:34 | 只看该作者
luofeng2g 发表于 2015-5-21 18:17
你的意思是有波形,没有数据么?你可以换个接口试试

你是说主机的接口可能有问题吗?我配置过这个接口,给它置高可以测量的出来高电平。另外,我这是PCB板,没办法换接口啊

使用特权

评论回复
地板
kaly_liu| | 2015-5-21 19:03 | 只看该作者
会不会是你的CPU时序要求比较严格?时序不符合要去,比如上升沿、下降沿 太慢了了?

使用特权

评论回复
5
感知新生|  楼主 | 2015-5-21 19:07 | 只看该作者
kaly_liu 发表于 2015-5-21 19:03
会不会是你的CPU时序要求比较严格?时序不符合要去,比如上升沿、下降沿 太慢了了? ...

我是把主机的MOSI的信号直接短接到MISO上面了,但是主机还是不能收到数据。另外,如果一切正常情况下,我也不太清楚这样短接能不能收到数据呢?如果不能,我这样验证也就没意义了。

使用特权

评论回复
6
airwill| | 2015-5-21 19:12 | 只看该作者
这样短接当然能够收到数据。
原理上即使恒低电平,也是收到数据的,那就是 0
所以我感觉是你还没有理解 SPI 吧。你是怎么判断主设备接收不到数据的?

使用特权

评论回复
7
感知新生|  楼主 | 2015-5-21 19:30 | 只看该作者
airwill 发表于 2015-5-21 19:12
这样短接当然能够收到数据。
原理上即使恒低电平,也是收到数据的,那就是 0
所以我感觉是你还没有理解 SPI ...

我整的STM32 用JLINK在线调试的。你说的很是,确实能收到数据0(我是根据接受数据的指针的变动来判断接收数据0的),但是一直是0,我短接后,收到的数据还是零。

使用特权

评论回复
8
冰河w| | 2015-5-21 19:33 | 只看该作者
工作模式设置对了吗,在检查一下

使用特权

评论回复
9
感知新生|  楼主 | 2015-5-21 19:35 | 只看该作者
冰河w 发表于 2015-5-21 19:33
工作模式设置对了吗,在检查一下

嗯 ,这个我检查的好多次,都开始怀疑芯片手册写错了哈,甚至每个模式都试了,可是结果很失望啊……

使用特权

评论回复
10
Thor9| | 2015-5-21 20:43 | 只看该作者
会不会是硬件问题

使用特权

评论回复
11
感知新生|  楼主 | 2015-5-21 20:47 | 只看该作者
Thor9 发表于 2015-5-21 20:43
会不会是硬件问题

正在排查这方面的问题

使用特权

评论回复
12
huangxz| | 2015-5-21 20:59 | 只看该作者
如果可以的话,先用简单的命令测试从机是否响应。

使用特权

评论回复
13
感知新生|  楼主 | 2015-5-21 21:16 | 只看该作者
huangxz 发表于 2015-5-21 20:59
如果可以的话,先用简单的命令测试从机是否响应。

就是在用最简单的命令测试呢。我在排查硬件问题,发现MISO这个主机引脚有问题,但是似乎不知道怎么解决啊,这个引脚在被设置成 推挽式输出 后置高,但是测得的电压只有2.2V,正常值应该是3.1左右啊,而其他引脚被同样配置后,测得的电压都很正常。不知道这是什么原因呢?

使用特权

评论回复
14
感知新生|  楼主 | 2015-5-21 21:18 | 只看该作者
Thor9 发表于 2015-5-21 20:43
会不会是硬件问题

排查引脚时,发现MISO引脚设置成 推挽式输出 置高后,测得的引脚电压是2.2V,其他引脚正常。不知道这是什么原因呢?

使用特权

评论回复
15
mmuuss586| | 2015-5-21 23:04 | 只看该作者
不会是连错SPI引脚了吧?

使用特权

评论回复
16
wind~风| | 2015-5-21 23:55 | 只看该作者
这两天我也在研究SPI,留个脚印

使用特权

评论回复
17
songchenping| | 2015-5-22 07:25 | 只看该作者
你可以断开MISO管脚单独用示波器测量从设备有无输出信号。如果有。可能就是你主设备的SPI配置是否正确。

使用特权

评论回复
18
runningwzf| | 2015-5-22 08:23 | 只看该作者
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   //PB13/14/15 复用推挽输出  
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化 GPIOB

这段有问题:
CLK、MOSI应该是AF_FF
但是MISO是IPU

使用特权

评论回复
19
runningwzf| | 2015-5-22 08:24 | 只看该作者
STM32的端口设备,外射输出端口一般都是用AF_PP,外射输入端口一般都用IPU

使用特权

评论回复
20
caijin| | 2015-5-22 10:11 | 只看该作者
SPI线上拉或者下拉试试,有些SPI需要上拉,有些需要下拉,  如果软件能设置就用软件内部设置,不用外加电阻

使用特权

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

本版积分规则

5

主题

36

帖子

2

粉丝