单片机

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则是在干扰源回路串联电感或电阻以及增加续流二极管来实现。抑制干扰源的常用措施如下:

  • 继电器线圈增加续流二极管,消除断开线圈时产生的反电动势干扰。仅加续流二极管会使继电器的断开时间滞后,增加稳压二极管后继电器在单位时间内可动作更多的次数。
  • 在继电器接点两端并接火花抑制电路(一般是RC串联电路,电阻一般选几K 到几十K,电容选0.01uF),减小电火花影响。
  • 给电机加滤波电路,注意电容、电感引线要尽量短。
  • 电路板上每个IC要并接一个0.01μF~0.1μF高频电容,以减小IC对电源的影响。注意高频电容的布线,连线应靠近电源端并尽量粗短,否则,等于增大了电容的等效串联电阻,会影响滤波效果。
  • 布线时避免90度折线,减少高频噪声发射。
  • 可控硅两端并接RC抑制电路,减小可控硅产生的噪声(这个噪声严重时可能会把可控硅击穿的)。

  
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)。

围观 205

单片机主要作用是控制外围的器件,并实现一定的通信和数据处理。但在某些特定场合,不可避免地要用到数学运算,尽管单片机并不擅长实现算法和进行复杂的运算。下面主要是介绍如何用单片机实现数字滤波。

在单片机进行数据采集时,会遇到数据的随机误差,随机误差是由随机干扰引起的,其特点是在相同条件下测量同一量时,其大小和符号会现无规则的变化而无法预测,但多次测量的结果符合统计规律。为克服随机干扰引起的误差,硬件上可采用滤波技术,软件上可采用软件算法实现数字滤波。滤波算法往往是系统测控算法的一个重要组成部分,实时性很强。

采用数字滤波算法克服随机干扰的误差具有以下优点:

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)。

围观 27

我们先普及一个概念,单片机(即Microcontroller Unit;MCU) 里面有什么。一个人最重要的是大脑,身体的各个部分都在大脑的指挥下工作。MCU跟人体很像,简单来说是由一个最重要的内核加其他外设组成,内核就相当于人的大脑,外设就如人体的各个功能器官。下面我们来简单介绍下51单片机和STM32单片机的结构。

1. 51系统结构

“51系统结构框图"
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系统结构

“STM32系统结构框图"
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)。

围观 241

单片机解密是什么?

单片机解密又叫单片机破解,芯片解密,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)。

围观 131


下面先讲串口通信的一些基本概念,术语。如果对串口通信比较熟悉的,就当复习,如果哪里讲的不到位,欢迎及时指出。

这里并不对串口的编程作讲解,主要是从应用的角度去讲一讲。因为更多的时候,都是产品做好了,比如触摸屏需要和控制器,PLC通信。理想的情况下,一般只要一上电,不需要太多的操作和配置,就可以通信上。

文章后半部分罗列了一些相关问题,在解答前还需要先了解一下什么是串口通信,232,485,422等。

什么是串口通信

常见的串口通信一般是指异步串行通信。

这里就要说一下同步和异步的区别了。

先讲一下串行通信的概念。那么,与串行通信相对的是什么呢?

与串行通信相对的是并行通信。数据传输一般都是以字节传输的,一个字节8个位。拿一个并行通信举例来说,也就是会有8根线,每一根线代表一个位。一次传输就可以传一个字节,而串口通信,就是传数据只有一根线传输,一次只能传一个位,要传一个字节就需要传8次。就像小虎队那首歌一样,把你的心,我的心,串一串,再烤一烤。。串口通信就是把数据串在一根线上传输,所以就叫串口吧。


与异步通信相对的就是同步通信了。同步通信一般是指有一个时钟信号进行数据信号同步。同步通信对接收方来说就相对简单一些。因为有时钟信号在,每一个高低电平变化一下,就去取一下数据就行了。通信速率可以由发送方或者说是主站设备进行控制。通信速度也相对比串口通信快很多。但是为什么很多设备,屏和plc,控制器不采用这种方式,都使用串口呢。

