历史上的今天
返回首页

历史上的今天

今天是:2024年11月16日(星期六)

2019年11月16日 | 通过软件程序消除单片机由外界干扰产生的异常复位的影响

2019-11-16 来源:eefocus

前言:


首先简单介绍一下外界干扰对单片机的2点影响:


(1)异常复位


在刚上电或外部复位引脚为复位电平时,单片机系统进入一个预定的状态——复位状态。在复位状态下,控制寄存器的值是确定的,而数据寄存器的值是随机的,程序计数器也被赋予一个确定的值。但多数情况下控制寄存器的初始值并非我们需要的,不确定的数据寄存器的值也是无法使用的,需要初始化把它们设置成一个预期的、确定的且安全的状态。初始化完成后,系统进入待命状态。系统在工作过程中,因来自电源的干扰,也可能执行复位操作,称为异常复位,这时如不采取措施,记录工作过程的数据又会被初始化,从而造成异常停机。


(2)程序跑飞


所谓程序跑飞是程序没按预定的顺序执行。因为单片机执行了不该执行的指令,该指令一旦执行,系统的状态就发生改变且不能自动恢复,这时,系统处于失控制状态。


问题分析:


这里我们主要针对STM8S105系列单片机提出一种软件抗干扰的措施:


存在问题:使用STM8S105单片机控制电机正反转工作时,继电器的吸合和断开会对单片机产生电磁波干扰,使得单片机出现异常复位情况,造成系统停机。通过示波器检测单片机VCC,发现在继电器动作瞬间会对VCC产生较大冲击。


解决方案:


(1)硬件:合理布板;退耦、滤波以及隔离;加屏蔽(针对强电磁干扰下)


(2)软件:由于控制系统是通过计时器和外部端口的状态变化来驱动系统工作的,并通过数据寄存器记录工作过程,如果在异常复位的前后我们能保护记录工作过程的数据不变,在复位后系统就会继续工作,如同没发生过干扰一样。故我们应该将程序运行过程中的数据保存在数据寄存器中记录下当前运行位置。


解决过程:


(1)判断单片机是否产生EMS复位


STM8S105单片机为了避免由电磁干扰造成的对应用程序误写操作或系统挂起,大多数关键寄存器都有一个互补寄存器与之相对应。系统将会自动检测这些关键寄存器与其互补寄存器之间是否匹配。如果不匹配,则产生一个EMS复位,从而使应用程序恢复到正常操作。


如何判断单片机是EMS复位还是其他情况的复位(STM8S系列单片机有9个复位源):


通过IAR开发环境在线调试程序,观察当单片机受干扰复位时,复位状态寄存器(RST_SR)各个位的状态值。当位4置1时说明产生了EMC复位。 

                      

 (2)配置相关数据寄存器用于保存项目程序运行中的数据


STM8S105系列单片机中有最多32K字节Flash和多达1K字节真正的数据EEPROM,可以保证数据在掉电后不丢失。这里我们采用EEPROM存储数据。


数据EEPROM(DATA)区域可用于存储用户具体项目所需的数据。默认情况下,DATA区域是写保护的,这样可以在主程序工作在IAP模式时防止DATA区域被无意地修改。只有使用特定的MASS密钥才能对DATA区域的写保护解锁。


相关程序:


chipeeprom.h头文件:


#ifndef _chipeeprom_h_

#define _chipeeprom_h_

/* 说明:主芯片STM8S105C4T6*/

/* 自定义宏 */

extern void WriteMultiBlockByte(u8 BlockStartAddress,FLASH_MemType_TypeDef


      FLASH_MemType, FLASH_ProgramMode_TypeDefFLASH_ProgMode, uint8_t *Buffer,uint8_t BlockNum);

extern void ReadMultiBlockByte(u8 BlockStartAddress,uint8_t BlockNum,

                        uint8_t ReadBlockByte[]);


chipeeprom.c源文件:


#include "include.h"

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

****函数名称:

****函数功能:任意写多个Block字节

****入口参数:

          BlockStartAddress    字节被写入的Block首地址

          FLASH_MemType        FLASH Memory操作类型

          FLASH_ProgMode       FLASH 编程模式

          Buffer               要写进flash eeprom 的字节数组

          BlockNum             要写进flash eeprom 的Block个数

****出口参数:无

