硬汉嵌入式论坛

 找回密码
 立即注册
查看: 6496|回复: 10
收起左侧

[有问必答] 关于STM32+uCOSII 环境下 SPI通信数据不全的问题

[复制链接]

7

主题

10

回帖

31

积分

新手上路

积分
31
发表于 2016-3-22 22:44:44 | 显示全部楼层 |阅读模式
如题,想请教一下论坛上的高手们,我现在的板子是STM32F407 跑的ucOS系统,与一个模块间是SPI的方式进行通信的,现在遇到一个问题,如果说
我不跑系统,裸机进行数据的接收,是一点问题都没有的,模块发过来100KB的数据,我收到的就是100K数据,但是我上了操作系统后,我发现数据只能
接收到一大部分,也就是68K左右,我的SPI是中断方式接收的,没有开DMA,我想问一下大家是如何做的用操作系统还是可以进行SPI高速通信的。
我的任务其实也不多,就3个任务。来回的切换,可就是影响到了STM32 SPI中断的数据收发了。难道任务的切换会影响进出中断收数据吗?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2016-3-22 22:49:18 | 显示全部楼层
对于楼主的应用来说,把SysTick,即滴答定时器的中断也设置为最低优先级,另外配置NVIC的优先级分组为4,将SPI中断优先级高于15即可。

看看是否好用了些。不好用的话,我们再做进一步的交流。

PS:对于带RTOS的中断设计,强烈建议将NVIC优先级分组设置为4.
回复

使用道具 举报

7

主题

10

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2016-3-23 12:09:06 | 显示全部楼层

回 eric2013 的帖子

eric2013:对于楼主的应用来说,把SysTick,即滴答定时器的中断也设置为最低优先级,另外配置NVIC的优先级分组为4,将SPI中断优先级高于15即可。

看看是否好用了些。不好用的话,我们再做进一步的交流。

PS:对于带RTOS的中断设计,强烈建议将NVIC优先级分组设置为4.
....... (2016-03-22 22:49) 
我把SysTick_IRQn  配置成了  15   SPI中断配置成了 0    但是还是会比 没有操作系统的情况 少接收一半的数据呢
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2016-3-23 13:49:23 | 显示全部楼层

回 gejinglei 的帖子

gejinglei:

我把SysTick_IRQn  配置成了  15   SPI中断配置成了 0    但是还是会比 没有操作系统的情况 少接收一半的数据呢  
进入调试状态,全速运行,查看这个滴答定时器是否确定是最低的15,即这里的240.
1.png
回复

使用道具 举报

7

主题

10

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2016-3-23 14:11:55 | 显示全部楼层
貌似 是的
QQ截图20160323141141.jpg
回复

使用道具 举报

7

主题

10

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2016-3-23 14:13:33 | 显示全部楼层

回 eric2013 的帖子

eric2013:进入调试状态,全速运行,查看这个滴答定时器是否确定是最低的15,即这里的240.

 (2016-03-23 13:49) 
是240 。。。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2016-3-23 14:23:04 | 显示全部楼层
优先级分组设置了吧,另外我看下你的SPI中断的实现
回复

使用道具 举报

7

主题

10

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2016-3-23 14:30:46 | 显示全部楼层
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);


void SPI1_IRQHandler(void)
{
    INT8U err;
    OS_CPU_SR cpu_sr;
    OS_ENTER_CRITICAL();                             
    OSIntNesting++;               
    OS_EXIT_CRITICAL();        
   
    if(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)==SET)
    {   
                SPI_I2S_ClearITPendingBit(SPI1, SPI_I2S_FLAG_RXNE);         
        sram1[RxCounter1++] = SPI1_RecvByte();
    }  
        OSIntExit();
}
回复

使用道具 举报

7

主题

10

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2016-3-23 14:31:20 | 显示全部楼层

回 eric2013 的帖子