那么,在很多设备上,不方便接太多线,比如接8根数据线,也不方便接同步时钟信号(这个后面再说),于是一种异步串行通信就诞生了。

相对来说,异步串口通信,就只需要一根线就可以发送数据了。在对速率要求不高的情况,使用一根线发送数据是带来大大的方便和实用价值的。

那么问题来了,怎么样才能保证一根线就能发送正常的数据呢。也就说发送方发送的数据,接收方是怎么知道是什么数据呢。

为了能正常发送数据和接收正确的数据,那异步串口通信就需要满足以下几个条件:


也就是双方必要约定一种暗号。

也许当时发送这个通信的小组是这样讨论的。

经理:我要用一根线就能传输数据,你来给我定个标准。

研发:好。

经理:只有一根线,我怎么知道数据什么时候开始呢。

研发:就一根线,默认是高电平,那就有一个起始位吧。当检测到有低电平的时候,就是开始有一个字节的数据发送了,起始位之后,先是字节的最低位,传送一个字节。

经理:可是,就一根线,过来的数据会不会有干扰,容易出错呀。

研发:行呀,那就在字节数据后再加一个校验位。可以作奇校验,偶校验,1校验,0校验,无校验。

经理:嗯 ,很不错。有起始位就应该有停止位,那我们就再加个停止位在后面吧。

研发:。。。。。。。。。

经理:传输一串数据,对方要怎么知道数据的拆分呢,怎么按时间或频率去解读数据位,校验位呢。

研发:这样吧,双方约定一个波特率吧,定义一个每个位占用多长的时间,这样双方按这个波特率就可以处理了。

经理:这个比特率呀。。。

研发:老板,是波特率。

经理:我知道,是比特率嘛。

研发:这个波特率呢,是指1S钟可以传输多个位,也就知道一个位占用多长时间。这样就解决传输的问题了。

经理:那万一传输过程,数据快太,判断失误停不下来怎么办。

研发:那就把停止位可以调节为1个停止位或者2个停止位。这样就可以停下来了。

经理:嗯,听着不错。就这样办吧。

于是,串口通信就这样出来了。

在串口的通信参数上,就有了波特率,数据位,停止位,校验位这几个参数来确保串口通信的正确性和稳定上。当然,这只是某个方面保证串口通信的正确性和稳定性,不代表设备间通信的正确性和稳定性。

串口通信主要为分232,485,422 通信三种方式。

这三种有什么区别呢。

232:


232 通信主要是由RX,TX,GND三根线组成。

RX与TX,TX接RX,GND接GND。这样还是比较好理解吧。因为发送和接收分别是由不同的线处理的,也就是能同时发送数据和接收数据,这就是所谓的全双工。

在这里扩展一下,串口通信还有一个功能叫做全功能串口通信,也叫标准串口。因为在两个设备间进行数据传输,有些设备处理速度比较快,有些数据比较慢。为了保证数据能正常传输,在RX,TX的基础上,还增加了几个控制引脚,本来好端端就R,T,G,三根线,凑着就凑齐了9个引脚,召唤出了DB9这个东西。


这要怪就怪当时使用电脑的时候,还没有互联网这个概念,但是又想在两台电脑间进行通信。所以才有这样一个东西。

在后来的设备,很多控制器,人机界面,PLC等使用串口通信中,基本上就不使用标准串口,而是就直接使用RX,TX,GND三根线来通信了。

但是这里为什么要提到这个呢。因为只是很多设备这样用,也就是还存在少数设备还保留了标准串口的功能。这就是为什么会遇到明明电脑通信是好的,换成触摸屏通信就不行了。因为很多触摸屏只使用了RX,TX,GND通信,遇到一些还保留标准串口功能的就比较讨厌了。

485:

485是为了解决232通信距离的问题。原理什么之类的就不多讲了。反正232通信距离就是不长。485主要是以一种差分信号进行传输,只需要两根线,+,-两根线,或者也叫A,B两根线。A,B两根线的差分电平信号就是作为数据信号传输。

那么问题来了,那是不是就没有RX和TX的概念了。是的,发送和接收就不能分开了。发送和接收都是靠这两根的来传输,也就是每次只能作发送或者只能作接收,这就是半双工的概念了,这在效率上就比232弱很多了。就像对讲机一样,经常是某个人讲完之后,都要说一个over,确保当前说完了,等待对方回复。


485就是这样牺牲了232全双工的效率来达到自己传输距离远的代价。那有没有即保留了232的全双工,又可以像485这样提高传输距离呢,于是,422出来了。

422:

422呢,有些标注为485-4。而485就标注为485-2。有什么区别呢。就是为了好记呢。485-2就是2根线。485-4就是4根线。


422就是把232的RX分成两根线,RX+,RX-,把TX分成TX+,TX-。这样就可以同时发送和同时接收了,还可以像485这样,有较远的传输距离。可是这样一种很有优势的通信方式,为什么用的不多呢。我个人的答案和理解就是:线太多了。特别是像我这样懒得接线的人,超过3根线就头晕的。搞个通信还需要接这么多线,什么TX,RX,正啊负啊。交换来交换去。

因为在很多设备通信中,基本上是属于一问一答式的,因此,232的全双工通信优势其实也并没有发挥出来。就像现在打电话,虽然两个人可以同时说话,但是两个人同时说话,叽叽歪歪的,谁知道说什么呀。特别是一个主站与多个从站通信的时候,485的接线就就方便多了,反正大家就两根线,把+都接一块,把-都接一块。如果是422作一主多从,接线上还要理半天呢,而且通信异常了也不好解决。

好了,串口通信基本就普及到这里吧。下面就对刚上提到的问题进行讲一讲。

1、电脑使用USB转串口可以和设备通信上,换成屏与设备就通信不上了?

1)有可能电脑USB转串口接到设备上,使用的是标准串口功能,也就是除了RX,TX,GDN外,还使用了其它引脚。比如像欧姆龙PLC,三菱PLC,在实际与屏的通信中,就需要接某些引脚短接的情况。

2)电脑与控制器或PLC通信时,是扫描波特率参数,自适应的,屏通信可能参数没有设备好。在三菱,基恩士等PLC,就存在变化波特率进行通信交互的过程。

3)也有可能是接线方式不对。因为有些DB9,还需要公头,母头。如果不注意的话,也会存在把TX接到TX上,把RX接到RX上,这样需要注意的地方。

4) 在这里补充一下,有时候可能会使用一些串口助手发送测试数据与控制器通信,有些串口助手的奇偶校验是不起作用,这个要提醒一下。

2、 这A家的屏可以和设备通信,换成B家的屏就通信不上了?

1) 首先确认一下接线是否正确了,RX和TX是否兼容。
2) 地线是否没有接。
3) 除了RX,TX,GND,是否还有其它引脚需要短接的。
4) 通信协议是否一致或不完善,波特率是否一样。

3、 以前不接地线可以通信,换个设备为什么需要接地线了?

这个问题和上一个有类似的。因为有些设备使用了隔离电源。以前不接地可以通信,有可能是地线已经在另外一个环路已经共地了,实际地线已经接了,所以才可以通信。可能换了个带隔离电源的,两个设备的地是隔离的,就需要在串口上把地线接起来。这个我是自身经历过的,有个客户老说他的设备通信不上,后来拍个照我给我,他地线没有接,他说以前不接地线可以通信的。于是我就给他科普了一下。

4 、一个设备是232,另一个设备是422,没有转换设备,怎么办?(232与422互转的简单方法)

这个情况我遇到过,客户的设备是422通信的,但是我手上并没有422设备,只有232通信可以测试。因此就需要把422转成232进行通信。

刚才也讲了422和232的接线,因为这两个都是全双工的,接收和发送都是分到的,而422只是以一种差分信号进行传输。

把422的Rx+与232的TX接,422的RX-与232的GND接。

把422的TX+与232的RX接,422的TX-与232的GDN接。

这样,422设备要发送数据的,就可以发送到了232的RX上。232的TX发数据后,由于TX和GND也形成了差分信号给422,422就可以接收到数据了。

5、 用232通信没问题,用485通信没问题,使用232转485之后就通信不稳定?

232和485从通信原理上,最大一个差别是全双工和半双工的区别。可是应用层发送数据和接收数据才不管底下是全双工还是半双工。

但是485就得管了。因为既然是半双工,就得严格保证通路上只能有发送或只能有接收的数据,一旦同时有发送和接收,数据就会冲突了。所以解决的办法就是主站设备,也就是主动命令的一方就需要严格控制好发送数据命令的节奏了。

当然有些232转485的设备做的比较好了,可以优化这个,但是主站还是要控制,比较把通信速率调节慢一些(不是调节波特率)。

6、 485单独接每个设备都通信正常,多个从站接一块通信就不稳定?

这个是属于485通信的不稳定因素了。

7 、要想实现两个屏或两个主站通过485访问modbus设备,有什么好的办法?

在485通信中,基本上是一主多从。但是遇到一些客户实际使用中,有客户想用两个屏来访问一个modbus设备的。目前暂时还没有好的办法。

8、 针对串口通信的弱点,在使用上应该要注意哪些地方?

说来串口通信的弱点,那就说来话长了。不过还是长话短说吧。

1)信号干扰的问题

建议使用带屏蔽线,接线要严格,比如要接地。有些485通信上,还考虑接上终端电阻来匹配。如果是232,尽量不要让线太长。通信协议上尽量避免长报文的数据通信。

2)波特率匹配的问题

因为有些设备的计算的波特率是存在误差的,特别是一些控制器,由于使用的晶振不一样。因此在一些波特率比如9600波特率就存在误差。存在误差带来的影响是什么呢。因为接收方是通过时间来计算一个位的。那么如果一个报文过长,就会存在误差积累的问题,算着算着就偏了。所以,这也是串口通信不稳定的一些地方,在使用上应注意避免发送太长数据的包。

3)在一些可能会存在干扰的情况,在有的选的情况,可以考虑使用奇校验或者偶校验。因为虽说出现错误的可能性不大,但既然存在干扰,如果加了校验,至少可以把错误的报文过滤掉。总好比没有校验然后通信数据错了不知道。或者尽量使用一些带校验的协议,防止数据出错。

4)串口通信本来就比较慢,请降低对数据响应的要求。

因为串口通信本身就比以太网慢。而且,串口通信并不是能像CPU那样多线程处理。因为就一个口一个线数据出去,即便你应用到程序再怎么用多线程处理数据,但是最底下也只有一个口出去,一次也只能传一个位,一个字节过去。因为有客户在使用9600的波特率通信,但是又希望多少的数据可以在多少毫秒内得到响应。

但是串口通信还是要事实求是,所以正确认识串口通信对应用,对开发,对沟通都有着很大的帮助的。

为什么不用同步通信呢?

刚才提到,同步通信需要依赖于时钟信号。这就存在一个问题,这个时钟信号是谁来发起呢。在同步通信中,往往需要一个主设备发起时钟信号读从模块的数据。在实际中,有屏读PLC,有屏读屏的数据。而单纯地从异步串口通信来说,是没有主从之说,双方都是平等的角色,都可以互发信息,互收信息。而同步通信一般是应用于CPU读一些模块,由CPU发起时钟信号,比如读SD卡模块,就可以通过SPI方式,还有一些传感器模块。

本文是转载文章,直接来源:技成培训,转载此文目的在于传递更多信息,版权归原作者所有。

围观 134

一、 前言

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
转载此文目的在于传递更多信息,版权归原作者所有。

围观 104

因为单片机有CPU、存储器、IO等等,使他(人性化一点以配合下文)看起来就像一个比较小的计算机,所以,在理解单片机的时候如果能把你之前有的那些也许仅仅是直觉上的对计算机的理解融入进来的话,可能会对你学习单片机的概念有极大的帮助,至少对于我是这样的。

我想在关于单片机的众多让你头晕脑胀、摸不着头脑甚至想撞墙的概念里面,“堆栈”可能是其中最可恶的一个,因为即使单单是从汉语的角度来理解这个词就已经让你很晕了,其实我最初也想不通这是哪位大侠的创意,不过不用担心,这里我们完全不去讨论关于这个词的问题(这个词用得其实很好“堆”和“栈”都有他们各自的意思,准确的概括了这个区域的功能,有兴趣可以Baidu一下),这里我会打一个比较有趣的比方,以此来绕过那些令你想撞墙的概念,并使你在直觉上对“堆栈”这个概念有一个深刻的理解。

你基本上应该清楚,单片机里面是有存储区和CPU的,如果你不清楚,那么我刚刚告诉你了,请记住。现在,请你把单片中的CPU想成一个人(你完全可以把他想成是你宿舍的那个天天和你吵嘴的同学,一会你就会发现这会非常有趣),在这里就叫他C哥吧,不过这个人不同于常人,有一些特点,一会我们会慢慢说清楚,现在要告诉你的关于这个人的第一个特点是:他的记忆能力很差。下面,请你把存储区想象成一个一个排好的小盒子,这些盒子的作用大致可以分成两类:1、保存写有你命令的纸条,比如你在某个盒子里面的纸条上写着:去洗我的袜子!;2、保存你的一些东西,比如你那双正在污染宿舍空气的臭袜子。因为C哥是一个记忆力不怎么好的人,所以,这些盒子都有自己的编号,以方便他查找。

那么,现在,我们可以来说明一下单片机是如何工作的了。首先,你要把所有的命令还有需要处理的东西放进那些小盒子,比如刚才提到的你那双待洗的袜子还有那张纸条,这时你应该发现C哥另一个特点:笨——他只会做你明确告诉他的事情,也就是说,如果你没有在纸条上写“去洗我的袜子!”,那么C哥极有可能会无动于衷地看着你的袜子直到他被熏晕倒,当然,更可能的情况是他根本找不到你的袜子…好了,当你把要做的事情和该怎么做写到盒子里之后,下面的任务就交给C哥了。C哥做事真的很讲原则,他会按照你给定的顺序或者——如果你没有给定的话,根据盒子上面的编号按照从小到大的顺序——一个一个地打开盒子,读取里面的命令、处理相应的事件,直到所有的事情都执行完毕,他就会休息。请你牢记这个简单而有趣的过程,因为其实单片机就是这样工作的,当然,这里忽略了许多细节,但是这对你从直觉上理解单片机的概念以及足够了。

下面,就要开始说明堆栈这个概念了,思来想去,还是觉得如果直接把“堆栈”这个词用到文中来,实在不符合本文的风格,考虑到其实“堆栈”也是存贮区(这一点你要记住,堆栈并不是一个像专用寄存器那样专门的一个区域,它是由你在通用RAM区指定的。),按照本文的说法也就是一些盒子,所以,现在我们把“堆栈”改名叫“记忆盒子”,你可以感觉到,“堆栈”的作用和记忆有极大的关系,不过你也不用在这里纠结这个名字的由来,下面我会说的。

现在,请注意,我要开始解释“记忆盒子”了,也就是“堆栈”。大致上说,“记忆盒子”的作用是当C哥执行某任务到一半的时候突然有了更紧急的是事情要执行的时候用来保存当前任务的(包括盒子的编号和盒子里面的东西)。这么说你肯定晕了,其实,通俗一点,就是当C哥洗袜子洗到一半的时候突然接到你的命令要去打开另一个盒子(那个盒子里的纸条上可能写着“给我换尿布”)并执行里面的命令,因为C哥记忆力很差,以至于他做完那件紧急的事情后记不起要回到哪个盒子来继续执行“洗袜子”这个命令,这时候,他要把现在手头的东西保存到“记忆盒子”里,要保存的东西有:1、放着纸条和袜子的盒子的编号(注意这里其实是两项内容);2、那双袜子。这样,当他执行完紧急任务后会去记忆盒子里,从里面找到两张纸条,和一双袜子(这个时候C哥还是没有想起来他要洗袜子,他必须要到那张写着洗袜子命令的纸条),他按照两张纸条的信息知道自己要去哪个盒子去洗袜子,并在那里继续完成洗袜子的任务。你可能会发现,在这一段的解释里面有一个重要的漏洞,那就是在C哥执行完紧急任务后他是如何知道储存着原来的任务信息的盒子的编号是存储在哪个“记忆盒子”里呢?别着急,下面我会解释的。

