记一次stm8l程序跑飞

2019-12-02来源: eefocus关键字:stm8l  程序跑飞  主控

项目使用stm8l051f3做主控,CC2500做数据接收,不发送。


跑飞的现象就是,刚开始能运行,经过一段未知长度的时间,有可能是3分钟,有可能是30分钟,指示灯不再闪烁,中断按键单片机无反应。


接入调试器发现跑到了一个非常大的地址,已经超过了mcu的内部flash空间。可以确定是程序跑飞。


经验是:


程序跑飞,查条件语句是否都有做处理。


程序跑飞,查内存溢出。


查了好久,查出是内存溢出导致。


因为发送端发送的数据固定是32字节,所以在接收端只开辟了一个32字节的buffer去读取收到的数据。


/*******************************************************************************  

* @brief GDO2中断处理函  

* @param None

* @retval None

****************************************************************Author:Liming**/

void GDO2_Int(void)

{

    uint8_t temp;

    unsigned char RecvBuffer[0x20]={0};//开辟32字节缓存

    unsigned char RecvLength;

    if(EXTI_GetITStatus(EXTI_IT_Pin6) != RESET)

    {

        EXTI_ClearITPendingBit(EXTI_IT_Pin6);

        DelayNms(1);//等待接收完成

        RecvLength = CC2500Recv(RecvBuffer); //获取收到的数据长度

            

        temp = ProPacketCheck(RecvBuffer,RecvLength,0x0001,0x0003);//数据完整性校验

        

        if((temp == 0x04)||(temp==0xff))   // 本机和广播信息需要处理

        {            

        //数据处理


            CC2500SetState(CC2500_STATUS_POWERDOWN_LEVEL2);            

        }

        else

            CC2500SetState(CC2500_STATUS_RECEIVE);

    }

}

 


//接收数据

unsigned char CC2500Recv(unsigned char *Buffer,unsigned char Mode)

{

  unsigned char Result=0x00,Status=0x00;

  switch(CC2500State)

  {

  case 0x00:

  case 0x01:

    if(CC2500State) Delayms(0x07);

    else Delayus(0x30);

    Status=CC2500SpiReadStatus(RXBYTES);

    if(Status&0x80)//如果数据长度超过64字节

    {

      CC2500SpiReadBuffer(FIFO,Buffer,0x40);//读取64字节

      Result=0x40;

    }

    else if(Status&0x7F)

    {

      CC2500SpiReadBuffer(FIFO,Buffer,Status&0x7F);//读取收到的数据

      Result=Status&0x7F;

    }

    CC2500SetState(Mode);

    break;

  }

  return Result;//返回读取的数据长度

}

 


但由于无线信号的干扰,CC2500可能会收到大于32字节的数据(虽然不是本系统需要的),


导致在从cc2500取出的时候,存入buffer的长度超过开辟的buffer空间。


解决办法1:既然知道是32字节数据,可以在


    CC2500Recv接收函数里只接收32字节。

    if(Status&0x80)//如果数据长度超过64字节

    {

      CC2500SpiReadBuffer(FIFO,Buffer,0x20);//读取32字节

      Result=0x20;

    }

    else if(Status&0x7F)

    {

      CC2500SpiReadBuffer(FIFO,Buffer,0x20);//读取收到的数据

      Result=0x20;

    }

 

解决办法2:


    GDO2_Int函数里开辟64字节空间即便是收到最多的数据也不会超出缓存空间。

    unsigned char RecvBuffer[0x40]={0};//开辟64字节缓存

有了这次的程序跑飞的处理经历,再次验证了程序跑飞大部分都是内存溢出导致的说法。


