独闷闷网

 找回密码
 立即注册
搜索
查看: 3084|回复: 1
收起左侧

[原创] stm8自带的spi从机不稳定,因此把io口模拟spi的程序和注意问题分享给大家。

[复制链接]
发表于 2015-6-10 18:25:40 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

x
本帖最后由 jianhong_wu 于 2015-6-17 13:39 编辑

★坚鸿-深圳:
       今天测试后发现,stm8自带的spi从机不稳定,发现只要中途一旦数据出错或者错位,那么后面接收到的数据就全部是错位或者说是错的,所以不得不放弃。后来我改用io口模拟spi,仅占用一个io口电平中断就可以了,但是有个地方大家一定要注意,就是务必保持这个电平中断是最高优先级的中断,可以让它抢占和嵌套任何中断,否则数据不稳定。我一开始的时候系统用了定时中断和电平中断,发现数据还是偶尔出错,后来把定时中断关闭了,只留电平中断,就没有再出现这个问题。这个现象告诉我们,以后凡是单片机通讯,就应该把通讯的相关中断设置为最高优先级,并且允许它抢占和嵌套任何中断。现在把stm8s105单片机的spi代码分享给大家,我是用IAR的编译环境,用stm8的库函数。
spi从机的初始化:
  1.     GPIO_Init(GPIOC,GPIO_PIN_6, GPIO_MODE_IN_FL_NO_IT);  //DATA线
  2.     GPIO_Init(GPIOC,GPIO_PIN_5, GPIO_MODE_IN_FL_NO_IT);  //CLK线


  3.       
  4.     GPIO_Init(GPIOC,GPIO_PIN_2, GPIO_MODE_IN_FL_IT);   //CE线,中断
  5.     EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOC,EXTI_SENSITIVITY_FALL_ONLY);  
复制代码


spi从机的CE电平中断接收一个字节代码:
  1. INTERRUPT_HANDLER(EXTI_PORTC_IRQHandler, 5)   //CE的下降沿产生的电平中断
  2. {
  3.   /* In order to detect unexpected events during development,
  4.      it is recommended to set a breakpoint on the following instruction.
  5.   */
  6.    unsigned char ucSpiReadData=0;  //必须初始化为0,很关键!
  7.    unsigned char i;
  8.    

  9.    for(i=0;i<8;i++)
  10.    {
  11.      
  12.       ucSpiReadData=ucSpiReadData<<1;

  13.       while(GPIO_ReadInputPin(GPIOC,GPIO_PIN_5)==0)  //时钟线
  14.       {
  15.         if(GPIO_ReadInputPin(GPIOC,GPIO_PIN_2)!=0)
  16.         {
  17.            break;
  18.         }
  19.       }
  20.       
  21.       if(GPIO_ReadInputPin(GPIOC,GPIO_PIN_6)!=0)  //不能是1,只能判断非0.因为GPIO_ReadInputPin库函数读取的高电平不是1,而是非0。
  22.       {
  23.          ucSpiReadData=ucSpiReadData+1;
  24.       }
  25.       
  26.       while(GPIO_ReadInputPin(GPIOC,GPIO_PIN_5)!=0)  //时钟线,不能是1,只能判断非0.因为GPIO_ReadInputPin库函数读取的高电平不是1,而是非0。
  27.       {
  28.         if(GPIO_ReadInputPin(GPIOC,GPIO_PIN_2)!=0)
  29.         {
  30.            break;
  31.         }
  32.       }

  33.    }
  34.    
  35.    ucSpiBufferRecieve[ucSpiBufferCnt]=ucSpiReadData;
  36.    if(ucSpiBufferCnt<const_spi_recieve_max)
  37.    {
  38.       ucSpiBufferCnt++;
  39.    }

  40.    ucSpiTimeFlag=0;   //把累加时间清零
  41.   
  42. }
复制代码


乐于分享,勇于质疑!
发表于 2015-6-10 21:20:21 | 显示全部楼层
感谢鸿哥 !
乐于分享,勇于质疑!
回复

使用道具 举报

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

本版积分规则

QQ|Archiver|手机版|独闷闷网 ( 粤ICP备12007667号-2 )

GMT+8, 2019-10-18 06:49 , Processed in 0.105251 second(s), 18 queries .

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