搜索
bottom↓
回复: 28

【求拍砖】感觉STM32的SPI没有STM8的SPI好使

[复制链接]

出0入0汤圆

发表于 2015-7-2 10:15:20 | 显示全部楼层 |阅读模式
        说stm32比stm8差,肯定会n多人拿棍子拍我,但是我这两条调试出来的结果,的确让我产生这种感觉!
我做一个实验,使用串口,将串口调试助手发送过来的字库bin文件烧录进SPIFlash中,stm8跟stm32同样使用
硬件spi方式,其中stm32使用SPI1方式2,CPOL = 1,CPHA = 1;时钟72M4分频得到18M的通信时钟速度,
在串口中断中,进入串口中断,我会有一下步骤:
接收串口数据,把数据烧录进SPI固定地址,地址值+1,同时读出地址信息,打印屏幕。
波特率控制在115200,使用stm8,勉强能够在115200的波特率下进行以上工作,信息也能完整,但是stm32则
不可以,得到的信息是,接收到的字节数打了个5折,也就是说,串口每发送两个字节过来,stm32才接到加处理到
1个字节,那么另外一个字节就丢了,而stm8却可以勉强处理,如果波特率设置在9600,stm32依然不行,而stm8
完美处理消化!
        不知道是我程序哪里处理不好,还是我这个感觉是真的,以下给我的代码信息:
stm32串口中断:
  1. u32 Ziku_Addr = 1024*1024*6;
  2. void USART1_IRQHandler(void)                        //串口1中断服务程序
  3. {
  4.         uint8_t wData = 0;
  5.         uint8_t rData = 0;

  6.         if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
  7.         {

  8.                 wData=USART_ReceiveData(USART1);
  9.                 SPI_Flash_Write_Page(&wData, Ziku_Addr, 1);
  10.                 SPI_Flash_Read(&rData,Ziku_Addr,1);
  11.                 UART1_SendByte(rData);
  12.                 Ziku_Addr++;
  13.         }

  14. }
复制代码


stm8串口中断:
  1. void UART_IRQ( void )
  2. {
  3.         uint8_t RecieveBuf = 0;
  4.         uint8_t RXData = 0;


  5.         //以下是用户处理函数
  6.         RXData = UART_ReceiveByte();
  7.         SPI_FLASH_BufferWrite(&RXData, addr, 1);
  8.         SPI_FLASH_BufferRead(&RecieveBuf, addr, 1);
  9.         addr++;
  10.         UART_SendByte(RXData);


  11.         //清除接收标志位
  12.         UART2_ClearITPendingBit(UART2_IT_RXNE);
  13. }
复制代码


spiflash函数一模一样,唯一不同就是stm32挂的是8Mbyte的Flash,而stm8挂的是2Mbyte的Flash!
还请各位多多拍砖

阿莫论坛20周年了!感谢大家的支持与爱护!!

如果想吃一顿饺子,就得从冰箱里取出肉,剁馅儿,倒面粉、揉面、醒面,擀成皮儿,下锅……
一整个繁琐流程,就是为了出锅时那一嘴滚烫流油的热饺子。

如果这个过程,禁不住饿,零食下肚了,饺子出锅时也就不香了……《非诚勿扰3》

出0入0汤圆

发表于 2015-7-2 17:16:11 | 显示全部楼层
可能由于UART1_SendByte占用太多时间
建议使用DMA或队列

出0入0汤圆

 楼主| 发表于 2015-7-2 17:33:12 | 显示全部楼层
lcw_swust 发表于 2015-7-2 17:16
可能由于UART1_SendByte占用太多时间
建议使用DMA或队列

stm8也是Sendbyte,如果是这样,我不明白为什么stm8等待这么快,而stm32却等这么久,还望前辈指导批评!

出0入0汤圆

发表于 2015-7-2 17:44:34 | 显示全部楼层
qq开始学单片机 发表于 2015-7-2 17:33
stm8也是Sendbyte,如果是这样,我不明白为什么stm8等待这么快,而stm32却等这么久,还望前辈指导批评! ...


最好把完整的程序弄上来。
还有,用示波器看看SPI的时钟频率对不对。

出0入0汤圆

 楼主| 发表于 2015-7-2 17:56:30 | 显示全部楼层
lcw_swust 发表于 2015-7-2 17:44
最好把完整的程序弄上来。
还有,用示波器看看SPI的时钟频率对不对。

附件已经上传,因为暂时手上没有示波器,所以没法测量,但是我读过总线的时钟,打印出来的都是正确的.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2015-7-2 18:52:47 | 显示全部楼层
本帖最后由 lcw_swust 于 2015-7-2 18:54 编辑
qq开始学单片机 发表于 2015-7-2 17:56
附件已经上传,因为暂时手上没有示波器,所以没法测量,但是我读过总线的时钟,打印出来的都是正确的. ...


