打印

STM32做从设备的SPI通信问题

[复制链接]
4078|29
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zijia0328|  楼主 | 2014-8-15 17:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我要实现STM32做从设备读取AD芯片做主设备的数据,我的AD7765芯片是主动发出10M时钟信号的,而且还发出数据有效控制信号FSO低电平有效,其有效时间是32个时钟周期,我把它接到NSS上了,选硬件置位。AD对STM接线如下:SDO-MOSI,SDI-MISO,FSO-NSS,SCO-SCK。我下载了程序,但是SPI的接收状态位一直没变,说明就移位寄存器就没接到数据,怎么解决呢?
程序如下:
void SPI3_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
          SPI_InitTypeDef  SPI_InitStructure;
                NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC
        |RCC_APB2Periph_GPIOD, ENABLE );//PORTʱÖÓʹÄÜ
        RCC_APB1PeriphClockCmd(        RCC_APB1Periph_SPI3,  ENABLE );//SPI3       

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  //PB3/4/5
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);//³õʼ»¯GPIOB
        GPIO_SetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5);  //PB3/4/5
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  //PA15=FSO
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);//³õʼ»¯GPIOA
        GPIO_SetBits(GPIOA,GPIO_Pin_15);
       
        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10|GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//RESET,FSI
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOC, &GPIO_InitStructure);               
        GPIO_SetBits(GPIOC,GPIO_Pin_10|GPIO_Pin_11);
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  //PC12=OVE
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
        GPIO_ResetBits(GPIOC,GPIO_Pin_12);
       
        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_2;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOD, &GPIO_InitStructure);               
        GPIO_ResetBits(GPIOD,GPIO_Pin_2);
       
       

        SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Rx;  //
        SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;                //
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                //
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                //
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;        //
        SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;                //
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;                //
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //
        SPI_InitStructure.SPI_CRCPolynomial = 7;        //
        SPI_Init(SPI3, &SPI_InitStructure);  //

  NVIC_InitStructure.NVIC_IRQChannel = SPI3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);


  SPI_I2S_ITConfig(SPI3,SPI_I2S_IT_RXNE,ENABLE);

        SPI_Cmd(SPI3, ENABLE); //
       
        SPI3_ReadWriteByte(0xff);//         

        RSET = 0;     //AD芯片复位
        delay_us(5);
        RSET = 1;
        delay_us(5);
        FSI =1;
       
        SYNC = 0;
        delay_us(5);
        SYNC = 1;  //同步AD时钟

}  
void SPI3_SetSpeed(u8 SPI_BaudRatePrescaler)
{
          assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
        SPI3->CR1&=0XFFC7;
        SPI3->CR1|=SPI_BaudRatePrescaler;        //
        SPI_Cmd(SPI3,ENABLE);

}

u8 SPI3_ReadWriteByte(u8 TxData)
{               
        u8 retry=0;                                        
        while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET) //
                {
                retry++;
                if(retry>200)return 0;
                }                          
        SPI_I2S_SendData(SPI3, TxData); //ͨ¹ýÍâÉèSPIx·¢ËÍÒ»¸öÊý¾Ý
        retry=0;

        while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET) //
                {
                retry++;
                       
                if(retry>200)return 0;
                }                                                              
        return SPI_I2S_ReceiveData(SPI3); //
                //data1=SPI_I2S_ReceiveData(SPI3);
}


void SPI3_IRQHandler(void)
{         
        u8 aa;
        static u32 data[1000];
        if(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_RXNE)==SET)
        {      
                 aa++;
               data[aa]= SPI_I2S_ReceiveData(SPI3);

        }
        //SPI_ClearITPendingBit(SPI3,SPI_IT_RXNE);
}










相关帖子

沙发
zijia0328|  楼主 | 2014-8-15 17:14 | 只看该作者
因为接收标志就没置一,所以中断也没进去,数据读不出来啊,求大神们帮忙!!!!

使用特权

评论回复
板凳
tuzihog| | 2014-8-16 08:29 | 只看该作者
本帖最后由 tuzihog 于 2014-8-17 21:54 编辑

占位

使用特权

评论回复
地板
tuzihog| | 2014-8-16 08:31 | 只看该作者
还有输出速率设置为50M可能会有问题。以前我用SPI驱动74HC595的时候就不能设置为50M,不然数码管会出现乱码

使用特权

评论回复
5
tuzihog| | 2014-8-16 08:33 | 只看该作者
还有你设计思路有点奇怪,干嘛设置ADC芯片作为主机?

使用特权

评论回复
6
zijia0328|  楼主 | 2014-8-18 09:23 | 只看该作者
tuzihog 发表于 2014-8-16 08:33
还有你设计思路有点奇怪,干嘛设置ADC芯片作为主机?

