STM32单片机裸机程序:高级实现实时性处理方法
cathy 在 提交
cathy 在 提交
1、在元器件的布局方面,应该把相互有关的元件尽量放得靠近一些,例如,时钟发生器、晶振、CPU的时钟输入端都易产生噪声,在放置的时候应把它们靠近些。
对于那些易产生噪声的器件、小电流电路、大电流电路开关电路等,应尽量使其远离单片机的逻辑控制电路和存储电路(ROM、RAM),如果可能的话,可以将这些电路另外制成电路板,这样有利于抗干扰,提高电路工作的可靠性。
2、尽量在关键元件,如ROM、RAM等芯片旁边安装去耦电容。实际上,印制电路板走线、引脚连线和接线等都可能含有较大的电感效应。大的电感可能会在Vcc走线上引起严重的开关噪声尖峰。
防止Vcc走线上开关噪声尖峰的方法,是在VCC与电源地之间安放一个0.1uF的电子去耦电容。如果电路板上使用的是表面贴装元件,可以用片状电容直接紧靠着元件,在Vcc引脚上固定。是使用瓷片电容,这是因为这种电容具有较低的静电损耗(ESL)和高频阻抗,另外这种电容温度和时间上的介质稳定性也很不错。尽量不要使用钽电容,因为在高频下它的阻抗较高。
在安放去耦电容时需要注意以下几点:
在印制电路板的电源输入端跨接100uF左右的电解电容,如果体积允许的话,电容量大一些则更好。
原则上每个集成电路芯片的旁边都需要放置一个0.01uF的瓷片电容,如果电路板的空隙太小而放置不下时,可以每10个芯片左右放置一个1~10的钽电容。
对于抗干扰能力弱、关断时电流变化大的元件和RAM、ROM等存储元件,应该在电源线(Vcc)和地线之间接入去耦电容。
电容的引线不要太长,特别是高频旁路电容不能带引线。
3、在单片机控制系统中,地线的种类有很多,有系统地、屏蔽地、逻辑地、模拟地等,地线是否布局合理,将决定电路板的抗干扰能力。在设计地线和接地点的时候,应该考虑以下问题:
逻辑地和模拟地要分开布线,不能合用,将它们各自的地线分别与相应的电源地线相连。在设计时,模拟地线应尽量加粗,而且尽量加大引出端的接地面积。一般来讲,对于输入输出的模拟信号,与单片机电路之间通过光耦进行隔离。
在设计逻辑电路的印制电路版时,其地线应构成闭环形式,提高电路的抗干扰能力。
地线应尽量的粗。如果地线很细的话,则地线电阻将会较大,造成接地电位随电流的变化而变化,致使信号电平不稳,导致电路的抗干扰能力下降。在布线空间允许的情况下,要保证主要地线的宽度至少在2~3mm以上,元件引脚上的接地线应该在1.5mm左右。
要注意接地点的选择。当电路板上信号频率低于1MHz时,由于布线和元件之间的电磁感应影响很小,而接地电路形成的环流对干扰的影响较大,所以要采用一点接地,使其不形成回路。当电路板上信号频率高于10MHz时,由于布线的电感效应明显,地线阻抗变得很大,此时接地电路形成的环流就不再是主要的问题了。所以应采用多点接地,尽量降低地线阻抗。
电源线的布置除了要根据电流的大小尽量加粗走线宽度外,在布线时还应使电源线、地线的走线方向与数据线的走线方身一致在布线工作的,用地线将电路板的底层没有走线的地方铺满,这些方法都有助于增强电路的抗干扰能力。
数据线的宽度应尽可能地宽,以减小阻抗。数据线的宽度至少不小于0.3mm(12mil),如果采用0.46~0.5mm(18mil~20mil)则更为理想。
由于电路板的一个过孔会带来大约10pF的电容效应,这对于高频电路,将会引入太多的干扰,所以在布线的时候,应尽可能地减少过孔的数量。再有,过多的过孔也会造成电路板的机械强度降低。
一个单片机应用系统的硬件电路设计包含两部分内容:一是系统扩展,即单片机内部的功能单元,如ROM、RAM、I/O、定时器/计数器、中断系统等不能满足应用系统的要求时,必须在片外进行扩展,选择适当的芯片,设计相应的电路。二是系统的配置,即按照系统功能要求配置外围设备,如键盘、显示器、打印机、A/D、D/A转换器等,要设计合适的接口电路。
系统的扩展和配置应遵循以下原则:
1)尽可能选择典型电路,并符合单片机常规用法。为硬件系统的标准化、模块化打下良好的基础。
2)系统扩展与外围设备的配置水平应充分满足应用系统的功能要求,并留有适当余地,以便进行二次开发。
3)硬件结构应结合应用软件方案一并考虑。硬件结构与软件方案会产生相互影响,考虑的原则是:软件能实现的功能尽可能由软件实现,以简化硬件结构。但必须注意,由软件实现的硬件功能,一般响应时间比硬件实现长,且占用CPU时间。
4)系统中的相关器件要尽可能做到性能匹配。如选用CMOS芯片单片机构成低功耗系统时,系统中所有芯片都应尽可能选择低功耗产品。
5)可靠性及抗干扰设计是硬件设计必不可少的一部分,它包括芯片、器件选择、去耦滤波、印刷电路板布线、通道隔离等。
6)单片机外围电路较多时,必须考虑其驱动能力。驱动能力不足时,系统工作不可靠,可通过增设线驱动器增强驱动能力或减少芯片功耗来降低总线负载。
7)尽量朝“单片”方向设计硬件系统。系统器件越多,器件之间相互干扰也越强,功耗也增大,也不可避免地降低了系统的稳定性。随着单片机片内集成的功能越来越强,真正的片上系统SoC已经可以实现,如ST公司 的μPSD32××系列产品在一块芯片上集成了80C32核、大容量FLASH存储器、SRAM、A/D、I/O、两个串口、看门狗、上电复位电路等等。
单片机系统硬件抗干扰常用方法实践:
影响单片机系统可靠安全运行的主要因素主要来自系统内部和外部的各种电气干扰,并受系统结构设计、元器件选择、安装、制造工艺影响。这些都构成单片机系统的干扰因素,常会导致单片机系统运行失常,轻则影响产品质量和产量,重则会导致事故,造成重大经济损失。
形成干扰的基本要素有三个:
1)干扰源。指产生干扰的元件、设备或信号,用数学语言描述如下:du/dt, di/dt大的地方就是干扰源。如:雷电、继电器、可控硅、电机、高频时钟等都可能成为干扰源。
2)传播路径。指干扰从干扰源传播到敏感器件的通路或媒介。典型的干扰传播路径是通过导线的传导和空间的辐射。
3)敏感器件。指容易被干扰的对象。如:A/D、D/A变换器,单片机,数字IC,弱信号放大器等。干扰的分类干扰的分类有好多种,通常可以按照噪声产生的原因、传导方式、波形特性等等进行不同的分类。按产生的原因分:可分为放电噪声音、高频振荡噪声、浪涌噪声。按传导方式分:可分为共模噪声和串模噪声。按波形分:可分为持续正弦波、脉冲电压、脉冲序列等等。
干扰的耦合方式:
干扰源产生的干扰信号是通过一定的耦合通道才对测控系统产生作用的。因此,有必要看看干扰源和被干扰对象之间的传递方式。干扰的耦合方式,无非是通过导线、空间、公共线等等,细分下来,主要有以下几种:
1)直接耦合:这是直接的方式,也是系统中存在普遍的一种方式。比如干扰信号通过电源线侵入系统。
2)公共阻抗耦合:这也是常见的耦合方式,这种形式常常发生在两个电路电流有共同通路的情况。为了防止这种耦合,通常在电路设计上就要考虑。使干扰源和被干扰对象间没有公共阻抗。
3)电容耦合:又称电场耦合或静电耦合。是由于分布电容的存在而产生的耦合。
4)电磁感应耦合:又称磁场耦合。是由于分布电磁感应而产生的耦合。
5)漏电耦合:这种耦合是纯电阻性的,在绝缘不好时就会发生。
采取的抗干扰主要手段:
常用硬件抗干扰技术
针对形成干扰的三要素,采取的抗干扰主要有以下手段:
1)抑制干扰源
抑制干扰源就是尽可能的减小干扰源的du/dt,di/dt。这是抗干扰设计中先考虑和重要的原则,常常会起到事半功倍的效果。减小干扰源的du/dt主要是通过在干扰源两端并联电容来实现。减小干扰源的di/dt则是在干扰源回路串联电感或电阻以及增加续流二极管来实现。抑制干扰源的常用措施如下:
2)切断干扰传播路径
按干扰的传播路径可分为传导干扰和辐射干扰两类。所谓传导干扰是指通过导线传播到敏感器件的干扰。高频干扰噪声和有用信号的频带不同,可以通过在导线上增加滤波器的方法切断高频干扰噪声的传播,有时也可加隔离光耦来解决。电源噪声的危害,要特别注意处理。所谓辐射干扰是指通过空间辐射传播到敏感器件的干扰。一般的解决方法是增加干扰源与敏感器件的距离,用地线把它们隔离和在敏感器件上加蔽罩。切断干扰传播路径的常用措施如下:
充分考虑电源对单片机的影响。电源做得好,整个电路的抗干扰就解决了一大半。许多单片机对电源噪声很敏感,要给单片机电源加滤波电路或稳压器,以减小电源噪声对单片机的干扰。比如,可以利用磁珠和电容组成π形滤波电路,当然条件要求不高时也可用 100Ω电阻代替磁珠。
如果单片机的I/O口用来控制电机等噪声器件,在I/O口与噪声源之间应加隔离(增加π形滤波电路)。
注意晶振布线。晶振与单片机引脚尽量靠近,用地线把时钟区隔离起来,晶振外壳接地并固定。
电路板合理分区,如强、弱信号,数字、模拟信号。尽可能把干扰源(如电机、继电器)与敏感元件(如单片机)远离。
用地线把数字区与模拟区隔离。数字地与模拟地要分离,在一点接于电源地。A/D、D/A芯片布线也以此为原则。
单片机和大功率器件的地线要单独接地,以减小相互干扰。大功率器件尽可能放在电路板边缘。
在单片机I/O口、电源线、电路板连接线等关键地方使用抗干扰元件如磁珠、磁环、电源滤波器、屏蔽罩,可显著提高电路的抗干扰性能。
3)提高敏感器件的抗干扰性能
提高敏感器件的抗干扰性能是指从敏感器件这边考虑尽量减少对干扰噪声的拾取,以及从不正常状态尽快恢复的方法。提高敏感器件抗干扰性能的常用措施如下:
布线时尽量减少回路环的面积,以降低感应噪声。
布线时,电源线和地线要尽量粗。除减小压降外,更重要的是降低耦合噪声。
对于单片机闲置的I/O口,不要悬空,要接地或接电源。其它IC的闲置端在不改变系统逻辑的情况下接地或接电源。
对单片机使用电源监控及看门狗电路,如:IMP809,IMP706,IMP813, X5043,X5045等,可大幅度提高整个电路的抗干扰性能。
在速度能满足要求的前提下,尽量降低单片机的晶振和选用低速数字电路。
IC器件尽量直接焊在电路板上,少用IC座。
3)其它常用抗干扰措施
交流端用电感电容滤波:去掉高频低频干扰脉冲。
变压器双隔离措施:变压器初级输入端串接电容,初、次级线圈间屏蔽层与初级间电容中心接点接大地,次级外屏蔽层接印制板地,这是硬件抗干扰的关键手段。
次级加低通滤波器:吸收变压器产生的浪涌电压。
采用集成式直流稳压电源:因为有过流、过压、过热等保护。I/O口采用光电、磁电、继电器隔离,同时去掉公共地。
通讯线用双绞线:排除平行互感。防雷电用光纤隔离为有效。
A/D转换用隔离放大器或采用现场转换:减少误差。
外壳接大地:解决人身安全及防外界电磁场干扰。加复位电压检测电路。防止复位不充分CPU就工作,尤其有EEPROM的器件,复位不充分会改变EEPROM的内容。
印制板工艺抗干扰:
电源线加粗,合理走线、接地,三总线分开以减少互感振荡。
CPU、RAM、ROM等主芯片,VCC和GND之间接电解电容及瓷片电容,去掉高、低频干扰信号。
独立系统结构,减少接插件与连线,提高可靠性,减少故障率。
集成块与插座接触可靠,用双簧插座,集成块直接焊在印制板上,防止器件接触不良故障。
有条件采用四层以上印制板,中间两层为电源及地。
本文转载自:网络
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。
单片机主要作用是控制外围的器件,并实现一定的通信和数据处理。但在某些特定场合,不可避免地要用到数学运算,尽管单片机并不擅长实现算法和进行复杂的运算。下面主要是介绍如何用单片机实现数字滤波。
在单片机进行数据采集时,会遇到数据的随机误差,随机误差是由随机干扰引起的,其特点是在相同条件下测量同一量时,其大小和符号会现无规则的变化而无法预测,但多次测量的结果符合统计规律。为克服随机干扰引起的误差,硬件上可采用滤波技术,软件上可采用软件算法实现数字滤波。滤波算法往往是系统测控算法的一个重要组成部分,实时性很强。
采用数字滤波算法克服随机干扰的误差具有以下优点:
1、数字滤波无需其他的硬件成本,只用一个计算过程,可靠性高,不存在阻抗匹配问题。尤其是数字滤波可以对频率很低的信号进行滤波,这是模拟滤波器做不到的。
2、数字滤波使用软件算法实现,多输入通道可共用一个滤波程序,降低系统开支。
3、只要适当改变滤波器的滤波程序或运算,就能方便地改变其滤波特性,这对于滤除低频干扰和随机信号会有较大的效果。
4、在单片机系统中常用的滤波算法有限幅滤波法、中值滤波法、算术平均滤波法、加权平均滤波法、滑动平均滤波等。
(1)限幅滤波算法
该运算的过程中将两次相邻的采样相减,求出其增量,然后将增量的绝对值,与两次采样允许的最大差值A进行比较。A的大小由被测对象的具体情况而定,如果小于或等于允许的最大差值,则本次采样有效;否则取上次采样值作为本次数据的样本。
算法的程序代码如下:
#defineA //允许的最大差值 chardata; //上一次的数据 char filter() { chardatanew; //新数据变量 datanew=get_data(); //获得新数据变量 if((datanew-data)>A||(data-datanew>A)) return data; else returndatanew; }
说明:限幅滤波法主要用于处理变化较为缓慢的数据,如温度、物体的位置等。使用时,关键要选取合适的门限制A。通常这可由经验数据获得,必要时可通过实验得到。
(2)中值滤波算法
该运算的过程是对某一参数连续采样N次(N一般为奇数),然后把N次采样的值按从小到大排列,再取中间值作为本次采样值,整个过程实际上是一个序列排序的过程。
算法的程序代码如下:
#define N11 //定义获得的数据个数 char filter() { charvalue_buff[N]; //定义存储数据的数组 char count,i,j,temp; for(count=0;count { value_buf[count]=get_data(); delay(); //如果采集数据比较慢,那么就需要延时或中断 } for(j=0;j { for(value_buff[i]>value_buff[i+1] { temp=value_buff[i]; value_buff[i]=value_buff[i+1]; value_buff[i+1]=temp; } } returnvalue_buff[(N-1)/2]; }
说明:中值滤波比较适用于去掉由偶然因素引起的波动和采样器不稳定而引起的脉动干扰。若被测量值变化比较慢,采用中值滤波法效果会比较好,但如果数据变化比较快,则不宜采用此方法。
(3)算术平均滤波算法
该算法的基本原理很简单,就是连续取N次采样值后进行算术平均。
算法的程序代码如下:
char filter() { int sum=0; for(count=0;count { sum+=get_data(); delay(): } return (char)(sum/N); }
说明:算术平均滤波算法适用于对具有随机干扰的信号进行滤波。这种信号的特点是有一个平均值,信号在某一数值附近上下波动。信号的平均平滑程度完全到决于N值。当N较大时,平滑度高,灵敏度低;当N较小时,平滑度低,但灵敏度高。为了方便求平均值,N一般取4、8、16、32之类的2的整数幂,以便在程序中用移位操作来代替除法。
(4)加权平均滤波算法
由于前面所说的“算术平均滤波算法”存在平滑度和灵敏度之间的矛盾。为了协调平滑度和灵敏度之间的关系,可采用加权平均滤波。它的原理是对连续N次采样值分别乘上不同的加权系数之后再求累加,加权系数一般先小后大,以突出后面若干采样的效果,加强系统对参数变化趋势的认识。各个加权系数均小于1的小数,且满足总和等于1的结束条件。这样加权运算之后的累加和即为有效采样值。其中加权平均数字滤波的数学模型是:
式中:D为N个采样值的加权平均值:XN-i为第N-i次采样值;N为采样次数;Ci为加权系数。加权系数Ci体现了各种采样值在平均值中所占的比例。一般来说采样次数越靠后,取的比例越大,这样可增加新采样在平均值中所占的比重。加权平均值滤波法可突出一部分信号抵制另一部分信号,以提高采样值变化的灵敏度。
样例程序代码如下:
char codejq[N]={1,2,3,4,5,6,7,8,9,10,11,12}; //code数组为加权系数表,存在程序存储区 char codesum_jq=1+2+3+4+5+6+7+8+9+10+11+12; char filter() { char count; char value_buff[N]; int sum=0; for(count=0;count { value_buff[count]=get_data(); delay(); } for(count=0;count sum+=value_buff[count]*jq[count]; return(char)(sum/sum_jq); }
(5)滑动平均滤波算法
以上介绍和各种平均滤波算法有一个共同点,即每获取一个有效采样值必须连续进行若干次采样,当采速度慢时,系统的实时得不到保证。这里介绍的滑动平均滤波算法只采样一次,将一次采样值和过去的若干次采样值一起求平均,得到的有效采样值即可投入使用。如果取N个采样值求平均,存储区中必须开辟N个数据的暂存区。每新采集一个数据便存入暂存区中,同时去掉一个最老数据,保存这N个数据始终是最新更新的数据。采用环型队列结构可以方便地实现这种数据存放方式。
程序代码如下:
char value_buff[N]; char i=0; char filter() { char count; int sum=0; value_buff[i++]=get_data(); if(i==N) i=0; for(count=0;count sum=value_buff[count]; return (char)(sum/N); }
(6)低通滤波
将普通硬件RC低通滤波器的微分方程用差分方程来表求,变可以采用软件算法来模拟硬件滤波的功能,经推导,低通滤波算法如下:
Yn=a* Xn+(1-a) *Yn-1
式中 Xn——本次采样值
Yn-1——上次的滤波输出值;
,a——滤波系数,其值通常远小于1;
Yn——本次滤波的输出值。
由上式可以看出,本次滤波的输出值主要取决于上次滤波的输出值(注意不是上次的采样值,这和加权平均滤波是有本质区别的),本次采样值对滤波输出的贡献是比较小的,但多少有些修正作用,这种算法便模拟了具体有教大惯性的低通滤波器功能。滤波算法的截止频率可用以下式计算:
fL=a/2Pit pi为圆周率3.14…
式中 a——滤波系数;
, t——采样间隔时间;
例如:当t=0.5s(即每秒2次),a=1/32时;
fL=(1/32)/(2*3.14*0.5)=0.01Hz
当目标参数为变化很慢的物理量时,这是很有效的。另外一方面,它不能滤除高于1/2采样频率的干搅信号,本例中采样频率为2Hz,故对1Hz以上的干搅信号应采用其他方式滤除,
低通滤波算法程序于加权平均滤波相似,但加权系数只有两个:a和1-a。为计算方便,a取一整数,1-a用256-a,来代替,计算结果舍去最低字节即可,因为只有两项,a和1-a,均以立即数的形式编入程序中,不另外设表格。虽然采样值为单元字节(8位A/D)。为保证运算精度,滤波输出值用双字节表示,其中一个字节整数,一字节小数,否则有可能因为每次舍去尾数而使输出不会变化。
设Yn-1存放在30H(整数)和31H(小数)两单元中,Yn存放在32H(整数)和33H(小数)中。
本文转载自:面包板社区
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。
我们先普及一个概念,单片机(即Microcontroller Unit;MCU) 里面有什么。一个人最重要的是大脑,身体的各个部分都在大脑的指挥下工作。MCU跟人体很像,简单来说是由一个最重要的内核加其他外设组成,内核就相当于人的大脑,外设就如人体的各个功能器官。下面我们来简单介绍下51单片机和STM32单片机的结构。
1. 51系统结构
我们说的51一般是指51系列的单片机,型号有很多,常见的有STC89C51、AT89S51,其中国内用的最多的是STC89C51/2,下面我们就以STC89C51来讲解,并以51简称。
1)内核
51单片机由一个IP核和片上外设组成,IP核就是上图中的CPU,片上外设就是上图中的:时钟电路、SFR和RAM、ROM、定时/计数器、并行I/O口、串行I/O口、中断系统。IP核跟外设之间由系统总线连接,且是8bit的,速度有限。
51内核是上个世纪70年代Intel公司设计的,速度只有12M,外设是IC厂商(STC)在内核的基础上添加的,不同的IC厂商会在内核上添加不同的外设,从而设计出各具特色的单片机。这里Intel属于IP核厂商,STC属于IC厂商。我们后面要讲的STM32也一样,ARM属于IP核厂商,ARM给ST授权,ST公司在Cortex-M3内核的基础上设计出STM32单片机。
2)外设
我们在学习51的时候,关于内核部分接触的比较少,使用的最多的是片上外设,我们在编程的时候操作的也就是这些外设。
编程的时候操作的寄存器位于SFR和RAM这个部分,其中SFR(特殊功能寄存器)占有 128字节(实际上只用了 26 个字节,只有 26 个寄存器,其他都属于保留区),RAM占有 128 字节,我们在程序中定义的变量就是放在RAM中。其中SFR和RAM在地址上是重合的,都是在80~FF地址区间,但在物理区间上是分开的,所以51的RAM是有256个字节。
编写好的程序是烧写到ROM区。剩下的外设都是我们非常熟悉的IO口,串口、定时器、中断这几个外设。
2. STM32系统结构
1)内核
在系统结构上,STM32和51都属于单片机,都是由内核和片上外设组成。只是STM32使用的Cortex-M3内核比51复杂得多,优秀得多,支持的外设也比51多得多,同时总线宽度也上升到32bit,无论速度、功耗、外设都强于51。
从结构框图上看,对比51内核只有一种总线,取指和取数共用。Cortex-M3内部有若干个总线接口,以使CM3能同时取址和访内(访问内存),它们是:
指令存储区总线(两条)、系统总线、私有外设总线。有两条代码存储区总线负责对代码存储区(即FLASH外设)的访问,分别是I-Code总线和D-Code总线。
I-Code用于取指,D-Code用于查表等操作,它们按最佳执行速度进行优化。
系统总线(System)用于访问内存和外设,覆盖的区域包括SRAM,片上外设,片外RAM,片外扩展设备,以及系统级存储区的部分空间。
私有外设总线负责一部分私有外设的访问,主要就是访问调试组件。它们也在系统级存储区。
还有一个DMA总线,从字面上看,DMA是data memory access的意思,是一种连接内核和外设的桥梁,它可以访问外设、内存,传输不受CPU的控制,并且是双向通信。简而言之,这个家伙就是一个速度很快的且不受老大控制的数据搬运工,这个在51里面是没有的。
2)外设
从结构框图上看, STM32比51的外设多得多,51有的串口、定时器、IO口等外设 STM32 都有。STM32还多了很多特色外设:如FSMC、SDIO、SPI、I2C等,这些外设按照速度的不同,分别挂载到AHB、APB2、APB1这三条总线上。
本文转载自:程序源Lee
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。
单片机解密是什么?
单片机解密又叫单片机破解,芯片解密,IC解密,但是这严格说来这几种称呼都不科学,但已经成 了习惯叫法,我们把CPLD解密,DSP解密都习惯称为单片机解密。单片机只是能装载程序芯片的其中一个类。
单片机(MCU)一般都有内部程序区和数据区(或者其一)供用户存放程序和工作数据(或者其一)。为了防止未经授访问或拷贝单片机的机内程序,大部分单片机都带有加密锁定位或者加密字节,以保护片内程序。
如果在编程时加密锁定位被使能(锁定),就无法用普通编程器直接读取单片机内的程序,这就叫单片机加密。
单片机程序基本上都存在于Flash中,大部分能够读取或者识别Flash上的数据就能够获得Firmware文件,从而给复制产品带来了机会。
单片机攻击者借助专用设备或者自制设备,利用单片机芯片设计上的漏洞或软件缺陷,通过多种技术手段,就可以从芯片中提取关键信息,获取单片机内程序这就叫单片机解密。
能烧录程序并能加密的芯片还有 DSP,CPLD,PLD,AVR,ARM等。
当然具存储功能的存储器芯片也能加密,比如DS2401、DS2501、AT88S0104、DM2602、AT88SC0104D等,当中也有专门设计有加密算法用于专业加密的芯片或设计验证厂家代码工作等功能芯片,该类芯片业能实现防止电子产品复制的目的。
单片机解密方法
软件攻击
该技术通常使用处理器通信接口并利用协议、加密算法或这些算法中的安全漏洞来进行攻击。比如一个典型事例是对早期XXX系列单片机的攻击。攻击者利用了该系列单片机擦除操作时序设计上的漏洞,使用自编程序在擦除加密锁定位后,停止下一步擦除片内程序存储器数据的操作,从而使加过密的单片机变成没加密的单片机,然后利用编程器读出片内程序。
目前在其他加密方法的基础上,可以研究出一些设备,配合一定的软件,来做软件解密。
还有比如利用某些编程器定位插字节,通过一定的方法查找芯片中是否有连续空位,也就是说查找芯片中连续的FF FF字节,插入的字节能够执行把片内的程序送到片外的指令,然后用解密的设备进行截获,这样芯片内部的程序就被解密完成了。
电子探测攻击
该技术通常以高时间分辨率来监控处理器在正常操作时所有电源和接口连接的模拟特性,并通过监控它的电磁辐射特性来实施攻击。
因为单片机是一个活动的电子器件,当它执行不同的指令时,对应的电源功率消耗也相应变化。这样通过使用特殊的电子测量仪器和数学统计方法分析和检测这些变化,即可获取单片机中的特定关键信息。
过错产生技术
该办法就是使得单片机异常运行从而使得单片机处于非保护状态。
该技术使用异常工作条件来使处理器出错,然后提供额外的访问来进行攻击。使用最广泛的过错产生攻击手段包括电压冲击和时钟冲击。
低电压和高电压攻击可用来禁止保护电路工作或强制处理器执行错误操作。时钟瞬态跳变也许会复位保护电路而不会破坏受保护信息。电源和时钟瞬态跳变可以在某些处理器中影响单条指令的解码和执行。
探针技术
通过该技术使芯片内部都完全暴露!直接暴露芯片内部连线,然后观察、操控、干扰单片机以达到攻击目的。
为了方便起见,人们将以上四种攻击技术分成两类:
一类是侵入型物理攻击,这类攻击需要 破坏封装,然后借助半导体测试设备、显微镜和微定位器,在专门的实验室花上几小时甚至几周时间才能完成。所有的微探针技术都属于侵入型攻击。
另外一类属于非侵入型攻击,被攻击的单片机不会被物理损坏。在某些场合非侵入型攻击是特别危险的,这是因为非侵入型攻击所需设备通常可以自制和升级,因此非常廉价。大部分非侵入型攻击需要攻击者具备良好的处理器知识和软件知识。与之相反,侵入型的探针攻击则不需要太多的初始知识,而且通常可用一整套相似的技术对付宽范围的产品。
因此,对单片机的攻击往往从侵入型的反向工程开始,积累的经验有助于开发更加廉价 和快速的非侵入型攻击技术。
侵入式解密过程
侵入型攻击的第一步是揭去芯片封装(简称“开盖”有时候称“开封”,英文为 “DECAP”,decapsulation)。有两种方法可以达到这一目的。
第一种是完全溶解掉芯片封装,暴露金属连线。
第二种是只移掉硅核上面的塑料封装。
第一种方法需要将芯片绑定到测试夹具上,借助绑定台来操作。第二种方法除了需要具备攻击者一定的知识和必要的技能外,还需要个人的智慧和耐心,但操作起来相对比较方便,完全实验室中操作。
芯片上面的塑料可以用小刀揭开,芯片周围的环氧树脂可以用浓硝酸腐蚀掉。热的浓硝酸会溶解掉芯片封装而不会影响芯片及连线。该过程一般在非常干燥的条件下进行,因为水的存在可能会侵蚀已暴露的铝线连接,这就可能造成解密失败。接着在超声池里先用丙酮清洗该芯片以除去残余硝酸,并浸泡。
最后一步是寻找保护熔丝的位置并将保护熔丝暴露在紫外光下。一般用一台放大倍数至少100倍的显微镜,从编程电压输入脚的连线跟踪进去,来寻找保护熔丝。若没有显微镜,则采用将芯片的不同部分暴露到紫外光下并观察结果的方式进行简单的搜索。
操作时应用不透明的物体覆盖芯片以保护程序存储器不被紫外光擦除。将保护熔丝暴露在紫外光下5~10分钟就能破坏掉保护位的保护作用,之后,使用简单的编程器就 可直接读出程序存储器的内容。
对于使用了防护层来保护EEPROM单元的单片机来说,使用紫外光复位保护电路是不可行的。对于这种类型的单片机,一般使用微探针技术来读取存储器内容。在芯片封装打开后,将芯片置于显微镜下就能够很容易的找到从存储器连到电路其它部分的数据总线。
由于某种原因,芯片锁定位在编程模式下并不锁定对存储器的访问。利用这一缺陷将探针放在数据线的上面就能读到所有想要的数据。在编程模式下,重启读过程并连接探针到另外的数据线上就可以读出程序和数据存储器中的所有信息。
还有一种可能的攻击手段是借助显微镜和激光切割机等设备来寻找保护熔丝,从而寻查和这部分电路相联系的所有信号线。
由于设计有缺陷,因此,只要切断从保护熔丝到其它电路的某一根信号线,或者切割掉整个加密电路。又或者连接1~3根金线,通常称为FIB(focused ion beam),就能禁止整个保护功能。这样使用简单的编程器就能直接读出程序存储器的内容。
虽然大多数普通单片机都具有熔丝烧断保护单片机内代码的功能,但由于通用低档的单片机并非定位于制作安全类产品,因此,它们往往没有提供有针对性的防范措施且安全级别较低。
加上单片机应用场合广泛,销售量大,厂商间委托加工与技术转让频繁,大量技术资料外泻,使得利用该类芯片的设计漏洞和厂商的测试接口,并通过修改熔丝保护位等侵入型攻击或非侵入型攻击手段来读取单片机的内部程序变得比较容易。
防止单片机被解密的几点建议
作为电子产品的设计工程师非常有必要了解当前单片机攻击的最新技术。因为任何一款单片机从理论上讲,攻击者均可利用足够的投资和时间使用以上方法来解密!为避免辛苦劳作的成果被窃取,提出以下建议:
在选定加密芯片前,要充分调研,了解单片机破解技术的新进展,包括哪些单片机是已经确认可以破解的。尽量不选用已可破解或同系列、同型号的芯片选择采用新工艺、新结构、上市时间较短的单片机。
对于安全性要求高的项目,尽量不要使用普及程度最高,被研究得也最透的芯片。
产品的原创者,一般具有产量大的特点,所以可选用比较生僻、偏冷门的单片机来加大仿冒者采购的难度,选用一些生僻的单片机。
在设计成本许可的条件下,应选用具有硬件自毁功能的智能卡芯片,以有效对付物理攻击;另外程序设计的时候,加入时间到计时功能,比如使用到1年,自动停止所有功能的运行,这样会增加破解者的成本。
如果条件许可,可采用两片不同型号单片机互为备份,相互验证,从而增加破解成本。
打磨掉芯片型号等信息或者重新印上其它的型号,以假乱真。
可以利用单片机未公开,未被利用的标志位或单元,作为软件标志位。
你应在程序区写上版权信息,以备获得法律保护。
采用高档的编程器,烧断内部的部分管脚,还可以采用自制的设备烧断金线,这个目前国内几乎不能解密,即使解密,也需要上万的费用,需要多个母片。
采用保密硅胶,比如环氧树脂灌封胶,封住整个电路板,PCB上多一些没有用途的焊盘,在硅胶中还可以掺杂一些没有用途的元件,同时把MCU周围电路的电子元件尽量抹掉型号。
可以用编程器把空白区域中的FF改成00,也就是把一些未使用的空间都填充好,这样一般解密器也就找不到芯片中的空位,也就无法执行以后的解密操作。
总结
当然,要想从根本上防止单片机被解密,那是不可能的,加密技术不断发展,解密技术也不断发展,现在不管哪个单片机,只要有人肯出钱去做,基本都可以做出来,只不过代价高低和周期长短的问题,编程者还可以从法律的途径对自己的开发作出保护,比如写相关专利。
本文转载自:嵌入式Linux
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。
一、 前言
1、利用所学知识设计一个单片机数字电子钟
2、数字电子钟的功能要求:
(1)有自动计时功能;
(2)能显示计时时间,显示效果良好;
(3)有校时功能,能对时间进行校准
3、设计要求:
(1)主电路由秒信号发生器、“时、分、秒”计数器、译码器及显示器、校准电路等构成。
(2)秒信号发生器一般用石英晶体振荡器加分频器实现。
(3)译码电路将时、分、秒计数器的输出状态送七段译码器译码,经过六位LED七段显示器显示出来。
(4)校时电路用来对时、分、秒显示数字进行校对。
二、 硬件原理分析
1、时钟信号部分
单片机XTAL1,XTAL2端接外部时钟电路(时钟电路参考课本),EA端接5V电源,使得单片机读取片内程序。
2、按键开关部分
开始仿真,按下开关K1,时钟暂停,然后按下开关K2一次,切到调时位,再按K3,K4实现时位加减;按K1两次切到调分位,按K3,K4实现分位加减;按K1三次切到调秒位,按K3,K4实现秒位加减;按下K5,确定当前操作,然后再按K1,重新启动时钟。
3、数码管显示器部分(共阴极)
所用的是一个六位七段共阴极数码管
4、共阴极数码管编码
三、 程序设计
四、 程序代码
#include <reg51.h> #define uchar unsigned char #define uint unsigned int sbit set=P1^0; sbit save=P1^5; sbit rselect=P1^1; sbit lselect=P1^2; sbit add=P1^3; sbit reduce=P1^4; uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; uchar disp_buf[6]; uchar disp_bit=0; uint hour,min,sec; uint select_num=0; uint hour_adj,min_adj,sec_adj; uchar count; uchar key_num=0; void key_scan() { if(!set) { hour_adj=hour; min_adj=min; sec_adj=sec; key_num++; } while(!set); if(key_num%2==1) { if(rselect==0) { select_num++; if(select_num==4) select_num=1; } while(!rselect); if(lselect==0) { select_num--; if(select_num<=0) select_num=3; } while(!lselect); } if(!add&&(key_num%2)) { switch(select_num) { case 1 : { hour_adj++; if(hour_adj==24) hour_adj=0; break; } case 2 : { min_adj++; if(min_adj==60) min_adj=0; break; } case 3 : { sec_adj++; if(sec_adj==60) sec_adj=0; break; } default:break; } while(!add); } if(!reduce&&(key_num%2)) { switch(select_num) { case 1 : { hour_adj--; if(hour_adj<=0) hour_adj=23; break; } case 2 : { min_adj--; if(min_adj<=0) min_adj=59; break; } case 3 : { sec_adj--; if(sec_adj<=0) sec_adj=59; break; } default:break; } while(!reduce); } if(!save&&(key_num%2)) { select_num=0; hour=hour_adj; min=min_adj; sec=sec_adj; while(!save); } } void main() { TMOD=0x11; TH0=0xf7; TL0=0x00; TH1=0x4c; TH0=0x00; ET0=1; ET1=1; EA=1; TR0=1; TR1=1; PT1=1; hour=23; min=59; sec=59; count=0; while(1) { key_scan(); if(key_num%2) { switch(select_num) { case 1 : { if(count<=10) { disp_buf[0]=hour_adj/10; disp_buf[1]=hour_adj%10; } else { disp_buf[0]=0x40; disp_buf[1]=0x40; } disp_buf[2]=min_adj/10; disp_buf[3]=min_adj%10; disp_buf[4]=sec_adj/10; disp_buf[5]=sec_adj%10; break; } case 2 : { if(count<=10) { disp_buf[2]=min_adj/10; disp_buf[3]=min_adj%10; } else { disp_buf[2]=0x40; disp_buf[3]=0x40; } disp_buf[0]=hour_adj/10; disp_buf[1]=hour_adj%10; disp_buf[4]=sec_adj/10; disp_buf[5]=sec_adj%10; break; } case 3 : { if(count<=10) { disp_buf[4]=sec_adj/10; disp_buf[5]=sec_adj%10; } else { disp_buf[4]=0x40; disp_buf[5]=0x40; } disp_buf[0]=hour_adj/10; disp_buf[1]=hour_adj%10; disp_buf[2]=min_adj/10; disp_buf[3]=min_adj%10; break; } default : break; } } if(key_num%2==0) { disp_buf[0]=hour/10; disp_buf[1]=hour%10; disp_buf[2]=min/10; disp_buf[3]=min%10; disp_buf[4]=sec/10; disp_buf[5]=sec%10; } } } void timer0() interrupt 1 { TH0=0xf7; TL0=0x00; P2=~(0x01<<disp_bit); P0=tab[disp_buf[disp_bit]]; disp_bit++; if(disp_bit==6) disp_bit=0; } void timer1() interrupt 3 { TH1=0x4c; TL1=0x00; if(++count==20) { count=0; if(++sec==60) { sec=0; if(++min==60) { min=0; if(++hour==24) { hour=0; } } } } }
五、 仿真效果图
六、 参考文献
1. 网上搜索
2. 单片机教材
3. 网上论坛
七、学习体会
通过本次单片机课程设计,不仅加深了我对单片机理论课程知识的认识,而且通过将理论与实践相结合,使我真正地全面理解单片机的功能。 在刚开始编程时,没有一点思路,通过书上所提供的例程,慢慢理清了思路、基本了解了程序大致需要那几部分,基本确定编程思想。在课程设计的整个过程中也遇到了很多问题,但本着遇到问题解决问题的原则,通过查找资料和询问老师、同学的办法,基本解决了所遇到问题。整个课程设计过程学到了不少通过理论学习没法学到的东西,真正增强了自己的能力。
课程设计的这天时间,虽然辛苦但是收获巨大。
作者:小西贝
出处:https://www.cnblogs.com/jtd666/p/12499243.html
转载此文目的在于传递更多信息,版权归原作者所有。
对于初学者而言,对单片机的内存分配往往最让人头疼,很多人学了单片机几年 都不知道单片机内部的内存使用情况是如何分配的。要了解 ROM(flash)、RAM(sram)启动,首先需要对链接器 Linker 如何分配内存有一定的了解。
通常,对于栈生长方向向下的单片机,其内存一般模型是:
一个进程运行时,所占用的内存,可以分为如下几个部分:
1、栈区(stack):由编译器自动分配释放,存放函数的参数值,局部变量的值等。
2、堆区(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS释放。
3、全局变量、静态变量:初始化的全局变量和静态变量放在一块区域,未初始化的全局变量和和未初始化的静态变量在相邻的的另一块区域。程序结束后由系统自动释放。
4、文字常量:常量字符串就是放在这里的。这些数据是只读的,分配在RO-data(只读数据存储区),则被包含在flash中,程序结束后由系统自动释放
5、程序代码(code):存放函数体的二进制代码。
同时,单片机内存被总分为flash(rom)和sram(ram),flash里面的数据掉电可保存,sram中的数据掉电就丢失,sram的执行速度要快于flash,flash容量大于sram
上方的最低内存地址,最高地址,都是在flash和sram中
我们正常下载程序都是下载存储进flash里面,这也是为什么断电可保存的原因
单片机的程序存储分为code(代码存储区)、RO-data(只读数据存储区)、RW-data(读写数据存储区) 和 ZI-data(零初始化数据区)
在使用MDK编译时可以看到
Code为程序代码部分 = 程序代码区(code)
RO-data 表示 程序定义的常量 = 文字常量区
RW-data 表示 已初始化的全局变量 = 栈区(stack)堆区(heap)全局区(静态区)(static)
ZI-data 表示 未初始化的全局变量
部分参考自:http://blog.chinaunix.net/uid-15473693-id-388637.html
版权声明:
本文为CSDN博主「Z小旋」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/as480133937/article/details/87608816