看来还真是这个函数的问题,楼主程序中是这样的:
void UART1_SendByte(u8 data)
{
        USART_SendData(USART1, data);//向串口1发送数据
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}

应交改为下面这样:
void UART1_SendByte(u8 Data)
{
        while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE)==RESET);        //等待"发送寄存器空",也就是等待上次的发送结束
        USART_SendData(USARTx, Data);       
}

你想想看,你的程序“等待发送结束”会占用串口发送1个字节的CPU时间,
而我的程序则不会占用这么久的时间,而且利用了等待标志的时间做其它的事情。

出0入12汤圆

发表于 2015-7-2 21:02:43 | 显示全部楼层
楼主,你难道不知道1个基本原则吗?在中断中最好是只处理标志位。在主循环中处理各种动作。

出0入0汤圆

发表于 2015-7-2 21:25:26 | 显示全部楼层
STM32肯定要比STM8复杂

出0入8汤圆

发表于 2015-7-2 21:27:53 | 显示全部楼层
应该说楼主的编程思想还不能驾驭stm32

出0入0汤圆

发表于 2015-7-2 21:35:31 | 显示全部楼层
ST会不会有要哭的感觉了??

出0入0汤圆

发表于 2015-7-2 21:40:04 | 显示全部楼层
中断, while,... 也是醉了。

出0入0汤圆

 楼主| 发表于 2015-7-2 22:26:11 | 显示全部楼层