因为时钟信号是AD自动输出的,能设为从设备吗?单片机SPI的主设备是需要时钟输出的,还有分频等设置。
IO口不设50M,那设多少合适呢?

使用特权

评论回复
7
shell.albert| | 2014-8-18 11:31 | 只看该作者
50M?速率也太高了吧。那你的slave采样端至少需要50*3=150M的时钟才能保证可靠采样,亲,你有吗?

使用特权

评论回复
8
zijia0328|  楼主 | 2014-8-18 12:07 | 只看该作者
shell.albert 发表于 2014-8-18 11:31
50M?速率也太高了吧。那你的slave采样端至少需要50*3=150M的时钟才能保证可靠采样,亲,你有吗? ...

IO的配置函数不都是比较固定的吗,我也没见别人有改过
入:        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);               
        GPIO_ResetBits(GPIOB,GPIO_Pin_4);
我的数据采样是AD采集并转换的,主动发出10M的时钟信号,并通过SDO口输出给单片机,所以单片机要做从机。

使用特权

评论回复
9
tuzihog| | 2014-8-18 12:36 | 只看该作者
zijia0328 发表于 2014-8-18 12:07
IO的配置函数不都是比较固定的吗,我也没见别人有改过
入:        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;  ...

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
查找GPIO_Speed_50MHz的定义处,就会看到还有2M和10M的供你选择。

使用特权

评论回复
10
zijia0328|  楼主 | 2014-8-18 13:44 | 只看该作者
tuzihog 发表于 2014-8-18 12:36
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
查找GPIO_Speed_50MHz的定义处,就会看到还有2M和10 ...

嗯 有的,谢啦,我改改试试吧。

使用特权

评论回复
11
zijia0328|  楼主 | 2014-8-18 14:24 | 只看该作者
tuzihog 发表于 2014-8-18 12:36
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
查找GPIO_Speed_50MHz的定义处,就会看到还有2M和10 ...

非常遗憾,不是速率这方面的问题唉,还有其他什么方面的问题吗:Q

使用特权

评论回复
12
lgnativs| | 2014-8-18 14:58 | 只看该作者
从机不能主动发生数据.你要深入的了解一下SPI的通讯模式.

使用特权

评论回复
13
zijia0328|  楼主 | 2014-8-18 15:23 | 只看该作者
lgnativs 发表于 2014-8-18 14:58
从机不能主动发生数据.你要深入的了解一下SPI的通讯模式.

大哥,你没看明白呀,我的AD是作为SPI主机的,单片机做从设备,想要从设备(stm32)读取主设备(AD)的数据。

使用特权

评论回复
14
tuzihog| | 2014-8-18 21:18 | 只看该作者
zijia0328 发表于 2014-8-18 14:24
非常遗憾,不是速率这方面的问题唉,还有其他什么方面的问题吗

stm32作为从机是不需要设置波特率的。
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
你去掉这行代码试试看

使用特权

评论回复
15
lgdjade| | 2014-8-18 22:50 | 只看该作者
:)

使用特权

评论回复
16
zijia0328|  楼主 | 2014-8-19 08:58 | 只看该作者
tuzihog 发表于 2014-8-18 21:18
stm32作为从机是不需要设置波特率的。
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescal ...

对,芯片资料上说做从机时设置的波特率无效,是被忽略的,按说写不写都没影响吧。那我去了试试看吧。

使用特权

评论回复
17
zijia0328|  楼主 | 2014-8-19 08:59 | 只看该作者
lgdjade 发表于 2014-8-18 22:50

大哥,给解解惑吧

使用特权

评论回复
18
zijia0328|  楼主 | 2014-8-19 15:33 | 只看该作者
zijia0328 发表于 2014-8-19 08:58
对,芯片资料上说做从机时设置的波特率无效,是被忽略的,按说写不写都没影响吧。那我去了试试看吧。 ...

测了好多遍,也不是那的问题呀:'(

使用特权

评论回复
19
zijia0328|  楼主 | 2014-8-19 15:34 | 只看该作者
tuzihog 发表于 2014-8-18 21:18
stm32作为从机是不需要设置波特率的。
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescal ...

测了好多遍,也不是那的问题呀

使用特权

评论回复
20
dongranmengming| | 2014-8-20 09:05 | 只看该作者
从机不能发送数据的,你这种情况应该是ad发送数值的时候主动去波动时钟和发送数据,mcu只能被动接收,所以你用示波器看看波形以及stm32的配置

使用特权

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

本版积分规则

4

主题

40

帖子

2

粉丝