OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 11537|回复: 11

STM32F303RE SPI通信数据设置为8位,但是实际上收发16位

[复制链接]

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
55
金钱
55
注册时间
2017-6-6
在线时间
16 小时
发表于 2017-6-30 12:50:29 | 显示全部楼层 |阅读模式
1金钱

void SPI1_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;

        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_SPI1, ENABLE );       
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);

    GPIO_PinAFConfig(GPIOA,GPIO_PinSource5,GPIO_AF_5);
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_5);
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_5);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;  //复用推挽输出
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;   
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);

        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                                //设置SPI工作模式:设置为主SPI
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                            //设置SPI的数据大小:SPI发送接收8位帧结构
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                                    //选择了串行时钟的稳态:时钟悬空高
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;                            //数据捕获于第二个时钟沿
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                                    //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;//定义波特率预分频的值:波特率预分频值为256
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
        SPI_InitStructure.SPI_CRCPolynomial = 7;                                //CRC值计算的多项式
        SPI_Init(SPI1, &SPI_InitStructure);                                 //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器

        SPI_Cmd(SPI1, ENABLE); //使能SPI外设
       
        SPI1_ReadWriteByte(0xff);//启动传输                 
}

//SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI1_ReadWriteByte(u8 TxData)
{               
        u16 retry=0;                                 
        while((SPI1->SR&1<<1)==0)//等待发送区空       
        {
                retry++;
                if(retry>0XFFFE)return 0;
        }                          
        SPI1->DR=TxData;                   //发送一个byte
        retry=0;
        while((SPI1->SR&1<<0)==0) //等待接收完一个byte  
        {
                retry++;
                if(retry>0XFFFE)return 0;
        }                                                              
        return SPI1->DR;          //返回收到的数据                                    
}


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2017-7-1 00:31:33 | 显示全部楼层
回复

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
55
金钱
55
注册时间
2017-6-6
在线时间
16 小时
 楼主| 发表于 2017-7-1 15:02:33 | 显示全部楼层

用逻辑分析仪抓的,SPI口度W25Q64的ID
QQ图片20170701145649.png
回复

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
55
金钱
55
注册时间
2017-6-6
在线时间
16 小时
 楼主| 发表于 2017-7-1 15:04:00 | 显示全部楼层
怎么破?
回复

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
55
金钱
55
注册时间
2017-6-6
在线时间
16 小时
 楼主| 发表于 2017-7-2 21:38:53 | 显示全部楼层
别沉啊,各位哥哥们帮忙研究一下啊
回复

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
55
金钱
55
注册时间
2017-6-6
在线时间
16 小时
 楼主| 发表于 2017-7-5 12:28:06 | 显示全部楼层
没人理我
回复

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
55
金钱
55
注册时间
2017-6-6
在线时间
16 小时
 楼主| 发表于 2017-7-16 21:17:17 | 显示全部楼层
我怎么被盗号了?上面的内容并不是我发表的啊!
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2017-8-11
在线时间
2 小时
发表于 2017-8-11 12:00:40 来自手机 | 显示全部楼层
我也遇到过了同样的问题,设置的data size 8bit,单步调试,出来的数据好多跑到spi_dr高8位,导致读错  求大神指点
回复

使用道具 举报

1

主题

3

帖子

0

精华

初级会员

Rank: 2

积分
63
金钱
63
注册时间
2017-8-16
在线时间
16 小时
发表于 2017-8-16 22:50:22 | 显示全部楼层
SPI_RxFIFOThresholdConfig(SPI2, SPI_RxFIFOThreshold_QF); 要设这个FIFO阈值
回复

使用道具 举报

4

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
140
金钱
140
注册时间
2016-6-22
在线时间
31 小时
发表于 2022-5-15 14:45:57 | 显示全部楼层
我也遇到了,配置的8bit,CLK变成16bit了,但是在F4就是对的,F3上变成了16bit,无解啊
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2022-6-12
在线时间
1 小时
发表于 2022-6-12 12:12:55 | 显示全部楼层
杰伦周 发表于 2022-5-15 14:45
我也遇到了,配置的8bit,CLK变成16bit了,但是在F4就是对的,F3上变成了16bit,无解啊

这个问题的原因有可能是,因为SPI_DR数据寄存器是16位的,你配置位8位时,比如配置的是低8位,那么你发送时确实发送的是低8位数据,比如0x10, 但是收到的数据会自动补全为0x0010,所以会有16个CLK出来,也就是16位寄存器,你配置8位时,没有配置的位会被自动补0。

我用的是国产32位的(防STM32),我看了他们的库函数,配置8位发送的库函数里SPI->DR是用指针赋值的,也就是直接取16位DR寄存器里的低8位,那么收到的数据也不会补0了,可以收到正常的8位数据,STM32的没改过来吗?感觉这是STM32的一个bug, 你对比下F4和F030上关于SPI发送库函数是否有不一样,应该能找到答案。
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2022-6-12
在线时间
1 小时
发表于 2022-6-12 12:38:05 | 显示全部楼层
你这个SPI发送函数是自己写的吧?最好用STM的库函数,你这个函数有问题,因为你直接把发送数据赋值给SPI1->DR是有问题的,因为DR寄存器是16位的,你直接赋值给DR,操作的是16位,不是8位,就算你配置了8位数据也不行。比如你赋值SPI1->DR =0x10, 实际上会被转换为SPI1->DR=0x0010,没有配置的位会被自动补0,你去看看STM的库函数是怎么写的,你就明白了,不要用自己的写法,如果要自己写,也要按照STM库函数的写法
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-25 15:13

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表