lcw_swust 发表于 2015-7-2 18:52
看来还真是这个函数的问题,楼主程序中是这样的:
void UART1_SendByte(u8 data)
{

这我是参考过iboard,原子的代码才这样写的,听前辈一言,胜读四年书,虽然我没读过书,谢谢前辈指导

出0入0汤圆

 楼主| 发表于 2015-7-2 22:27:56 | 显示全部楼层
skynet 发表于 2015-7-2 21:02
楼主,你难道不知道1个基本原则吗?在中断中最好是只处理标志位。在主循环中处理各种动作。 ...

指导,先谢谢前辈指导,因为这个程序我只是单纯 串口接收一个不会中断的bin文档,然后烧进flash,然后就完事了,所以也没有想太多,
敢问前辈,如果像我这个,应该怎么组织好呢?因为要确保要接收到bin

出0入0汤圆

 楼主| 发表于 2015-7-2 22:29:04 | 显示全部楼层
liwei_jlu 发表于 2015-7-2 21:27
应该说楼主的编程思想还不能驾驭stm32

谢谢指导,请问我应该怎么改进好一点,在此先谢前辈批评

出0入0汤圆

 楼主| 发表于 2015-7-2 22:29:55 | 显示全部楼层
steaven2000 发表于 2015-7-2 21:40
中断, while,... 也是醉了。

谢谢前辈批评指导,这while我也不想用,但是我看了很多stm32的书都这样教,请问应该怎么做比较好一点?

出0入0汤圆

 楼主| 发表于 2015-7-2 22:31:09 | 显示全部楼层
lcw_swust 发表于 2015-7-2 18:52
看来还真是这个函数的问题,楼主程序中是这样的:
void UART1_SendByte(u8 data)
{

是不是这样想,只要标志放开了,cpu释放了,直接运行到下次数据来到引发中断,这样cpu不会被阻塞掉?

出0入0汤圆

发表于 2015-7-2 22:37:31 | 显示全部楼层
我用STM32 对STM32自动握手后4.5M波特率接收 写SPI FLASH都没问题, 一个包连接收12+4096+2字节
和电脑连时用1228800(受限PL2303HX最高波特率)
2M 4M 8M Bytes的都用过, SST25 W25的都用过

明显是LZ的代码结构完全不合理...哪有在中断里直接阻塞操作的...

出0入0汤圆

 楼主| 发表于 2015-7-2 22:45:54 | 显示全部楼层
snoopyzz 发表于 2015-7-2 22:37
我用STM32 对STM32自动握手后4.5M波特率接收 写SPI FLASH都没问题, 一个包连接收12+4096+2字节
和电脑连时 ...

这个while是标志位的,lcw_swust前辈指导了一下感觉我学到很多,请问你是怎么做的,能否给我拍一砖,先谢谢!

出0入0汤圆

发表于 2015-7-3 08:51:42 | 显示全部楼层
本帖最后由 steaven2000 于 2015-7-3 08:58 编辑

1、文件通过串口传输需要有传输协议,也就是PC传一段数据,等待MCU处理完给个回应后再接着发下一段。
     如果没有传输协议持续发的话就有些问题了,除非你的SPI FLASH操作足够快,每一个字节收到后都能及时写入;
     或者你的RAM足够大能把文件先全部保存再写入,否则总是存在数据丢失的可能。

2、有传输协议的话参照传输协议看数据是怎么传的,一般来说要么每次传固定数量,比如128字节,或者其他带有明显数据段间隔的信息
     比如以回车结尾等等。这样就好办了,每次接收完整的一段数据,中断只接收并存数组,接收完一段后置标志位,主程序检测标志位
     并处理数据。然后给PC回应,请求下一段数据。

出0入0汤圆

 楼主| 发表于 2015-7-3 09:00:18 | 显示全部楼层
steaven2000 发表于 2015-7-3 08:51
你的字库文件通过什么方式/协议进行串口传输的。也就是说,是一段(一帧)的传,还是一下子全部传下 ...

        由于我不会弄上位机,所以没有任何的传输协议,只能是收一个字节,立马往Flash里面塞,参考过很多人的
烧flash代码,基本就是放中断里面直接往Flash塞,所以我也是这般处理,不过,听各位的狠狠的批评,甚是高兴,
把读Flash和发送串口的操作放在主循环,但是难免也会阻塞,因为Flash用的硬件,里面也有while等待标志位的操作,
所以还请各位狠狠给我一砖,让我,让各位看客知道正确应该如何处理!

出0入0汤圆

发表于 2015-7-3 09:04:09 | 显示全部楼层
qq开始学单片机 发表于 2015-7-3 09:00
由于我不会弄上位机,所以没有任何的传输协议,只能是收一个字节,立马往Flash里面塞,参考过很多人的
...

用过超级终端不(XP自带,WIN7没有的话可以单独下载)?里面有各种文件传输协议,Xmodem,Ymodem,Kermit等待,自己baidu相关协议看看传输过程。

一般用串口升级程序都是用这个,哪能一下子把数据全部传下去呢。传得再快单片机处理不过来肯定不行啊。

出0入0汤圆

 楼主| 发表于 2015-7-3 09:06:52 | 显示全部楼层
steaven2000 发表于 2015-7-3 09:04
用过超级终端不(XP自带,WIN7没有的话可以单独下载)?里面有各种文件传输协议,Xmodem,Ymodem,Kermit ...

谢谢前辈拍砖指导!

出0入0汤圆

 楼主| 发表于 2015-7-3 09:44:23 | 显示全部楼层
在此上传超级终端,发现群里已经有了超级终端的一些使用方法,这里就不作介绍,用了发现真的很不错,下一步看看具体的实现流程

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2015-7-3 10:14:42 | 显示全部楼层
qq开始学单片机 发表于 2015-7-2 22:31
是不是这样想,只要标志放开了,cpu释放了,直接运行到下次数据来到引发中断,这样cpu不会被阻塞掉? ...

你说的我不太理解。
总之,只要“发送寄存器空”就能往“发送寄存器”写入数据,而不必再等待“发送完成”。
USART是CPU之外的一个独立的模块,当“发送寄存器”写入数据后,它会自动向引脚发送数据,不占用CPU。

出0入0汤圆

发表于 2015-7-3 20:11:54 来自手机 | 显示全部楼层
路过,学习

出0入0汤圆

 楼主| 发表于 2015-7-4 00:59:25 | 显示全部楼层
lcw_swust 发表于 2015-7-3 10:14
你说的我不太理解。
总之,只要“发送寄存器空”就能往“发送寄存器”写入数据,而不必再等待“发送完成 ...

明白,谢谢前辈你耐心指导

出0入0汤圆

发表于 2015-7-4 07:02:31 来自手机 | 显示全部楼层
qq开始学单片机 发表于 2015-7-3 09:44
在此上传超级终端,发现群里已经有了超级终端的一些使用方法,这里就不作介绍,用了发现真的很不错,下一步 ...

多谢,手机mark下超级终端

出0入0汤圆

发表于 2017-1-23 07:27:36 | 显示全部楼层
超级终端很好用  mark一下

出0入0汤圆

发表于 2017-3-24 15:10:06 | 显示全部楼层
snoopyzz 发表于 2015-7-2 22:37
我用STM32 对STM32自动握手后4.5M波特率接收 写SPI FLASH都没问题, 一个包连接收12+4096+2字节
和电脑连时 ...

您好,STM32 SPI相关的代码能分享一下吗?刚学习SPI,对NSS和连续收发数据有点疑问。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-28 23:42

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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