历史上的今天
今天是: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); }
上一篇:单个按键,实现单击+双击+长按
史海拾趣
|
QuartusII 10.0 的新颖之处的确吸引着大家,但是由于是用QT重写了quartus,可能很多地方存在bug 1。有没有安装完10.0之后并口下载线无法找到的?我的bbii不能用了!!! 声明一下,我的系统是重新装的,没有老版本的quartus存在!直接安装的10. ...… 查看全部问答> |
|
我用的是Mini2440开发板,板载的DM9000网卡的INT端接在SCS2440芯片上的EINT7上。在为uC/OS-II编写驱动时,请求EINT7中断就会死机。 代码如下: [code]… 查看全部问答> |
|
从“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 ...… 查看全部问答> |
|
32位处理器,16位外部数据总线,总线周期为0.00005s.该处理器可以支持的最大数据传送速度为多少?外部数据总线增加到21位或者外部时钟频率增加,哪种更能提高处理器性能?… 查看全部问答> |
|
本帖最后由 dontium 于 2015-1-23 12:59 编辑 ti./lit/ds/symlink/adc08100.pdf ADC08100 ADC08060 ADC08200 ADC08B200 ADC08L060 Resolution (Bits) 8 &nb ...… 查看全部问答> |