****说明:每种型号的EEPROM的大小不一样,调用此函数的时候要注意将要写进的字节数组

         的大小是否超过该型号的EEPROM的地址。

         大容量的EEPROM的型号是STM8S208, STM8S207, STM8S007, STM8AF52Ax, STM8AF62Ax 

         EEPROM的地址是从0x004000到0x0047ff,共2048Byte,每个Block是128Byte,一共16个Block.

         中容量的EEPROM的型号是STM8S105, STM8S005, STM8AF626x

         EEPROM的地址是从0x004000到0x0043ff,共1024Byte,每个Block是128Byte,一共8个Block.

         小容量的EEPROM的型号是STM8S103, STM8S003, STM8S903 

         EEPROM的地址是从0x004000到0x00427f,共1024Byte,每个Block是64Byte,一共10个Block.

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

void WriteMultiBlockByte(u8 BlockStartAddress,FLASH_MemType_TypeDef FLASH_MemType, 

                FLASH_ProgramMode_TypeDef FLASH_ProgMode, uint8_t *Buffer,uint8_t BlockNum)

{

  uint8_t  BlockNum_Temp;

  /* 解锁 flash data eeprom memory */

  FLASH_Unlock(FLASH_MEMTYPE_DATA);

  /* 等待 Data EEPROM area 解锁标志位置位*/

  while (FLASH_GetFlagStatus(FLASH_FLAG_DUL) == RESET) ;

  for(BlockNum_Temp=BlockStartAddress;BlockNum_Temp  {

      if(BlockNum_Temp>FLASH_DATA_BLOCKS_NUMBER)

         break;

      FLASH_ProgramBlock(BlockNum_Temp, FLASH_MemType, FLASH_ProgMode,Buffer+BlockNum_Temp*FLASH_BLOCK_SIZE);

      FLASH_WaitForLastOperation(FLASH_MemType);

  }

  FLASH_Lock(FLASH_MEMTYPE_DATA);/*操作完要加锁*/

}

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

****函数名称:

****函数功能:任意读多个Block字节

****入口参数:

         BlockStartAddress    读Block首地址

         BlockNum                 读多少Block

         ReadBlockByte[]       存放读到字节的数组

****出口参数:无

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

void ReadMultiBlockByte(u8 BlockStartAddress,uint8_t BlockNum,uint8_t ReadBlockByte[])

{

    uint32_t add, start_add, stop_add;

    start_add = FLASH_DATA_START_PHYSICAL_ADDRESS+(u32)((BlockNum-1)*FLASH_BLOCK_SIZE);

    stop_add = FLASH_DATA_START_PHYSICAL_ADDRESS + (u32)(BlockNum*FLASH_BLOCK_SIZE);

    for (add = start_add; add < stop_add; add++)

        ReadBlockByte[add-FLASH_DATA_START_PHYSICAL_ADDRESS]=FLASH_ReadByte(add);

}


主函数(这里只列举了关于EEPROM读写的相关程序代码)


#include "include.h"


u8 WriteBuffer[FLASH_BLOCK_SIZE];  //设置一个数组用于保存程序运行中的数据

u8 ReadBuffer[FLASH_BLOCK_SIZE];


void main(void)

{


      ......


      WriteMultiBlockByte(0,FLASH_MEMTYPE_DATA,FLASH_PROGRAMMODE_STANDARD,WriteBuffer,1);


      ......


       ReadMultiBlockByte(0,1,ReadBuffer);


}

推荐阅读

史海拾趣

Antiference公司的发展小趣事

在追求经济效益的同时,Antiference公司始终不忘履行社会责任。公司积极参与环保事业,推动绿色生产,努力降低生产过程中的能耗和排放。此外,Antiference还积极投身公益事业,支持教育事业和扶贫工作,为社会做出了积极贡献。

绿索超容(GreenSource)公司的发展小趣事

在追求经济效益的同时,Antiference公司始终不忘履行社会责任。公司积极参与环保事业,推动绿色生产,努力降低生产过程中的能耗和排放。此外,Antiference还积极投身公益事业,支持教育事业和扶贫工作,为社会做出了积极贡献。

Comax Industrial Co Ltd公司的发展小趣事

随着公司的不断发展壮大,Comax Industrial Co Ltd公司开始积极拓展市场。公司不仅在国内市场取得了显著的成绩,还积极进军国际市场,与多个国家和地区的客户建立了稳定的合作关系。通过参加国际展会、建立海外分支机构等方式,公司的业务范围逐渐扩大,市场份额也持续提升。这种市场拓展的策略,使得Comax实现了跨越式的发展。

德芯半导体(Doeshare)公司的发展小趣事

德芯半导体自成立以来,就致力于半导体技术的研发与创新。公司拥有一支由电子学材料学博士、硕士和教授组成的专家团队,他们不断在半导体MEMS技术上取得突破。这些技术创新不仅推动了产品的发展,还使德芯半导体在智能家居、智能制造等领域的应用中取得了显著的成绩。公司通过与国内外先进企业的合作,采用OEM的合作方式,委托完成关键的工序工艺,确保了产品的高品质。

驰兴电感(Coilank)公司的发展小趣事

驰兴电感自成立之初,就深知技术创新对于企业发展的重要性。公司投入大量资源进行研发,成功推出了一系列全自动、小型化的SMD绕线电感产品。这些产品不仅具有更高的性能和稳定性,而且满足了市场对小型化、轻量化的需求,迅速在市场上获得了广泛的认可。驰兴电感凭借技术创新的优势,逐渐在电子行业中崭露头角。

AOS公司的发展小趣事

随着技术的不断发展和市场的扩大,AOS公司开始积极寻求全球扩张的机会。1998年,AOS在南京独资成立了中国总部,开始了其在中国的深耕之旅。通过多年的努力,AOS在中国建立了完善的产研基地和销售网络,其产品横跨家用和商用两大领域,赢得了广大消费者的信任和喜爱。如今,AOS已成为中国市场上备受推崇的热水设备品牌之一。

问答坊 | AI 解惑

156最后一个

还想看看吗。…

查看全部问答>

这个图小字部分看得清么?

小弟入行不深,在网上看到了这,但是最左边是在看不清楚,请大大们帮忙解释下。 …

查看全部问答>

QuartusII10.0 Bug汇总

QuartusII 10.0 的新颖之处的确吸引着大家,但是由于是用QT重写了quartus,可能很多地方存在bug 1。有没有安装完10.0之后并口下载线无法找到的?我的bbii不能用了!!! 声明一下,我的系统是重新装的,没有老版本的quartus存在!直接安装的10. ...…

查看全部问答>

DM9000驱动的问题

我用的是Mini2440开发板,板载的DM9000网卡的INT端接在SCS2440芯片上的EINT7上。在为uC/OS-II编写驱动时,请求EINT7中断就会死机。 代码如下: [code]…

查看全部问答>

想做一个usb驱程该从何入手啊

如题,对如何写驱程还不了解?正在看接口,还需要学什么呢?不同的设备所编写的驱程一样吗? …

查看全部问答>

麻烦帮分析一下这个ppp数据包

从“0x00,0x32”后面开始就不知道什么意思了 {0xff,0x03,0xc0,0x21,0x01,0x00,0x00,0x32,0x02,0x06,0,0,0,0,0x05,0x06,0x02,0xb6,0x5f,0x43,0x07,0x02,0x08,0x02,0x0d,0x03,0x06,0x11,0x04,0x06,0x4e,0x13,0x17,0x01,0x6c,0xf1,0x2d,0x0c,0x43,0x2 ...…

查看全部问答>

CMD文件

请问.cmd文件有固定格式没?2812的程序是不是都要用到.lib文件?.lib文件可否看到内容?是不是只有4个.lib文件? [ad.c] \"C:\\CCStudio_v3.1\\C2000\\cgtools\\bin\\cl2000\" -g -fr\"C:/CCStudio_v3.1/examples/MyProjects/ads/Debug\" -d\"_DEB ...…

查看全部问答>

外部数据总线与处理器速度

32位处理器,16位外部数据总线,总线周期为0.00005s.该处理器可以支持的最大数据传送速度为多少?外部数据总线增加到21位或者外部时钟频率增加,哪种更能提高处理器性能?…

查看全部问答>

ADC08100,很适合做数字示波器

本帖最后由 dontium 于 2015-1-23 12:59 编辑   ti./lit/ds/symlink/adc08100.pdf     ADC08100 ADC08060   ADC08200   ADC08B200   ADC08L060   Resolution (Bits) 8   &nb ...…

查看全部问答>

求actel LiberoI 破解码

江湖救急,大侠们帮帮忙…

查看全部问答>