发帖数

53

原创数

53

关注者

11

阅读数

10236

点赞数

1

黄忠

  • 抛开CRC校验的“神秘面纱”

    大家好!我是张飞实战电子黄忠老师!今天给大家抛开CRC校验的“神秘面纱”!

    模2运算是一种二进制算法,CRC校验技术中的核心部分。与四则运算相同,模2运算也包括模2加法、模2减法、模2乘法、模2除法四种运算。


    与四则运算不同的是模2运算不考虑进位和借位,模2运算是编码理论中多项式运算的基础。下面我们就来看一看什么是模2运算。


    模2运算使用与四则运算相同的运算符,即“+”表示模2加,“-”表示模2减,“×”或“·”表示模2乘,“÷”或“/”表示模2除。与四则运算不同的是模2运算不考虑进位和借位,即模2加法是不带进位的二进制加法运算,模2减法是不带借位的二进制减法运算。这样,两个二进制位相运算时,这两个位的值就能确定运算结果,不受前一次运算的影响,也不对下一次造成影响。


    “模2加法”就是0和1之间的加法,其中0+0 =0,1+0 =0+1 =1,1+1=0。这种运算是比较常用的,并不神秘。对于任意多个数a1,a2,…,an(每个都是0或1),可以把它们做模2加法a1+a2+…+an。当这n个数中有奇数个1时,结果为1,否则结果为0。例如0101+0011=0110,列竖式计算:

    image.png

    模2减法是一种不考虑借位的减法,其定义如下:0-0=0,1-1=0,1-0=1,0-1=1。同样,第四式代表了模2减法的特征。在多位模减法中,每位都按上述定义进行运算,不考虑借位问题。根据上面减法可以得出一个结论:奇数个1相减得1,偶数个1相减得0。例如0110-0011=0101,列竖式计算:

    image.png

    一位数的模2乘法定义如下:0*0=0,0*1=0,1*0=0,1*1=1,多位数的模2乘法与普通乘法一样演算,区别是,部分积相加时按模2加,即奇数个1相加得1,偶数个1相加得0。例如1011×101=100111,列竖式计算:

    image.png

    模2除法是模2乘法的逆运算,定义如下:0÷1=0,1÷1=1,类似于普通的多位二进制除法,但是在如何确定商的问题上两者采用不同的规则。普通多位二进制除法按带借位的二进制减法,根据余数减除数够减与否确定商1还是商0,若够减则商1,否则商0。多位模2除法采用模2减法,不带借位的二进制减法,因此考虑余数够不够减除数是没有意义的。实际上,在CRC运算中,总能保证除数的首位为1,则模2除法运算的商是由余数首位与除数首位的模2除法运算结果确定。因为除数首位总是1,按照模2 除法运算法则,那么余数首位是1就商1,是0就商0。例如1011÷101=110101...001,列竖式计算:

    image.png

    模2算术是编码理论中多项式运算的基础。大家一定要掌握哦,下篇文章我们就一起看看它到底在CRC中是如何发挥作用的。

    收藏 0 回复 0 浏览 117
  • 单片机支持操作系统的特性


    大家好!我是张飞实战电子黄忠老师!今天给大家分享单片机支持操作系统的特性。

    1、支持操作系统的特性概述:

    就拿M0核的单片机来说,就有一部分特性是针对嵌入式操作系统的(OS),包括:

    SysTick定时器,24位向下计数,且周期产生SysTick异常。

    栈指针,即进程栈指针,两个栈指针的结构可以使得应用栈和OS内核栈相互独立。

    SVC异常和SVC指令,通过异常机制,应用程序可以使用SVC访问OS服务。

    PendSV异常,其可以被OS、设备驱动或者应用程序使用来产生可延迟的服务请求。

    2、为什么要使用嵌入式操作系统?

    当提到操作系统的时候,大多数人首先会想到WindowsLinux之类的桌面操作系统。这些操作系统要想运行起来,需要强大的处理器、大量的存储器以及其他硬件,而对于嵌入式设备,各种OS的差别很大。嵌入式操作系统可以运行在低功耗的微控制器上,它们需要很少的存储器(相对于桌面系统),并且运行的时钟频率要低很多,比如Keil RTX只需要4KB的程序空间以及大约0.5KBSRAM,一般情况下,这些操作系统设置不需要显示或者键盘。当然也可以增加一些显示接口和输入设备,并且通过运行在OS上的应用任务来访问这些输入和输出接口。

    在嵌入式应用程序中,OS一般用来管理多任务。在这种情况下,OS将处理器时间划分多个时间片,并且在每个时间片上执行不同的任务。当一个时间片结束时,OS任务调度器开始执行,这样在下一个时间片开始的时候,处理器已经切换到其他任务执行了。这种任务切换一般被称作上下文切换。

    每个时间片的长度依赖于硬件以及操作系统的设计,有些嵌入式操作系统每秒会进行几百次的任务切换。

    有些嵌入式OS也为每个任务定义了优先级,这样高优先级的任务就能在低优先级任务之前执行。如果一个任务的优先级比其他的都要高,在其到达空闲状态前,OS可能会连续多个时间片都在执行这个任务。应该注意的是,OS的优先级的定义与异常优先级是完全独立的(例如中断的优先级)。任务的优先级基于特定的OS,并且随着OS的不同而有所区别。

    除了支持多任务以外,嵌入式OS也提供了其他各种功能,包括资源管理、内存管理、电源管理,以及应用程序编程接口(API)用以访问外设、硬件和信道。


    hu.jpg

    使用嵌入式OS并不总是有好处的,因为它需要额外的程序空间来存放OS内核,而且会增加执行周期的开销。多数简单应用并不需要嵌入式OS,不过,有些复杂的嵌入式应用需要并行执行任务,这时使用OS会使软件开发更加容易,并且降低出现错误的概率。

    目前,可以应用在M0上的嵌入式OS有很多,例如,Keil 微控制器开发套件提供的免费且易于使用的RTX kernel,另外还有Micriumuc/OS-IIuc/OS-III等都支持M0处理器。并且这个支持的操作系统在不断的增加中。

    由于很多微控制器是不具备存储器管理单元(MMU),比如我们上面时候的M0核的处理器,所以它不能运行需要虚拟地址的嵌入式OS,比如Windows CESymbian OS。平常使用的Linux OS也需要MMU,它也不能再M0上工作。而uCLinuxLinux的特殊版,并且面向的是没有MMU的嵌入式设备,所以要在微控制器上加入OS也要先看能不能支持,并且支持哪些,再结合自己的项目实际选取。

     


    收藏 0 回复 0 浏览 140
  • 什么是Map文件,它有什么用?

         大家好!我是张飞实战电子黄忠老师;前文章《不要再找啦,关于Cortex-Mx芯片的启动没有比这里更清楚啦》STM32单片机的启动流程以及main函数的执行做了一个详细的分析,今天我们MDK编译、链接后生成的map文件简单分析一下,加深对链接器、嵌入式系统可执行映像特点的了解。

    什么是map文件?简单的说map文件是通过编译器编译之后,集众多信息为一身的一种映射文件。很多工程师在遇到内存越界溢出情况分析map文件。通过map文件可以知道函数大小,入口地址等一些重要信息。最直观的的在Keil编译之后,编译窗口会显示类似如下一段信息:Program Size这一段提示信息汇总了程序和数据的信息,这些信息是单个模块汇总而成,在map文件里有详细列表。

    图片1.png 

    1.Section Cross References,主要是各个源文件生成的模块之间相互引用的关系。

    图片2.png
    上面这句话,main.omain.c生成的目标文件模块,start.ostart.s生成的目标文件模块,上面这2个含义是:用户在start.o启动代码中调用了__main.o模块中的StartProgram函数,StartProgram又调用了同文件中Led_Init函数。
     
    2.Removing Unused input sections from the image. 就是将库中没有用到的函数从可执行映像中删除掉,减小程序的体积。
    3.Image Symbol Table

    图片3.png
     

    Local Symbols 是系统内部的局部标号以及用户的一些局部标号
    图片4.png
    Global Symbols此部分描述了系统以及外部标号的所属地址、所占空间大小、所属文件等信息。
    图片5.png     

    4. Memory Map of the image映像的内存分布图片6.png
    1>.Image Entry point : 0x08000009,这个指的是复位程序RESET_Handler的地址。
    2>.Load Region LR_1 (Base: 0x08000000, Size: 0x00000044, Max:0xFFFFFFFF, ABSOLUTE),是程序的加载映像地址和长度,0x00000044=Start.0文件的大小(0x0C) + main.oLed_Init函数的大小(0x3C) + main.oStartProgram函数的大小(0x08)
    3>.Execution Region ER_RO (Base: 0x08000000, Size: 0x00000044, Max:0xFFFFFFFF, ABSOLUTE,指的是程序中的代码段和常量。
    4>.Execution Region ER_RW(Base: 0x20000000, Size: 0x00000000, Max: 0xFFFFFFFF, ABSOLUTE) 指的是可读写的全局变量和静态变量区域,因为我们现在只是一个简单的测试程序,没有变量,所以这里Size大小为0

    5>.Execution Region ER_ZI(Base: 0x20000000, Size: 0x00000000, Max: 0xFFFFFFFF, ABSOLUTE) 指的是程序中被初始化为零的变量,这里Size大小为0的原因同上。

    6>6.Image component sizes 这是指各个模块的大小信息

    图片7.png
    Total RO  Size (Code + RO Data)                680.07kB)
    Total RW  Size (RW Data + ZI Data)              68 (   0.00kB)
    Total ROM Size (Code + RO Data + RW Data)      68 (  0.07kB)

    图片8.png
    由于我们测试程序总没有定义一些变量,只是简单的操作了3个寄存器,所以RW Data + Zi Data0,其余全是代码指令信息,共680x44)个字节,程序总大小为68/10241KB = 1024个字节), 约0.07Kb

    至此我们已经解开了Map文件的神秘面纱,文件包含的信息全部分析完成,从文件中我们可以得出一些有用的信息,便于我们在分析调试代码的时候使用,当然Map配合链接文件(.sct)可能会看到直接的效果,后期有机会我们聊一聊链接文件,谢谢大家。




    收藏 0 回复 0 浏览 1286
  • 24C02存储细节规范

    大家好,我是张飞实战电子黄忠老师;前面文章分享了I2C的一个标准规范,只是知道这些标准规范,还不能和目标器件进行正常通信,我们以24C02(EEPROM)为例来做一个简单说明,想要和EEPROM通信,就得遵从EEPROM的通信规范因为EEPROM是一个不可编程器件,它的规范是固定的。
        那么它都有哪些规范需要我们去注意呢?比如数据传输的时候拉高拉低要保持多长时间才有效通信的时候要按照什么格式写,先发高位还是低位等等。在这里一共有4个时间需要注意,分别为数据建立时间,保持时间,时钟高电平时间,时钟低电平时间,手册上对这几个时间都是有要求的。
    图片9.png
        从图中我们看出,当我们在SCL为低电平期间,把SDA数据改变,这个时候SCL时钟还是要保持一段时间才能拉高发送,这个保持的时间就是数据建立时间
    图片10.png图片10.png

    1                                图2
        从图1箭头处可以看出,当我们把SCL拉低之后,SDA数据是不可以立马去改变的,SCL时钟拉低还是要保持一段时间才能去改变SDA数据线电平的,这个时间就是保持时间

    从图2箭头处可以看出,当我们把SCL拉高发送数据的时候,这个SCL时钟保持高电平,是要持续一定时间的,这个时间就是时钟高电平时间,时钟低电平时间也是同理

    图片12.png
      这个是24C02器件在400K高速通信4个时间的要求,那我们在进行单片机编程的时候,我们需要根据这几个C间设置相关寄存器24C02操作时,不光有这几个时间,它还有自己的通信协议规范我们以字节写为例,来进行说明。
      下图就是24C02通信协议我们先看对24C02写数据,是1个字节写指令根据这个写一个字节对应的定义我来一个一个进行解释
    图片13.png图片14.png
    1表示启动
    2表示设备地址也就是我们说的从机地址设备地址为7位),发地址时,先发地址的高位,再发低位(MSB为高位,MSB在前,表示先发),可以通过24C02器件某几个特定的引脚接不动的电平状态来设置地址。
    3表示是对从机如何操作,是读还是写(一个位)这里是写操作
    4表示要读写数据的地址
    5表示要读写的数据内容

    6表示停止
    7表示每进行一次传输从机的应答每次传送1个字节,也就是8个bit也就是每8个bit一个ACK信号

    以上就是一个字节的写,当然还有多字节写,单字节读,多字节读等操作,原理都是一样的,知道了这些之后,我们才可以对应的去写程序代码。赶快去试试吧!


    收藏 0 回复 0 浏览 183
  • 单片机的几种复位电路

    大家好,我是张飞实战电子黄忠老师;在单片机的使用中,经常会接触到复位电路,它是单片机最小系统重要的一个构成部分。同样它也是非常重要的一部分。

    复位就是让单片机从初始化状态开始重新运行,即程序从头开始执行。复位电路设计的好坏,直接影响整个系统是否稳定可靠。复位电路与单片机的RESET/NRST引脚相连,拿STM32系列单片机举例,当系统正常工作时,如果RESET引脚电压低于某一阈值,则单片机进入复位状态。单片机的复位可分为低电平复位和高电平复位,这是由厂家决定的,区分的方式可以看数据手册,手册中的复位章节会写清楚是什么电平复位。单片机的复位可以分为:上电复位、掉电复位、软件复位、外部手动复位等。

    上电复位:单片机每次上电都会给RESET脚一个复位信号,让单片机从一个固定的相同状态重新开始工作;

    掉电复位:单片机复位引脚电压低于某一阈值电位时,单片机会进入复位状态。

    软件复位:程序员执行某一特定的复位指令,来使单片机进行复位,或者当程序在一定时间失去响应的情况下通过看门狗电路控制单片机进行复位。

    外部手动复位可以通过一个复位按键让死机或跑飞的程序重新运行。

        图片15.png图片15.png

    下面我们一起看一下常见的几种复位电路。

    图片16.png     图片17.png

                1                                                                                                                                                 2

    1是最常见的低电平上电复位原理图,我们来分析这个过程,上电前电容两端电压为0。上电后,电流从3.3V流经电阻、电容到地,由于电容两端电压不能突变,所以上电瞬间RESET脚上电压也为零,并保持一小段时间低电平,这段时间触发单片机复位;随着时间推移,电容两端电压太高超过某一阈值电位,复位完成。这个电阻、电容的取值大小影响到复位引脚电平的上升时间(电容的充电时间)。

    2 手动按键复位原理图,手动按钮复位在GND和RESET之间接一个按钮。当人为按下按钮时, RESET脚就会被GND拉为低电平,使单片机进入复位状态,如果手不松掉,那么会一直处于复位状态,直至手松掉之后,复位引脚电平恢复。下图位ST单片机内部的复位波形,上电的时候VDD大于Vpor并持续一定的时间,单片机脱离复位状态,掉电的时候Vdd电压低于Vpdr电压,单片机进行复位。

                 图片19.png

    软件复位也分两种,我们可以使用复位指令,直接使单片机进行复位,另外一种使用单片机内置看门狗,配置启动看门狗,在主循环程序中每隔一定地时间刷新看门狗,俗称喂狗。如果一定的时间没有喂狗,可以认为程序跑飞,则看门狗模块会复位单片机,内置看门狗又分窗口看门狗和独立看门狗,区别如下:

    时钟不同

    1、独立看门狗:独立看门狗使用的是内部专门的 40Khz低速时钟,不需要使能时钟操作。

    2、窗口看门狗:窗口看门狗使用的是 PCLK1的时钟,使用前需要先使能时钟。

    中断不同

    1、独立看门狗:独立看门狗没有中断,超时直接复位。

    2、窗口看门狗:窗口看门狗可以在中断中做复位前的函数操作,比如报错一些数据等。

    使用场景不同

    1、独立看门狗:独立看门狗一般用于避免程序跑飞或者死循环。

    2、窗口看门狗:窗口看门狗避免程序不安预定逻辑执行,比如先于理想环境完成,或者后于极限时间超时。

    当然复位衍生出来的电路形态可能不止上述的两种,但是基本上都是围绕上述的电路进行变换,最后强调一点,RESET的走线越短越好,复位电路一定要尽可能靠近MCU, 因为复位电路到单片机这一段的走线,可能会引入其他外界因素的干扰,是单片机处于不稳定的状态。关于复位的内容就跟大家分享到这里,大家有没有遇到过关于一些复位引起的问题呢?


    收藏 0 回复 0 浏览 688
×
黄忠