关键字:stm8l  程序跑飞  主控 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic481696.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM8L052C6T6液晶LCD驱动过程
下一篇:stm8s 定时器2测量脉冲宽度(单位 us)

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM8L读写EEPROM(24LC64)
使用24LC64(24XX64)是低功耗应用的EEPROM,存储容量 8K byte(64K bit),IIC 最大时钟频率400 KHz(24FC64达到1MHz),低功耗CMOS技术:工作电流 1 mA(典型)、 待机电流 1 μ A(典型),32字节的页写缓冲器,超过100万擦/写周期,数据保存>200年。24C02只有8字节的页写缓冲器,操作的地址只有8位,而24LC64操作的地址包含高8位和低8位。两者的数据手册去区别如下:1、AT24C02页写时序:2、24LC64页写时序:STM8L的程序设计如下:(1)数据的页写操作:(2)数据的连续读取:
发表于 2019-12-03
STM8L读写EEPROM(24LC64)
STM8L052C6T6液晶LCD驱动过程
; for (counter = 0; counter <= LCD_RAMRegister_13; counter++)    {        LCD->RAM[counter] = 0xff;    }}下面着重记录一下踩过的坑:LCD_Init();函数里面的最后一个参数是LCD_VoltageSource_Internal还是LCD_VoltageSource_External官方STM8L-DISCOVERY的原理图上[object Object]R25这个0R电阻没有焊接,所以代码里使用的是
发表于 2019-12-02
STM8L052C6T6液晶LCD驱动过程
stm8l151低功耗程序架构
最近帮医院做了一款体温记录仪,整个硬件方案资源是:stm8L151 + NTC*2 + EEPROM + 锂电池充电保护电路 + 18mAh纽扣电池;软件逻辑是,每隔一分钟,采样两路温度并保存在EEP里;通过USB转TTL,上位机能够读取,展示温度曲线,最大最小平均值等简单的运算;整个方案很简单,但也走了不少弯路......单片机程序框架之伪代码:void main(void){    CLK_Config();    GPIO_Config();    ADC_Config();    USART_Config();   
发表于 2019-12-02
STM8L的LCD接口详解及驱动程序
STM8L部分型号集成了段式液晶驱动器,可以驱动4*28=112个液晶段.段式液晶屏为低功耗显示器件,功耗根据屏的大小和显示段数会有所不同,通常功耗在10ua左右.生活中,数字电子表,数字万用表,数显温度计等,使用的都是段式液晶屏,通常一颗纽扣电池可以保证设备间隔不断显示数字两年或更久.大家比较熟悉的液晶屏1602模块其实也是段式液晶,是一个有很多段的点组成的,由于点比较多,所以1602模块集成了驱动芯片,我们只需给1602送数据,就可以控制1602进行显示了.液晶本身不会发光,1602之所以会发光是因为使用了LED背光板.段式液晶驱动器,通常会含有一个电压泵,一个频率分频器.电压泵用来提供驱动液晶段的电压,电压的高低决定着显示
发表于 2019-11-29
STM8L的LCD接口详解及驱动程序
STM8L的EEPROM读写原理及例程
STM8L103C6拥有1KB的片上EEPROM,可以用来存储程序需要用到的参数,就不需要额外使用24C02这样的外部存储器了.同时,和24C02比起来,STM8L的片上EEPROM操作更简单,可以直接对地址进行操作,进行数据读写.下图是STM8L闪存和EEPROM的地址分配图,可以看到EEPROM的起始地址为0x001000,结束地址为0x0013FF.共1024个地址空间,所以EEPROM的容量为1KB.EEPROM在上电复位后是写保护的,在向其中写入数据时,需要解锁,关闭写保护.解锁流程为:①第一次向FLASH_DUKR写入密钥0xAE②第二次向FLASH_DUKR写入密钥0x56两次都写入正确后,写保护功能被关闭,可以对
发表于 2019-11-25
STM8L的EEPROM读写原理及例程
51系列单片机程序跑飞的经验总结
 一、 程序运行跑飞现象:单片机中的程序计数器(PC)的值出乎我们所需要的,发生了异常的偏移,脱离了原本设定好的程序要执行的位置,进入原定程序以外的区域,例如:程序的空白区、程序以外的空间或者是某种死循环中。二、 跑飞的影响:使指令的地址码和操作码发生改变,而PC把操作码当作指令来执行,操作码改变就代表着将执行错误的指令;或者PC的值指向一个不符合逻辑关系的指令或非程序的区域,会造成运行结果进入死循环,即常说的“死机”。三、 程序跑飞的原因:1. 意外中断。打开了某个中断,但是没有响应和清除中断标志,导致程序一直进入中断,造成死机假象。2. 中断变量处理不妥。3. 地址溢出。4. 无条件的死循环。5. 看门狗没有关闭
发表于 2018-11-19
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved