OpenEdv-开源电子网

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

两块探索者通过SPI主从通讯

[复制链接]

40

主题

137

帖子

0

精华

高级会员

Rank: 4

积分
579
金钱
579
注册时间
2019-8-4
在线时间
187 小时
发表于 2020-9-8 09:22:07 | 显示全部楼层 |阅读模式
10金钱
从机频率和主机一样设置为SPI_BaudRatePrescaler_256时,从机收到的数据右移了一位,比如主机发0X20,从机收到的却是0X10,但是将从机频率翻倍,莫名其妙的就接收数据对了,这是巧合还是啥子原因

从机配置,和原子哥例程相同的就不列出来了:
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
        SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;                //设置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_128;                //定义波特率预分频的值:波特率预分频值为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_I2S_ITConfig(SPI1,SPI_I2S_IT_RXNE,ENABLE);
        SPI_Cmd(SPI1, ENABLE); //使能SPI外设

        //需不需要将CR1的第八位置1
        SPI1->CR1&=~(1<<8);
       

void SPI1_IRQHandler()
{
        u8 data;
        if(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != RESET)
        {
                        SPI_ClearFlag(SPI1,SPI_I2S_FLAG_RXNE);
                data=SPI_ReceiveData(SPI1);
                        printf("%#X\r\n",data);
        }
}

主机:
if(key==KEY1_PRES)//KEY1按下,写入W25Q128
                {
//                        while(SPI_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
//                        SPI_I2S_SendData(SPI1, 0Xff);
                        while(SPI_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
                        SPI_I2S_SendData(SPI1, 0X30);
                }
                if(key==KEY0_PRES)//KEY0按下,读取字符串并显示
                {
//                        while(SPI_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
//                        SPI_I2S_SendData(SPI1, 0Xff);
                                while(SPI_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
                        SPI_I2S_SendData(SPI1, 0X20);
                       
                        //发送的数据为什么右移了一位
                }

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

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2020-9-8 11:16:00 | 显示全部楼层
本帖最后由 nashui_sx 于 2020-9-8 11:17 编辑

stm32 SPI主从通讯好像一直有错位bug,一次错后面全错  你试试在两个cs引脚都按你的配置外部电阻上拉下拉试试 应该能好点
特别从机cs引脚由于配置GPIO_Mode_IN_FLOATING,一定要外部上拉到vcc,防止数据错位

回复

使用道具 举报

0

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2020-8-10
在线时间
10 小时
发表于 2020-9-8 11:43:04 | 显示全部楼层
希望看到一个用普通IO模拟SPI通讯的例程
回复

使用道具 举报

40

主题

137

帖子

0

精华

高级会员

Rank: 4

积分
579
金钱
579
注册时间
2019-8-4
在线时间
187 小时
 楼主| 发表于 2020-9-8 13:29:15 | 显示全部楼层
本帖最后由 taomao 于 2020-9-8 13:45 编辑
nashui_sx 发表于 2020-9-8 11:16
stm32 SPI主从通讯好像一直有错位bug,一次错后面全错  你试试在两个cs引脚都按你的配置外部电阻上拉下拉试 ...

我的SPI1 CS配置,你的意思是改动硬件电路再上拉个电阻到VCC吗
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
回复

使用道具 举报

40

主题

137

帖子

0

精华

高级会员

Rank: 4

积分
579
金钱
579
注册时间
2019-8-4
在线时间
187 小时
 楼主| 发表于 2020-9-8 13:29:49 | 显示全部楼层
cdw1011 发表于 2020-9-8 11:43
希望看到一个用普通IO模拟SPI通讯的例程

你说的是软件SPI吧
回复

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2020-9-8 14:17:17 | 显示全部楼层
taomao 发表于 2020-9-8 13:29
我的SPI1 CS配置,你的意思是改动硬件电路再上拉个电阻到VCC吗
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_ ...

对你上拉GPIO_PuPd_UP  从机cs在电阻上拉一下试试 应该好点
回复

使用道具 举报

40

主题

137

帖子

0

精华

高级会员

Rank: 4

积分
579
金钱
579
注册时间
2019-8-4
在线时间
187 小时
 楼主| 发表于 2020-9-8 16:24:37 | 显示全部楼层
nashui_sx 发表于 2020-9-8 14:17
对你上拉GPIO_PuPd_UP  从机cs在电阻上拉一下试试 应该好点

试了,不行,不过还是谢谢,就这样吧,能通讯就行
回复

使用道具 举报

0

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2020-8-10
在线时间
10 小时
发表于 2020-9-11 11:13:37 | 显示全部楼层
taomao 发表于 2020-9-8 13:29
你说的是软件SPI吧

不是的,我的意思是,用普通IO口来做一个SPI通讯,不用STM32系统设置好的那几个SPI口来做,就像普通IO模拟I2C一样,,,
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-4-30 07:32

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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