从本质来说,“记忆盒子”与普通的盒子是没有区别的,他们都是单片机里面的存储单元,证明这一点的最好证据就是堆栈是需要你来指定的,也就是说,你要预先把一些盒子指定为“记忆盒子”。下面,说明一下是如何指定“记忆盒子”的。其实这个过程很简单,在单片机的专用寄存器里面有一个SP指针(81H),这个指针里面记录着堆栈的开始处的地址。用符合本文的话来解释就是,C哥的衣服上有一个口袋(也就是SP指针),这个口袋里面的“神奇纸条”上记录着第一个“记忆盒子”的编号,而指定“记忆盒子”的过程就是你在这张“神奇纸条”上写上一个盒子的编号(作为第一个“记忆盒子”的编号),这个纸条会自动地将纸条上的编号加1或者减1,所以,某个目前并不确定的区域内盒子具备了成为“记忆盒子”的可能,注意,堆栈的大小是不能规定的,这就是为什么用“生长”这个词来形容堆栈。

现在,关于堆栈的概念基本上都介绍完了,但是,我知道,你可能还是很晕,甚至比看之前还晕,那是因为刚才叙述的这个过程是分开的,而且逻辑上并不是顺序的,下面,顺序的说一下,相信你马上就明白了。

主角仍然是傻傻笨笨但任劳任怨的C哥,他一个一个的打开盒子按照里面的纸条上的说明执行你规定的任务。而你,为了防止他在执行复杂任务时犯傻,把一个盒子指定为“记忆盒子”,并把这个“记忆盒子”的位置写在了一张 “神奇纸条”上放在了C哥的口袋里。现在,C哥正在洗你的袜子,这个时候,他突然接到你的命令要去给你换尿布,而C哥知道自己很笨,所以他自动地掏出了口袋里的纸条,找到了第一个“记忆盒子”,然后拿出一张空白纸条,把装着“给我洗袜子”那张纸条的盒子的编号写在了上面并放进“记忆盒子”。然后,他把“神奇纸条”放回了口袋里。当这个任务完成后“神奇纸条”会自动将写在它上面的编号加1,也就是将一个新的、空的“记忆盒子”的编号写在上面。之后,他会按照刚才的过程把装着袜子的那个盒子的编号以及袜子本身分别放进不同的记忆盒子(现在已经有三个盒子成为“记忆盒子”,堆栈已经长大了,红色下划线的字体就是这三个盒子里的内容,注意是有先后顺序的)。再然后,他就去给你换尿布了…

现在,尿布换完了,不过,果不其然,C哥完全忘记了他要给你洗袜子这件事情了,不过,他记得一件事,那就是看口袋里的纸条。于是,他摸出了口袋里的纸条,上面当然是一个“记忆盒子”的编号,他按照编号找到了第一个“记忆盒子”(按照上一段的顺序应该是第三个“记忆盒子”),里面应该是一双你的袜子,于是他拿到了你的袜子。但是,他还是不知道该干什么,于是他再次摸出了“神奇纸条”,这时,纸条上的编号已经自动减1了,于是,他找到了新的“记忆盒子”,里面的纸条上记录着袜子本来放置的盒子的编号,于是,他把袜子放到了那个盒子里。恩,你可以想到,现在C哥还是不知道要对袜子做些什么,他耐心的又一次摸出了那张“神奇纸条”,这次按照上面的编号,他找到了一张纸条,上面写着的仍然是一个盒子的编号。C哥按照编号找到了那个盒子,发现那个盒子里的纸条上写着“给我洗袜子!”…至此,C哥又回到了原来的任务——洗袜子。