eric2013:优先级分组设置了吧,另外我看下你的SPI中断的实现 (2016-03-23 14:23) 
void SPI1_Init(void)
{     
  GPIO_InitTypeDef  GPIO_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//ê1ÄüGPIOBê±Öó
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//ê1ÄüGPIOBê±Öó
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);//ê1ÄüSPI1ê±Öó

  //GPIOFB3,4,53õê¼»ˉéèÖÃ
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;//PB3~5¸′óÃ1|Äüêä3ö   
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//¸′óÃ1|Äü
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//íÆíìêä3ö
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//éÏà-
  GPIO_Init(GPIOB, &GPIO_InitStructure);//3õê¼»ˉ
   
    GPIO_PinAFConfig(GPIOB,GPIO_PinSource3,GPIO_AF_SPI1); //PB3¸′óÃÎa SPI1
    GPIO_PinAFConfig(GPIOB,GPIO_PinSource4,GPIO_AF_SPI1); //PB4¸′óÃÎa SPI1
    GPIO_PinAFConfig(GPIOB,GPIO_PinSource5,GPIO_AF_SPI1); //PB5¸′óÃÎa SPI1

    //ÕaàïÖ»Õë¶ÔSPI¿ú3õê¼»ˉ
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,ENABLE);//¸′λSPI1
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,DISABLE);//í£Ö1¸′λSPI1

    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //éèÖÃSPIμ¥Ïò»òÕßË«ÏòμÄêy¾YÄ£ê½:SPIéèÖÃÎaË«ÏßË«Ïòè«Ë«1¤
    SPI_InitStructure.SPI_Mode = SPI_Mode_Slave ;        //éèÖÃSPI1¤×÷Ä£ê½:éèÖÃÎaÖ÷SPI
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;        //éèÖÃSPIμÄêy¾Y′óD¡:SPI·¢Ëí½óêÕ8λ֡½á11
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;        //′®DDí¬2½ê±ÖóμÄ¿ÕÏD×′ì¬Îa¸ßμçÆ½
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;    //′®DDí¬2½ê±ÖóμÄμú¶t¸öìø±äÑØ£¨éÏéy»òϽ죩êy¾Y±»2éÑù
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;        //NSSDÅoÅóéó2¼t£¨NSS1ü½Å£©»1êÇèí¼t£¨ê1óÃSSI룩1üàí:Äú2¿NSSDÅoÅóDSSIλ¿ØÖÆ
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;        //¶¨òå2¨ìØÂêÔ¤·ÖÆμμÄÖμ:2¨ìØÂêÔ¤·ÖÆμÖμÎa256
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;    //Ö¸¶¨êy¾Y′«êä′óMSBλ»1êÇLSBλ¿aê¼:êy¾Y′«êä′óMSBλ¿aê¼
    SPI_InitStructure.SPI_CRCPolynomial = 7;    //CRCÖμ¼ÆËãμĶàÏîê½
    SPI_Init(SPI1, &SPI_InitStructure);  //¸ù¾YSPI_InitStructÖDÖ¸¶¨μÄ2Îêy3õê¼»ˉíaéèSPIx¼Ä′æÆ÷

    NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
   
    SPI_I2S_ITConfig(SPI1,SPI_I2S_IT_RXNE,ENABLE);
   
    SPI_Cmd(SPI1, ENABLE); //ê1ÄüSPIíaéè
   
    //SPI1_ReadWriteByte(0xff);//Æô¶ˉ′«êä            
}
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2016-3-23 14:42:26 | 显示全部楼层

回 gejinglei 的帖子

gejinglei:void SPI1_Init(void)
{    
  GPIO_InitTypeDef  GPIO_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;
....... (2016-03-23 14:31) 
我现在觉得有这么两种可能
1. 你的任务里面没有做开关中断操作吧,能不用的尽量别用,可以用调度锁代替
2. 你降低下你的SPI的首发速度,降低为10KHz,看看还有问题不,另外就是uCOS-II源码中
    有很多处开关中断的操作,一定程度上会增加中断延迟时间,容易丢失。
    你可以单独仅使用一个用户测试下。任务里面仅加上个延迟函数,测试下看看。
回复

使用道具 举报

7

主题

10

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2016-3-23 14:46:48 | 显示全部楼层

回 eric2013 的帖子

eric2013:我现在觉得有这么两种可能
1. 你的任务里面没有做开关中断操作吧,能不用的尽量别用,可以用调度锁代替
2. 你降低下你的SPI的首发速度,降低为10KHz,看看还有问题不,另外就是uCOS-II源码中
    有很多处开关中断的操作,一定程度上会增加中断延迟时间,容 .. (2016-03-23 14:42) 
好的 谢谢

我任务里没做开关中断的操作

SPI的发送速度不能降低,因为是供应商的SPI发送,我负责接收。
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-14 02:02 , Processed in 0.049521 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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