现在,我希望你已经明白了,堆栈其实就是你指定的一个些存储单元,这些存储单元被指定只用来保存一些特殊信息,比如地址(保护断点)或者一些数据(保护现场),如果你一定要说这个存储区有什么特别的话,那就是:1、这些存储单元内的内容都是CPU在执行某任务中途被打断时的一些相关参数;2、这些存储单元的地址被记在了一个叫堆栈指针的地方,也就是C哥口袋里的那张纸条上!

来源:单片机与嵌入式

围观 33

对于初学者而言,对单片机的内存分配往往最让人头疼,很多人学了单片机几年 都不知道单片机内部的内存使用情况是如何分配的。要了解 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(零初始化数据区)

  • Flash 存储 code和RO-data
  • Sram 存储 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

围观 252

1. MCU有串口外设的话,在加上电平转换芯片,如MAX232、SP3485就是RS232和RS485接口了。

2. RS485采用差分信号负逻辑,+2~+6V表示0,-6~-2表示1。有两线制和四线制两种接线,四线制是全双工通讯方式,两线制是半双工通讯方式。在RS485一般采用主从通讯方式,即一个主机带多个从机。

3. Modbus是一种协议标准,可以支持多种电气接口,如RS232,RS485,也可以在各种介质上传输,如双绞线,光纤,无线。

4. 很多MCU的串口都开始自带FIFO,收发FIFO主要是为了解决串口收发中断过于频繁而导致CPU的效率不高的问题。

如果没有FIFO,则没收发一个数据都要中断处理一次,有了FIFO,可以在连续收发若干个数据(根据FIFO的深度而定)后才产生一次中断去处理数据,大大提高效率。

5. 有些工程师在调试自己的系统时一出现系统跑飞,就马上引入看门狗来解决问题,而没有思想程序为什么会跑飞?

程序跑飞可能是程序本身的bug,也可能是硬件电路的问题(本身就是易受干扰或自己就是干扰源)。通常建议在调试自己的系统时,先不加看门狗,等完全调试稳定了,在补上(危机产品安全,人身安全的除外)。

6. 如何区分有源蜂鸣器和无源蜂鸣器?

从外观上看,如将两种蜂鸣器的引脚都朝上放置时,可以看出绿色电路板的一种是源蜂鸣器,没有电路板而用黑胶密封的一种是有源蜂鸣器。

有源蜂鸣器直接接上额定电源就可以连续发声,而无源蜂鸣器则和电磁扬声器一样,需要接在音频输出电路上才能发声。

7. 电压比较器的用途主要是波形的产生和变换,模拟电路到数字电路的接口。

8. 低功耗唤醒的常用方式:处理器进入低功耗后就停止了很多活动,当出现一个中断时,可以唤醒处理器,使其从低功耗模式返回到正常运行模式。

因此在进入低功耗模式之前,必须配置莫个片内外设的中断,并允许其在低功耗模式下继续工作。如果不这样,只有复位和重新上电才能结束低功耗模式。处理器唤醒后首先执行中断服务程序,退出后接着执行主程序中的代码。

9. 注册中断服务函数:中断服务函数已经编写好,但当中断事件发生时,CPU还是无法找到它,因为我们还缺少最后一步:注册中断服务函数。

注册有两种方法:一是直接利用中断注册函数,优点是操作简单,可移植性好,缺点是由于把中断向量表重新映射到SRAM中而导致执行效率下降;还有一种是需要修改启动文件,优点效率很高,确定可移植性不高。

10. 很多的MCU提供数字电源VDD/GND和模拟电源VDDA/GNDA。通常建议是采用两路不同的3.3V电源供电。但为了节省成本,也可以采用单路3.3V电源,但VDDA/GNDA要通过电感从VDD/GND分离出来。

一般GNDA和GND最终还是要连接在一起的,建议用一个绕线电感连接并且接点尽可能靠近芯片(电感最好放置在PCB背面)。

本文转自网络,版权归原作者。

围观 35

页面

订阅 RSS - 单片机