当前位置:首页 > 单片机
  • 热烈庆祝芯圣电子成为上海大学学生实习基地!

    热烈庆祝芯圣电子成为上海大学学生实习基地!

    2020年10月10日上午,上海芯圣电子股份有限公司与上海大学“大学生实习与就业基地”授牌仪式暨校企座谈会在悉尼工商学院文荟楼409会议室顺利召开。 会上我司张兵总经理对公司的情况做了介绍,并表示未来将积极与两个学院开展合作,依托三方资源优势开展校企合作,拓展实习就业渠道,扩大合作内涵,实现企业、学校、学生三方共赢。签约环节,张兵总经理和胡春华科长分别代表上海芯圣电子股份有限公司和 上海大学签署《关于共同建立上海大学毕业生实习与就业基地协议书》,并为上海大学“大学生实习与就业基地”揭牌。胡春华科长代表上海大学向我司赠送《百年上大》与《永远的校长》两本画传。 授聘书环节,方慧副院长向张兵总经理和张金弟总监授予悉尼工商学院研究生校外导师聘书,李双书记向悉尼工商学院2007级校友叶嘉斌授予悉尼工商学院校友导师聘书。 在校企会谈环节,双方就人才培养、专业建设、科学研究、实习就业、社会服务等多方面开展交流与讨论,并就未来三方会更紧密的开展全方位合作达成一致。

    时间:2021-04-20 关键词: 单片机 芯片

  • 远程升级单片机程序怎么设计?

    远程升级单片机程序怎么设计?

    之前的文章中介绍过串口和U盘的IAP程序设计。在物联网应用中,远程IAP升级MCU的程序是一项非常有用的功能。当设备出现程序问题或者需要更新程序时,只需要在服务器上对设备进行升级,不需要在有专门的人员去现场进行升级,节省人力物力。 要实现远程升级,首先要实现以下几个基本功能: 1、Flash读写。不管是本地IAP还是远程IAP,这都是最基本的功能。 2、无线通讯。可通过WIFI、4G、以太网等多种方式来实现,根据实际项目需求选择。 3、通讯协议。常用的通讯协议有TCP、HTTP、FTP、MQTT等。其中HTTP、FTP和MQTT都属于应用层协议,都是基于TCP(传输层)来实现的。用户也可以自己基于TCP编写简单的通讯协议来实现。 远程IAP与本地IAP的设计思路是一致的,都需要设计BOOT程序和APP程序。但也有一些需要注意的地方。主要是远程升级需要考虑网络延迟甚至网络中断的问题。体现在以下几方面: 设计程序缓存区 在内部或外部存储器开辟一块区域,用于存储分包接收到的程序数据。等到全部数据接收完毕后再一次性写入到Flash进行升级。这样做有以下2点好处: 1.直接升级时间可能会比较长,影响用户正常使用,增加缓存区设计可以大大减少升级时间。 2 增加缓存区设计后,即使升级数据传输失败,也不影响设备的正常使用。 健壮的通讯协议 本地升级时数据传输出错的概率比较小。但远程设计时就需要多考虑一些,比如前后两包数据可能同时达到等。因此,设计通讯协议时,就要更严谨,服务器发送的指令和数据都需要设备的确认回复。 程序备份设计 即使有上面的各种设计的保障,也不能保证升级过程不会失败。最好能够设计一个程序备份区,在程序升级失败时运行备份区程序。 下面介绍一种简单的远程升级的步骤。 服务器发送升级请求指令。 设备回复收到请求升级指令。 服务器发送程序升级数据。(一般包含包头、包号、总包数、分包的程序数据、校验) 设备收到程序数据后,确认校验无误,存储到程序缓存区,并按包号回复服务器,防止出现传输包错乱。 服务器收到回复后再发送下一包数据,直至结束。 程序数据发送完成后,服务器发送升级结束指令。 设备收到结束指令后,回复服务器。并在Flash指定位置写入升级标志,重启进入BOOT程序。 BOOT程序读取升级标志,若需要升级,则读取程序缓存区数据,写入到Flash中。 升级完毕,跳转到Flash指定地址运行。

    时间:2021-04-20 关键词: 服务器 远程升级 单片机

  • 单片机在GPS和CDMA计时系统中的设计

    单片机在GPS和CDMA计时系统中的设计

    摘要介绍了一种基于MSP430单片机的GPS和CDMA双接收计时系统的设计思路与方法,并给出了系统的硬件电路和软件流程。该系统采用GPS和CDMA时钟信号,其可以自动调整时间,同时还拥有多方位保障时间的精确性、一致性、高可靠性及环境适应性强的优势。 在可靠性、扩展性、控制功能以及体积、功耗等方面比其他电子产品具有优越性。在天文、地震台、航空航天等对时间精度较高的场合,以及国防、通信、电力、交通等要求高精度时间同步的领域,得到广泛应用。 1 系统硬件设计方案 1.1 系统总体设计 基于MSP430单片机的GPS和CDMA双接收计时系统,是传统钟表计时技术与现代时频、微电子、通讯、计算机等多项技术的结合,通过接收不同形式的时间码,经内置微处理器解码处理,自动校准计时器走时,使该系统显示时间与标准时间自动保持精确同步。除保留传统机械时钟计时特点外,还增加了LCD数字显示,双显示方式。接收GPS、CDMA信号,实现双系统联合精确定时,在接收到精确的时码后,经数据处理器处理,即可自动校正时钟的走时误差,使每只时钟的走时均受统一精确的时码控制,从而实现了高精度计量时间的一致性,同时也可手动校时、接收时间信号,系统硬件框图如图1所示。 图1 系统硬件框图 1.2 系统各部分的硬件设计 1.2.1 MSP430 MCU MSP430F5xx是德州仪器仪表推出的实现超低功耗MSP430 MCU系列产品。该系列针对峰值高达25 MHz的产品,实现业界最低的功耗,拥有更高的闪存与RAM存储器存储容量,以及射频(RF)、USB、加密和LCD接口等集成外设。MSP430F5xx MCU的工作功耗与待机功耗仅为160μA/Hz与1.5μA,系统能以较小功耗运行的同时可执行高强度的任务。可充分发挥高达25 MHz峰值执行性能,同时确保功耗仅为160μA/HMz。MCU采用16位精简指令,一个时钟周期可执行一条指令,运行速度可达25~30 MI·s-1,而传统51单片机6个或12个时钟周期可执行一条指令。以上特点确保了其可编制出高效率的源程序,用以满足电池供电超低功耗要求。 1.2.2 GPS接收模块 GPS模块是应用较广的一种导航、定位和定时的多功能系统,具有全天候、高精度、自动测量以及体积小、功耗低的特点,且技术成熟、价格低廉。 GPS模块为系统提供GPS定时、定位信息,设计采用u-blox公司的MAX-6Q,其具有以下特点:(1)精度高,抗干扰能力强。(2)启动时间短,冷启动只需26 s,热启动只需1 s。(3)串行接口有1UART、1DDC,可方便与MSP430F5xx的UART模块通信。(4)体积小,电压为3.3 V,与MSP430F5xx相同。(5)输出信息采用标准的NEMA-0183协议。 1.2.3 CDMA接收模块 CDMA无线通信模块从CDMA基站上获取标准的时间信号,CDMA校时系统信号稳定,不易受电源、外界无线电干扰,便于部署在任何有CDMA信号的地方。针对以上特性,在室内无卫星信号或GPS信号难于接收的地点使用,恰好解决了常见的GPS模块局限性问题。 CDMA接收模块采用华为MC323模块,MC323将基带、RF收发器、电源管理模块单元、功率放大器集成,功能全面、应用广泛。其电路框图如图2所示。 图2 MC323电路框图 2 系统软件设计方案 系统的软件部分主要负责设置GPS模块与MCU之间的串口通信1、CDMA模块与MCU之间的串口通信2、时间的显示及人机接口。其主要包括初始化、串口通信、数据处理、故障提示、显示、键盘处理及电源管理等部分,其中初始化包括MSP430中各种寄存器的配置、串口相关参数配置以及外围电路的初始化等。 2.1 系统软件双接收的整体方案 系统采用GPS和CDMA双模式接收,同时可定时进行自动接收,也可通过外部接收按键进行强制接收。软件优先接收GPS模块的数据信息,当GPS数据无效或无法采集到信号时,再接收CDMA数据。若GPS和CDMA接收的数据有效,则更新数据;若无效,则数据保持。系统双接收处理流程如图3所示。 图3 系统双接收处理流程图 2.2 GPS模块接收方案 GPS模块MAX-6Q通信采用串口通信1,包括数据发送、接收、校验、通信障碍提示等,数据处理主要有GPS接收数据的解码、存储和数据刷新等。MAX-6Q的数据输出为NMEA-0183格式,最大更新速率5 Hz,为保证数据传输的可靠性与实时性,并提高单片机的利用率,文中采用中断方式而非查询方式。 在中断处理程序中,将接收到的GPS数据放入数组中,通过读取数据包的前7 bit,可判断该数据包格式,系统只处理了NEMA中GPGGA和GPZDA两种格式的消息,并定义了两种相应的处理函数,其各函数功能如下: GPZDA()函数:提出UTC日期和时间。 GPRMC()函数:提出UTC日期、时间、经度和纬度信息。 通过GPS数据处理,误码的判断,刷新数据显示,其GPS处理流程如图4所示。 2.3 CDMA模块接收方案 CDMA模块MC323通信采用串口通信2,数据处理主要是CDMA接收数据的解码、存储和数据刷新等。 CDMA接收打开,CDMA模块进行初始化。MSP430F5xx打开串口2向CDMA模块MC323发出查询指令“AT^TIME”,若查询时间超过10 min,则自动退出查询。CDMA模块MC323收到“AT^TIME”查询指令后,向单片机返回时间信息,而单片机将对时间信息进行分析处理并将处理后的时间信息进行存储和更新,CDMA处理流程如图5所示。 3 结束语 根据GPS和CDMA的不同特点,采用两种接收模式联合定时,不仅在GPS接收正常时,能保证时间的高精度、一致性,且在GPS失效或室内GPS信号接收困难时,通过CDMA接收,同样保障了时间的精确性和一致性,且还具有可靠性高、环境适应性强的特点。本单片机采用MSP430,其不仅功耗低,且处理能力强,模拟技术性能高及片上外围技术丰富,故满足了低功耗高性能的要求。此外,性能还可满足高精度计时系统对时间精度性和实时性的要求,本设计不论在室外或室内均具有良好的接收、自动智能授时能力。其既可满足精度要求较高的天文、航空航天等系统,又可满足普通民用使用,还可应变特殊情况下的使用需求,因此拥有良好的应用前景。

    时间:2021-04-15 关键词: CDMA GPS 计时系统 单片机

  • 基于MSP430单片机的称重式液位仪的设计

    基于MSP430单片机的称重式液位仪的设计

    1 引言 液位测控仪是属于智能化仪器仪表的一种(指采用了微处理器的仪器仪表),其发展始于70年代[1]。它是一种集测量与控制于一体的智能化产品,适用于石油化工、冶金、电力、制药、环保等行业中各种介质的液位测量。本仪器主要针对罐体内液体进行测量并能计算其重量,适用于对各种液态物质进行静态和动态测量与监控,并具有超限报警和主-从站模式联网功能。 2 系统设计方案 2.1 液位传感器的选择 一般情况下在液位测量中所采用的传感器有:压力传感器、超声波传感器、浮子式传感器等,由于系统设计中要求在测量液位的同时还要实现液体重量的检测。在液罐内,液体重量P的检测可直接利用计算得到,即P=H*S*ρ(H为液体高度CM;S为圆面积M2;ρ为液体比重),因此只有提高液位测试的分辨率才能保证液体重量测试的精度,本系统中液位测试分辨率为1cm。另外,考虑到压力传感器接口电路相对采用超声波传感器的接口电路要简单,因此确定采用压力传感器。 2.2 MSP430单片机 MSP430单片机为低功耗16位单片机,具有典型的SOC特点,集成大量外设。尤其是其内部集成的波特率微调器,可以使MCU在不低于32768HZ的任意晶振(但不能超过MCU对晶振要求的上限)下工作时,其通信波特率的选择可不受波特率因子不能带有小数的限制,即:在波特率的允许范围内可使用任意频率的晶振[2] [3]。另外,由于MSP430 MCU内部集成了温度传感器,可以很方便的实现对测液位所用的压力传感器的温度补偿。而且MSP430系列单片机针对不同的应用而由各种不同的模块组成,这些微控制器被设计为可用电池工作,并且可以使用很长时间。 2.3 模拟信号转换技术 由于系统的执行部件为电磁阀,易产生电磁干扰,因此为能够可靠的工作必须要使系统具有较高的抗干扰性。 一种方法是直接利用MCU内部的A/D转换器,其特点是:无须外围电路,采样速度快,但抗干扰能力较差[4]。 另一种方法是使用V/F变换器来实现A/D转换。由于V/F变换是利用积分电容的电荷平衡原理实现电压频率转换,因此该方式稳定性好,分辨率高,信号线少,便于实现光电隔离以提高系统的抗干扰性,但转换速度相对较慢。 考虑到压力信号是一个缓变信号,一般无须快速采样,为使系统具有较高的抗干扰性,根据分析对比,选择采用V/F变换器来实现对压力信号的处理,计算处理较简单,在测量精度方面也能达到使用要求,并且易于做到实时控制。 3 系统总体组成结构及工作原理 如图1所示,整个系统由单片机主机系统、传感器信号处理电路、液位控制电路、声光报警、键盘、液晶显示、电源模块和通信等模块组成。P1口作为系统的数据线,V/F转换电路的输出信号作为中断请求信号接至MCU的P2.4脚,P2.6和P2.7为执行部件电磁阀的控制信号,分别控制进液、出液电磁阀。声光报警电路的控制信号为P2.5。键盘接口电路通过P3.0,P3.1和P3.2接入MCU用来控制系统的6个按键。系统通过P3.0和P3.3输出信号给74HC245用做LCD汉字液晶显示器的数据接口,P3.0和P3.3用做LCD的控制信号。P3.4和P3.5为MCU的串行通信数据线,经由通信电路与从机连接,用来进行主站、从站之间的串行通信。系统的电源模块产生3.3V、+5V和-5V电压,分别为主机系统和传感器接口电路提供稳定的工作电压。 图1 系统总体构成图 本系统通过压力传感器进行液体压力的数据采集,经过V/F转换模块进行液位高度和液体重量的标定,实现高精度的测量。当容器内的液位值超过了设定值或警戒值时,系统自动启动报警电路进行声光提示报警。用户可以通过键盘设定液位的上、下限值和进液、出液量等参数,以便使容器内液位保持设定的液位值。系统采用大屏幕液晶汉字显示,可以显示出当前液位值、设定的液位上下限值、容器内当前液体重量和进液、出液阀门的状态等。主站控制8个从站中的任意一个,并完成主站和从站的同步通信,主站具有该系统的所有功能,并且可以对从站中的液位上下限值等进行设置,主站在巡回检测时,可以任意设定要查询的从站数目、从站号和从站容器中的液位高度。当主站、从站中的液位超过警戒限时,主站可以进行声光报警并能显示报警的从站号。同时从站也可以依据通信协议通过通讯模块将从站号、液位值和报警信号传送给主站,并且从站可以接受主站的控制信息并能自动执行,还可以自动报警和解除报警。系统中从站号可以任意设定。同时该系统还可以实时显示工作环境的温度和时间。 4 系统的主要硬件电路设计 4.1 V/F转换电路设计 如图2所示,输入电压经射随器UD1A从LM331的7脚输入,电阻RD7 可以抵消6脚的偏流影响,从而减小频率误差,为了减少LM331的增益误差和由RD10、RD11、CD2引起的偏差,RD13选用51K电阻CD1为滤波电容。当6脚和7脚的RC时间常数相匹配时,输入电压的阶跃变化将引起输出频率的阶跃变化,如果CD3比CD1大的多那么输入电压的阶跃变化可引起输出频率的瞬间停止,6脚的电阻和电容可以差生滞后效应,以获得良好的线性度。 图2 V/F转换电路原理图 4.2液位检测及控制电路 系统通过压力传感器进行数据信号采集,采集到的信号经过运算放大器进行信号放大。放大后的信号送入V/F进行压频转换,将其输出的频率信号作为中断请求信号接至MCU的P2.4脚,由MCU对其进行处理后,将其转换成液位值,并根据液位设定值和上、下限值控制相应的电磁阀,使容器内液位高度与设定值保持一致。为便于电路的调试和观察,每个电磁阀都设有工作状态指示灯,表明当前是出液阀还是进液阀正在工作。其控制电路见图3。 图3 液位测量及控制电路 4.3 声光报警电路设计 声光报警电路由三极管、发光二极管、电阻、电容、蜂鸣器等组成,当所测到的液位值超过所设定的警戒值时,单片机发出报警信号,当收到报警信号后发光二极管OUT被点亮、蜂鸣器发出声音,产生声光报警。 5 系统软件设计 系统的软件采用模块化结构设计,分为六大块即:系统初始化模块、LCD显示模块、按键识别及处理模块、液位检测及控制模块、主从站通信模块。时间、工作环境温度检测模块。 系统通过初始化模块设置显示缓冲区、堆栈指针、操作标志和工作寄存器、各I/O端口的方向、系统定时器模块、通信模块、以及系统中断设置等。键盘模块负责按键的识别和按键处理,当有按键动作时调用相应的按键处理子程序进行处理。可实现对进出的液体量和上、下报警限进行设置,也可利用按键对各电磁阀进行手动控制。当液位超过警戒限时,调用液位检测及控制模块进行相应的控制,以使相应的电磁阀动作。在自动检测和自动控制的同时,将相关数据和控制参数,通过通信模块发送给主站。各从站在进行检测和控制的同时也在不断的侦听主站是否有命令或数据发送过来,如果有则立即处理。 6 结论 本仪器可广泛应用于测量水、油、酸类、酒类、饮料等的液位高度。可根据设定的上下两个极限液位,自动控制进液和排液,并具有多台联网功能。本仪器工作性能稳定可靠,体积小,测量及控制准确灵敏,安装使用方便,功耗低。目前已在一家食品企业中投入使用。 创新点 采用的16位单片机MSP430具有高性能低功耗的特点,是取代8位51系列单片机的较好选择。而且测量方法非常简洁且精度高、测试范围较广,具备称重功能和主-从站模式联网功能。

    时间:2021-04-15 关键词: MSP430 称重式液位仪 单片机

  • 分析C51单片机的一些误区和注意事项

    分析C51单片机的一些误区和注意事项

    简介:常看见初学者要求使用_at_,这是一种谬误,把C当作ASM看待了。在C中变量的定位是编译器的事情,初学者只要定义变量和变量的作 用域,编译器就把一个固定地址给这个变量。怎么取得这个变量的地址?要用指针。 1) C忌讳绝对定位。常看见初学者要求使用_at_,这是一种谬误,把C当作ASM看待了。在C中变量的定位是编译器的事情,初学者只要定义变量和变量的作 用域,编译器就把一个固定地址给这个变量。怎么取得这个变量的地址?要用指针。比如unsigned char data x;后,x的地址就是&x, 你只要查看这个参数,就可以在程序中知道具体的地址了。所以俺一看见要使用绝对定位的人,第一印象就是:这大概是个初学者。 2) 设置SP的问题。 原因和1差不对,编译器在把所有变量和缓冲区赋予地址后,自动把最后一个字节开始的地方,作为SP的开始位置,所以初学者是不必 要去理会的。这体现C的优越性,很多事情C编译时候做了。 3) 用C的主程序结构: #include void main(void) { while(1); } 这是个最小的成功的C程序,包括头部文件和程序主体。 头部文件的名词解释:引用的外部资源文件,这个文件包括了硬件信息和外部模块提供的可使用的函数和变量的说明。可以用文本方 式打开reg52.h,仔细研究下,会有一些写程序的体会。 4) 这样构成一个C项目 在C中,常用项目来管理。项目一般分为两大块:C文件块和头部文件块。 我们常把不同功能写在不同的C文件中,依据项目的管理,最后把所有文件连接起来,这样就可以得到可以烧录的HEX文件或BIN文件。 这些C文件中,有且只有唯一一个包括main()函数,和3)中一样的C文件。 用头部文件把各个不同的C互相连接起来。 一个C文件基本上要对应有一个H头部文件,这个H文件就包含本C文件中可以提供给外面使 用的变量和函数,没有在H文件中列出的募??梢运闶歉肅文件的内部函数和变量,外部C不能使用。 例子:a.C: unsigned char i; unsigned char mWork; void Test1(void) { mWork++; } void Test2(void) { i++; } a.h文件中: extern unsigned char i; extern void Test1(void); 这样主程序M.c中: #include /*C编译器内部自带的H文件,使用<>*/ #i nclude 'a.h' /*自定义的H文件,一般用''*/ void main(void) { Test1(); /*使用a.c模块文件中的函数*/ while(1){ i++; /*使用a.c模块文件中的变量*/ } } 5) 51家族 核心都是基于8031的,有很多在此核心上进行扩展,有的把程序存储器放在内部:89c(S)51..,有的增加了RAM:89c(S)52..,有的增加 了一些专用硬件80C552...,有的改变时钟时序W77E58...。市面上现在常用的主要有ATMEL公司的AT89X系列,PHILIPS的P87(89)x,台 湾WINBOND的w77(78)x系列,Cygnal的C8051Fx系列。 6) 51单片机结构的C描述 这里不讲51的具体结构,只是引导初学者快速理解51单片机的物理结构。寄存器和IO及其它硬件设备的地址名称,在相应的C头部文件 中可以找到。51为reg51.h,52为reg52.h,以次类推,比如winbond的78E58就为w78e58.h这些H文件中的描述: srf,定义一个8位的设备。 srf16,定义一个16位的设备。 sbit,定义一个位的设备。 用这些语句定义后,就可以在C中象汇编一样使用这些硬件设备,这是单片机应用比标准C特殊的地方,其它差别很少。 7) 在51系列中data,idata,xdata,pdata的区别 data:固定指前面0x00-0x7f的128个RAM,可以用acc直接读写的,速度最快,生成的代码也最小。 idata:固定指前面0x00-0xff的256个RAM,其中前128和data的128完全相同,只是因为访问的方式不同。idata是用类似C中的指针方式 访问的。汇编中的语句为:mox ACC,@Rx.(不重要的补充:c中idata做指针式的访问效果很好) xdata:外部扩展RAM,一般指外部0x0000-0xffff空间,用DPTR访问。 pdata:外部扩展RAM的低256个字节,地址出现在A0-A7的上时读写,用movx ACC,@Rx读写。这个比较特殊,而且C51好象有对此BUG, 建议少用。但也有他的优点,具体用法属于中级问题,这里不提。 8) startup.a51的作用 和汇编一样,在C中定义的那些变量和数组的初始化就在startup.a51中进行,如果你在定义全局变量时带有数值,如unsigned char data xxx=100;,那startup.a51中就会有相关的赋值。如果没有=100,startup.a51就会把他清0。(startup.a51==变量的初始化)。 这些初始化完毕后,还会设置SP指针。对非变量区域,如堆栈区,将不会有赋值或清零动作。 有人喜欢改startup.a51,为了满足自己一些想当然的爱好,这是不必要的,有可能错误的。比如掉电保护的时候想保存一些变量, 但改startup.a51来实现是很笨的方法,实际只要利用非变量区域的特性,定义一个指针变量指向堆栈低部:0xff处就可实现。 为什么还要去改? 可以这么说:任何时候都可以不需要改startup.a51,如果你明白它的特性。

    时间:2021-04-12 关键词: C51 误区 注意事项 单片机

  • 总结单片机软件抗干扰的几种办法

    总结单片机软件抗干扰的几种办法

    简介:在提高硬件系统抗干扰能力的同时,软件抗干扰以其设计灵活、节省硬件资源、可靠性好越来越受到重视。下面以MCS-51单片机系统为例,对微机系统软件抗干扰方法进行研究。 1、软件抗干扰方法的研究 在工程实践中,软件抗干扰研究的内容主要是:一、消除模拟输入信号的噪声(如数字滤波技术);二、程序运行混乱时使程序重入正轨的方法。本文针对后者提出了几种有效的软件抗干扰方法。 1.1 指令冗余 CPU取指令过程是先取操作码,再取操作数。当PC受干扰出现错误,程序便脱离正常轨道“乱飞”,当乱飞到某双字节指令,若取指令时刻落在操作数上,误将操作数当作操作码,程序将出错。若“飞”到了三字节指令,出错机率更大。 在关键地方人为插入一些单字节指令,或将有效单字节指令重写称为指令冗余。通常是在双字节指令和三字节指令后插入两个字节以上的NOP。这样即使乱飞程序飞到操作数上,由于空操作指令NOP的存在,避免了后面的指令被当作操作数执行,程序自动纳入正轨。 此外,对系统流向起重要作用的指令如RET、RETI、LCALL、LJMP、JC等指令之前插入两条NOP,也可将乱飞程序纳入正轨,确保这些重要指令的执行。 1.2 拦截技术 所谓拦截,是指将乱飞的程序引向指定位置,再进行出错处理。通常用软件陷阱来拦截乱飞的程序。因此先要合理设计陷阱,其次要将陷阱安排在适当的位置。 (1)软件陷阱的设计 当乱飞程序进入非程序区,冗余指令便无法起作用。通过软件陷阱,拦截乱飞程序,将其引向指定位置,再进行出错处理。软件陷阱是指用来将捕获的乱飞程序引向复位入口地址0000H的指令。通常在EPROM中非程序区填入以下指令作为软件陷阱: NOPNOPLJMP 0000H其机器码为0000020000。 (2)陷阱的安排 通常在程序中未使用的EPROM空间填0000020000。最后一条应填入020000,当乱飞程序落到此区,即可自动入轨。在用户程序区各模块之间的空余单元也可填入陷阱指令。当使用的中断因干扰而开放时,在对应的中断服务程序中设置软件陷阱,能及时捕获错误的中断。如某应用系统虽未用到外部中断1,外部中断1的中断服务程序可为如下形式: NOPNOPRETI返回指令可用“RETI”,也可用“LJMP0000H”。如果故障诊断程序与系统自恢复程序的设计可靠、完善,用“LJMP0000H”作返回指令可直接进入故障诊断程序,尽早地处理故障并恢复程序的运行。 考虑到程序存贮器的容量,软件陷阱一般1K空间有2-3个就可以进行有效拦截。 1.3 软件“看门狗”技术 若失控的程序进入“死循环”,通常采用“看门狗”技术使程序脱离“死循环”。通过不断检测程序循环运行时间,若发现程序循环时间超过最大循环运行时间,则认为系统陷入“死循环”,需进行出错处理。 “看门狗”技术可由硬件实现,也可由软件实现。在工业应用中,严重的干扰有时会破坏中断方式控制字,关闭中断。则系统无法定时“喂狗”,硬件看门狗电路失效。而软件看门狗可有效地解决这类问题。 笔者在实际应用中,采用环形中断监视系统。用定时器T0监视定时器T1,用定时器T1监视主程序,主程序监视定时器T0。采用这种环形结构的软件“看门狗”具有良好的抗干扰性能,大大提高了系统可靠性。对于需经常使用T1定时器进行串口通讯的测控系统,则定时器T1不能进行中断,可改由串口中断进行监控(如果用的是MCS-52系列单片机,也可用T2代替T1进行监视)。这种软件“看门狗”监视原理是:在主程序、T0中断服务程序、T1中断服务程序中各设一运行观测变量,假设为MWatch、T0Watch、T1Watch,主程序每循环一次,MWatch加1,同样T0、T1中断服务程序执行一次,T0Watch、T1Watch加1。在T0中断服务程序中通过检测T1Watch的变化情况判定T1运行是否正常,在T1中断服务程序中检测MWatch的变化情况判定主程序是否正常运行,在主程序中通过检测T0Watch的变化情况判别T0是否正常工作。若检测到某观测变量变化不正常,比如应当加1而未加1,则转到出错处理程序作排除故障处理。当然,对主程序最大循环周期、定时器T0和T1定时周期应予以全盘合理考虑。限于篇幅不赘述。 2、系统故障处理、自恢复程序的设计 单片机系统因干扰复位或掉电后复位均属非正常复位,应进行故障诊断并能自动恢复非正常复位前的状态。 2.1 非正常复位的识别 程序的执行总是从0000H开始,导致程序从0000H开始执行有四种可能:一、系统开机上电复位;二、软件故障复位;三、看门狗超时未喂狗硬件复位;四、任务正在执行中掉电后来电复位。四种情况中除第一种情况外均属非正常复位,需加以识别。 (1)硬件复位与软件复位的识别 此处硬件复位指开机复位与看门狗复位,硬件复位对寄存器有影响,如复位后PC=0000H,SP=07H,PSW=00H等。而软件复位则对SP、SPW无影响。故对于微机测控系统,当程序正常运行时,将SP设置地址大于07H,或者将PSW的第5位用户标志位在系统正常运行时设为1,那么系统复位时只需检测PSW.5标志位或SP值便可判此是否硬件复位。 由于硬件复位时片内RAM状态是随机的,而软件复位片内RAM则可保持复位前状态,因此可选取片内某一个或两个单元作为上电标志。设40H用来做上电标志,上电标志字为78H,若系统复位后40H单元内容不等于78H,则认为是硬件复位,否则认为是软件复位,转向出错处理。若用两个单元作上电标志,则这种判别方法的可靠性更高。 (2)开机复位与看门狗故障复位的识别 开机复位与看门狗故障复位因同属硬件复位,所以要想予以正确识别,一般要借助非易失性RAM或者EEROM。当系统正常运行时,设置一可掉电保护的观测单元。当系统正常运行时,在定时喂狗的中断服务程序中使该观测单元保持正常值(设为AAH),而在主程中将该单元清零,因观测单元掉电可保护,则开机时通过检测该单元是否为正常值可判断是否看门狗复位。 (3)正常开机复位与非正常开机复位的识别 识别测控系统中因意外情况如系统掉电等情况引起的开机复位与正常开机复位,对于过程控制系统尤为重要。如某以时间为控制标准的测控系统,完成一次测控任务需1小时。在已执行测控50分钟的情况下,系统电压异常引起复位,此时若系统复位后又从头开始进行测控则会造成不必要的时间消耗。因此可通过一监测单元对当前系统的运行状态、系统时间予以监控,将控制过程分解为若干步或若干时间段,每执行完一步或每运行一个时间段则对监测单元置为关机允许值,不同的任务或任务的不同阶段有不同的值,若系统正在进行测控任务或正在执某时间段,则将监测单元置为非正常关机值。那么系统复位后可据此单元判系统原来的运行状态,并跳到出错处理程序中恢复系统原运行状态。 2.2 非正常复位后系统自恢复运行的程序设计 对顺序要求严格的一些过程控制系统,系统非正常复位否,一般都要求从失控的那一个模块或任务恢复运行。所以测控系统要作好重要数据单元、参数的备份,如系统运行状态、系统的进程值、当前输入、输出的值,当前时钟值、观测单元值等,这些数据既要定时备份,同时若有修改也应立即予以备份。 当在已判别出系统非正常复位的情况下,先要恢复一些必要的系统数据,如显示模块的初始化、片外扩展芯片的初始化等。其次再对测控系统的系统状态、运行参数等予以恢复,包括显示界面等的恢复。之后再把复位前的任务、参数、运行时间等恢复,再进入系统运行状态。 应当说明的是,真实地恢复系统的运行状态需要极为细致地对系统的重要数据予以备份,并加以数据可靠性检查,以保证恢复的数据的可靠性。 其次,对多任务、多进程测控系统,数据的恢复需考虑恢复的次序问题。 系统基本初始化是指对芯片、显示、输入输出方式等进行初始化,要注意输入输出的初始化不应造成误动作。而复位前任务的初始化是指任务的执行状态、运行时间等。 对于软件抗干扰的一些其它常用方法如数字滤波、RAM数据保护与纠错等,限于篇幅,本文未作讨论。在工程实践中通常都是几种抗干扰方法并用,互相补充完善,才能取得较好的抗干扰效果。从根本上来说,硬件抗干扰是主动的,而软件是抗干扰是被动的。细致周到地分析干扰源,硬件与软件抗干扰相结合,完善系统监控程序,设计一稳定可靠的单片机系统是完全可行的。

    时间:2021-04-12 关键词: 软件抗干扰 MCS-51单片机 单片机

  • 单片机中写1清0和写0清0,有什么区别?

    单片机文档的时候一般寄存器是rw类型,还有一些是r或者w。对于一些特殊寄存器的置1是由硬件自动实现的,比如标志位flag、中断int;但清0还是需要通过软件进行操作。清0方式有两种,写1清0、写0清0。这两种方式有什么区别呢?在硬件实现上有什么不同? 单片机是可以进行位操作的,一个8位的寄存器,我们可以只针对其中一个位或者某些位进行操作,将寄存器相应的位赋值1(高电平)为置位,相反赋值0(低电平)为清零。这是一种比较容易理解的方式。 1)从电路角度去看,对某位写1,即输入一个高电平,使内部的一个三极管导通接地,电容放电进行清0。 2)写1是在硬件上产生一个复位脉冲。能写0清除就很可能也可以写1进去,而这与功能要求不符。如要控制只能写0而不能写1,则硬件比较复杂。 3)从应用便捷性角度来说,读了寄存器数据以后,照着写回去就可以清0,不用再更改一次数据。

    时间:2021-04-10 关键词: 寄存器 单片机

  • 单片机中的高阻态,就应该这样理解!

    对这个问题可能感到疑惑,为什么是高阻态?加上拉电阻?今天针对这一概念进行简单讲解。 高阻态 电路分析时高阻态可做开路理解,你可以把它看作输出(输入)电阻非常大。它的极限可以认为悬空,也就是说理论上高阻态不是悬空,它是对地或对电源电阻极大的状态。而实际应用上与引脚的悬空几乎是一样的。 高阻态的意义 典型应用 来源:网络 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    时间:2021-04-07 关键词: 51单片机 高阻态 单片机

  • 学习单片机必须要知道的字节小知识

    很二很二的单片机  单片机比较二,啥都不认识,只认识0和1,即所谓的“二进制”,由于把0和1认到了极致,所以单片机能用0和1干许多事情。人在看二进制数据时,比较麻烦。比如二进制110 0100,不能一眼看出是十进制100,这无疑降低了效率。为了提高效率,人类发明了很多单位,比如bit、Byte、KB、MB等。 今天的文章很简单,但是很重要。但是把简单的事情做到极致,人人都可以是单片机。 什么是bit位 二进制只有0和1两个状态,非此即彼,其中的任意一个状态就是一个bit位。bit位是数据存储的最小单位。一个bit有0和1两种状态;两个bit就有00、01、10和11四个状态;以此类推,三个bit就有000-111等八个状态,这个规律符合2^n。所以计算机能表示很多种状态。 单片机都有位数之分,比如STM8S为8位单片机,表示一次最多能处理8位数据;STM32F103为32位单片机,一次最多可以处理32位数据。 什么是字节Byte 数据比较多时,二进制看起来比较麻烦。八个bit位的数据构成一个字节Byte,所以一个字节有8位,即

    时间:2021-04-04 关键词: 单片机

  • 入门PIC需要准备什么工具

    最近,一个帖子上了21ic论坛的热榜。名为panxiaoyi的网友在论坛咨询了关于入门PIC的技巧,背景是这样的: 1:8位的PIC,选什么型号来学比较好?要求这个芯片是近几年【新推出】的【大众化】的,有LQFP32以下封装甚至有PID封装的。 2:MPLAB IDE ,MPLAB X IDE ,MPLAB® XC8 ,它们之间是什么关系?需要注册或者购买版权的吗?我只会用C语言,我需要安装什么软件? 3:需要购买下载线吗?还是有USB转串口即可下载?仿真工具暂时就不考虑了(如果是一体化的便宜的也可以考虑)。 4:我之前就喜欢玩AVR的ATmega48-88-168,没有选择M128来玩是因为觉得它比较老款,而且它没有LQFP32以下的封装,再说我也不需要太大的资源 5:最重要的是我不懂得E文,之前的AVR有少量的中文,后来出的基本没有中文数据手册了,而我这几天发现原来PIC【官网】有大量的中文数据手册,而且 MPLAB X IDE 也是中文界面的,既然它对中文这么友好,所有我就想学一下它。这几天我还在【芯圣】单片机那里购买了3块HC89F0541的51系列1T的开发板,正准备来玩一下的,突然发现这个PIC有个中文社区,里面有大量的中文资料,所以,就不想了解HC89F0541了,估计PIC比较可靠是吗? 另外也想说一下这个HC89F0541芯圣单片机,看【芯圣】资料他家的所有单片机都有一个很好的特色,就是:外设功能引脚全映射模块。它允许大部分功能端口可任意映射到任意I/O 端口,比如说UASRT的TXD,RXD,它可以指定由任意的IO脚输出或者输入。 热心的网友是这样推荐的: 开发、学习PIC单片机要用到以下软硬件工具: 1. MPLAB IDE 老的集成开发环境软件,这个是所有PIC单片机的开发平台,2016年以后推出单片机基本上已经不支持了; 2. MPLAB X IDE 新的集成开发环境软件,支持全部的8位、16位和32位芯片(部分比较老的芯片不支持); 3. MPLAB® XC8是8位单片机C语言编译器,你用C语言编程必须要用此编译器,需要单独安装配合 MPLAB X IDE 使用; 4. 另外还要用到PIC单片机开发板、编写器(如KIT4或ICD3、ICD4); 5.建议买一个 MPLABPICKit4在线调试器。 以上是最基本的开发配置。 推荐MPLAB X IDE(集成开发环境) + XC8(编译器), 硬件可以直接选择一块curiosity nano开发板。PIC系列8位单片机为适应各种不同的用途,推荐PIC16F722/3/4/6/7。另外,PIC16F1946和PIC16F877A是8位单片机中性价比较高的一种。 最终,panxiaoyi在芯片方面选择了PIC18F27Q10和PIC18F47Q10系列。选择它们是因为它们有中文数据手册,资源丰富,某宝购买方便,也不贵,包邮10多元。下载线选择了pic kit3.5。 软件环境方面,现在已经安装了 MPLAB X IDE v4.20 没有安装5.x版本,因为4.x的中文界面更好,同时也安装了xc8。 点灯例程: #include #include #include #include "CONFIGURATION.h"int main(int argc, char** argv){ unsigned long i; for(i=1000000;i>0;i--) { TRISA=0; PORTA=0; } for(i=1000000;i>0;i--) { TRISA=0; PORTA=255; } return (EXIT_SUCCESS);} #ifndef XC_CONFIGURATION_H#define XC_CONFIGURATION_H#include // include processor files - each processor file is guarded. // PIC18F24Q10 Configuration Bit Settings// 'C' source line config statements// CONFIG1L#pragma config FEXTOSC = ECH // External Oscillator mode Selection bits (EC (external clock) above 8 MHz; PFM set to high power)#pragma config RSTOSC = HFINTOSC_64MHZ// Power-up default value for COSC bits (HFINTOSC with HFFRQ = 64 MHz and CDIV = 1:1)// CONFIG1H#pragma config CLKOUTEN = OFF // Clock Out Enable bit (CLKOUT function is disabled)#pragma config CSWEN = ON // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)// CONFIG2L#pragma config MCLRE = INTMCLR // Master Clear Enable bit (If LVP = 0, MCLR pin (RE3) is an input; If LVP =1, MCLR pin (RE3) is MCLR)#pragma config PWRTE = OFF // Power-up Timer Enable bit (Power up timer disabled)#pragma config LPBOREN = OFF // Low-power BOR enable bit (Low power BOR is disabled)#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled , SBOREN bit is ignored)// CONFIG2H#pragma config BORV = VBOR_190 // Brown Out Reset Voltage selection bits (Brown-out Reset Voltage (VBOR) set to 1.90V)#pragma config ZCD = OFF // ZCD Disable bit (ZCD disabled. ZCD can be enabled by setting the ZCDSEN bit of ZCDCON)#pragma config PPS1WAY = ON // PPSLOCK bit One-Way Set Enable bit (PPSLOCK bit can be cleared and set only once; PPS registers remain locked after one clear/set cycle)#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)//#pragma config DEBUG = OFF // Debugger Enable bit (Background debugger disabled)#pragma config XINST = OFF // Extended Instruction Set Enable bit (Extended Instruction Set and Indexed Addressing Mode disabled)// CONFIG3L#pragma config WDTCPS = WDTCPS_31// WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)#pragma config WDTE = OFF // WDT operating mode (WDT Disabled)// CONFIG3H#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)#pragma config WDTCCS = SC // WDT input clock selector (Software Control)// CONFIG4L#pragma config WRT0 = OFF // Write Protection Block 0 (Block 0 (000800-001FFFh) not write-protected)#pragma config WRT1 = OFF // Write Protection Block 1 (Block 1 (002000-003FFFh) not write-protected)// CONFIG4H#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-30000Bh) not write-protected)#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)#pragma config SCANE = ON // Scanner Enable bit (Scanner module is available for use, SCANMD bit can control the module)#pragma config LVP = ON // Low Voltage Programming Enable bit (Low voltage programming enabled. MCLR/VPP pin function is MCLR. MCLRE configuration bit is ignored)// CONFIG5L#pragma config CP = OFF // UserNVM Program Memory Code Protection bit (UserNVM code protection disabled)#pragma config CPD = OFF // DataNVM Memory Code Protection bit (DataNVM code protection disabled)// CONFIG5H// CONFIG6L#pragma config EBTR0 = OFF // Table Read Protection Block 0 (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)#pragma config EBTR1 = OFF // Table Read Protection Block 1 (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)// CONFIG6H#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks)// #pragma config statements should precede project file includes.// Use project enums instead of #define for ON and OFF.#endif /* XC_HEADER_TEMPLATE_H */ 其他PIC网友优质开箱测评帖: 1、[PIC®/AVR® MCU] 【CuriosityNano测评报告】初识PIC16F15244 用户:21ic蓝V作者jinglixixi 最近,如愿地收到了PIC16F15244Curiosity Nano评估工具包。其实说是工具包会有些误解,它其实是由一块PIC16F15244开发板和2排插针构成。 除去包装后,将开发板与排针连接后,则如图1所示。 图1  PIC16F15244开发板 由于工具包并没有配置相应的USB线,所以在找到一条USB线后便迫不及待连上电脑相看一下上电后的效果,其状态如图2所示。也就是说除了电源指示灯被点亮外,并无太大的变化。 图2  上电效果 但与此同时,在电脑上还有着一定变化的,明显的效果就是在安装驱动后,桌面上出现了一个虚拟的U盘,见图3所示。 图3 虚拟U盘 在打开U盘后,可见到里面存有3个文件,见图4所示。 图4 U盘内容 此时若打开资源管理器,则可看到不仅有虚拟的U盘,还有虚拟的串口,见图5所示。 图5 虚拟串口 观察到这里,似乎能做的也就这些了,那我们就为后续的工作先做些准备把。 1.找到那张器件联络图(原理图),下载为: ww1.microchip.com/downloads/en/DeviceDoc/PIC16F15244_Curiosity_Nano_Schematics.pdf,该原理图给我们的关键内容如图6所示。 由此可知,板载的2个器件与MCU的连接关系为: LED(黄色)  --- RA2(低电平点亮) SW(用户键)--- RC2(按下为低电平) 此外,串口的占用引脚为: TX(发送)  --- RC1 RX(接收)  --- RC0 2. 找到硬件的用户使用指南,其下载网站为: ww1.microchip.com/downloads/en/DeviceDoc/PIC16F15244-Curiosity-Nano-Hardware-User-Guide-DS50003045A.pdf 图6 关键内容 3. 了解PIC16F15244为我们具有哪些特色,其主要内容为: 4. 开发工具的配备,其主要内容为: 随后的工作就是下载软件来构建开发环境了,由于手头的开发环境是基于MPLAB® XIDE 5.30,所以需要重新下载安装MPLAB® X IDE 5.40,因为在MPLAB® XIDE 5.30下是找不到PIC16F15244,这一点似乎不如KEIL,如果能下载个升级包把问题解决了多好! 2、[PIC®/AVR® MCU] 【CuriosityNano测评报告】+初次上手PIC单片机之PWM呼吸灯 用户:南来之风 非常感谢论坛提供了一次难得的初次体验PIC单片机的机会。官网的资料是非常详细的,对于这款Curiosity Nano,建议从Github上开始学起来。 github.com/microchip-pic-avr-examples/pic16f15244-pwm-led-blink 首先是环境的搭建: 正确安装好驱动后,在端口中应该可以看到“Curiosity Virtual COM Port” 开发环境安装好后,首先打开MPLAB XIDE5.40,软件是自动识别我们这款板子,而且硬件资料,软件demo一应俱全,非常的便利! 转到Git上,试着运行一个pwm-led-blink-master的项目,下载后先build一个工程。 成功后,把程序下载到板子上。 与此同时,把GND和RA2引脚引出,连接到一个简易示波器的输入端,可以看到PWM的方波驱动LED闪烁,在简易示波器上显示出响应的波形。 在例程的基础上,增加了几个不同占空比的值,目前占空比可以选择0,12,25,37,50,62,75,88,100。代码比较糙,但还是贴出来了: uint16_t Array_dutyCycle[] ={0x0000,0x007F,0x00FA,0x177,0x01F4, 0x0271,0x02EE,0x036A,0x03E7};uint16_t i;uint8_t index = 0;int8_t direction = 1;void main(void){ SYSTEM_Initialize(); // Initialize the device INTERRUPT_GlobalInterruptEnable(); // Enable the Global Interrupts INTERRUPT_PeripheralInterruptEnable(); // Enable the Peripheral Interrupts while(1){ if(direction == 1){ if(index != 8) PWM3_LoadDutyValue(Array_dutyCycle[++index]); else{ direction = -1; PWM3_LoadDutyValue(Array_dutyCycle[--index]); } } else{ if(index != 0) PWM3_LoadDutyValue(Array_dutyCycle[--index]); else{ direction = 1; PWM3_LoadDutyValue(Array_dutyCycle[++index]); } } for(i = 5120; i!=0;i--); }} 可以看出PWM的波形占空比变化时候LED0的亮度也随之变化。 3、[PIC®/AVR® MCU] 【CuriosityNano测评报告】+开箱、建立开发平台及LED闪烁 用户:hu9jj 周末收到本次评测的主角PIC18F57Q43核心板,鲜红的外包装依旧那么惹人喜爱: 两个防静电包装袋中分别是排针和PIC18F57Q43核心板: 核心板上的焊盘依旧的交叉错位,稍加用力将排针插入核心板,就可以直接使用,省略焊接步骤。我之前曾打样了几块扩展板,本次依然派上用场: 上电之后,打开MPLAB X IDE,系统自动识别核心板,通过链接就可以下载PIC18F57Q43的相关资料: 电路图、硬件用户手册及数据表下载完之后,照例先升级PACK包: 我懒得选择,依次升级了全部PACK,因此花了一个多小时才完成: 准备工作基本完成之后,开始新建项目: 我安装的是中文版IDE,但不知怎么回事,有时菜单不出现中文,不过这无伤大雅,选择“New Project”就是:   照旧选择标准项目(参见上图),然后进入第二步,选择芯片类别:类别选择正确之后,在设备栏中输入“PIC18F57",然后从下拉列表框中选择对应的核心板型号,当然,您愿意录入完整的核心板型号也行,然后在工具栏中选择您的核心板编号,这样项目便会与核心板挂钩: 下一步便是选择编译器: 新建项目的最后一步是输入项目名称、选择项目文件存放的位置等: 至此,项目新建完毕,下一步就是通过MCC来配置代码,完善必要的代码文件: 可以从Window下拉菜单中点击进入(或退出)代码配置器MCC,也可以直接点击工具栏上的图标进入或退出MCC:点击之后,首先需要确定MCC配置文件存放的位置,我通常按默认的位置,直接点击“保存”按钮: 通过下载的电路图,我们知道LED是接在RF3引脚、KEY是接在RB4引脚,因此在引脚图表中将RF3设置成output,将RB4设置成input,为了容易理解,点击右上部分的Pin Module选项,然后在对应引脚的名称设置成KEY和LED: 配置完成后,不要忘记点击右上部的"Generate"选项来生成代码:退出MCC之后,打开main.c文件,添加一个计时用的全局变量ms,并在主循环中写入下列代码,用于计时和控制LED引脚电平翻转: 编译并下载程序到核心板上: 稍等片刻,程序烧录完毕,黄色LED灯便闪烁起来了,开发平台也顺利建立了。这是测试的动画: END 资源:21ic论坛,整理:付斌 版权归原作者所有,如有侵权,请联系删除。 ▍ 推荐阅读 你怎样选择开源免费RTOS? GD32也开始假货翻新泛滥了 工程师姓什么很重要!别再叫我“X工”!!! →点关注,不迷路← 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    时间:2021-04-04 关键词: PIC 单片机

  • 原来单片机竟然可以这样测量速度与行驶路程,高中生都会

    网站:bbs.21ic.com 这是我总结的论文中的一部分。由于很多符号没法正常显示,我截图帖出来了。 我们知道惯性传感器在导航系统上应用非常广泛,在导航定位上是一个关键元件,可以配合GPS信号实现高精度的定位,在GPS信号丢失后可以利用之前的位置信息作为初始数据,结合惯性传感器测量的数据准确的衔接上,并继续定位跟踪。然而,在普通公路上我们只能依靠精度有限的卫星定位信号来处理这些。同样的技术用到未来高速公路上,那就不一样,这些传感器获取的数据将会帮助车辆生产厂家和公路管理部门,用以提升自己的产品和服务能力。 另外我们分析精度问题,假设车辆行进的速度为10km/h,如果采样周期为1ms,则该采样周期内车辆前进了2.8mm,这个距离是非常小的。那么以速度100km/h计算就是28mm,这相对于车速来讲也是非常短的,当车速在200km/h的时候,每个采样周期也仅仅前进了5.6cm。 因此在计算机的时间尺度上,车辆完全可以在单位采样周期内近视成加速度不变的匀加速运动。 在物理学的混沌理论和非线性动力学中,急动度也有一定应用。 本文系21ic论坛网友gaoyang9992006原创。 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    时间:2021-04-04 关键词: GPS 测量测试 单片机

  • 单片机数据通信怎么学?这个工具要用好:串口通信

    单片机数据通信怎么学?这个工具要用好:串口通信

    刚开始学单片机的你,是不是会因用程序把LED点亮而感到高兴,会因用程序把数码管点亮而感到高兴。这是好事,这也是想继续学习下去的动力。 但是到了与数据相关的实验时,却感觉很难有所进步。有时候,把驱动写好了,下载到单片机后,一点反应都没有,可是又不知道问题出在哪里,数据通信又不像LED那样可以用万用表测出到底有没有电。 这是学习单片机和STM32的一道坎。又或者说,这是一条河,阻拦着你的去路的河,有一条河你会怎么办?过去的方法很多,但是笔者觉得较快的方法就是借助原有工具渡过去。过去之后你会发现河的那边是一个不一样的世界。 那这个原有的工具是什么呢?那就是"串口通信"。 串口通信介绍 串口通信是指外设和计算机间,通过数据信号线 、地线、控制线等,按位进行传输数据的一种通讯方式......这种太过理论了,看似懂了,但又不懂。还是用我笔者自己的话来说吧。 串口通信就是可以把程序在单片机或者STM32芯片中运行的结果发送到电脑的一种通信方式。如何使用串口通讯,你需要知道的几个重要的知识点:1)串口通信使用到的GPIO引脚配置 GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能USART1,GPIOA时钟 //USART1_TX GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9//USART1_RX GPIOA.10初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 串口使用的的GPIO口是PA9和PA10,所以只需配置这两个IO口的输入输出模式就可以了。 2)串口主要参数设置(直接看程序) USART_InitTypeDef USART_InitStructure;//USART 初始化设置USART_InitStructure.USART_BaudRate = bound;//串口波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b;//数据格式,8位USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式USART_Init(USART1, &USART_InitStructure); //初始化串口1USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断 串口参数配置无法就是配置串口的波特率、数据格式、停止位、奇偶校验、硬件流、收发模式。除了波特率需要改变其他的参数都不需要管。直接复制拿来用。 3)串口中断配置 NVIC_InitTypeDef NVIC_InitStructure;//Usart1 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能NVIC_Init(&NVIC_InitStructure);//根据指定的参数初始化VIC寄存器 4)串口使能 USART_Cmd(USART1, ENABLE); //使能串口1 5)编写串口中断处理函数 END

    时间:2021-03-31 关键词: 数据通信 串口通信 单片机

  • 使用STM32、WIFI模组,亲手打造一款智能宠物喂食器

    1 前言 我从小就喜欢小动物,工作了之后养了一只可爱的小泰迪,取名叫COCO。白天,我上班把COCO独自锁在家中;晚上回家,COCO热情相迎,这种感觉很治愈。 有时候出短差,就把COCO自己锁在家中,也正是这个原因,很想自己做一个宠物喂食器,可以实现远程喂食和定时喂食的功能,无奈,不懂Android/IOS编程无法实现云端和客户端的功能,一直在搁浅。 幸好,最近我参与了一个调查问卷,以开发者的身份参与了涂鸦智能的开源项目,获得的了涂鸦智能所提供的开发套件,今天就和大家分享一下这个开源项目,并介绍一下参与开发的流程,有兴趣或者有时间想玩的朋友们可以扫描以下二维码报名参与,本次活动免费为你准备了模组以及元器件,还有直播培训教程,手把手教你开发一款宠物喂食器,还是相当不错的。 依托涂鸦的智能模组,可以“轻代码”编程,轻松实现客户端的配置,打通了云端、MCU端的“轻代码”甚至“零代码”开发。所用到的硬件资源和平台如下: STM32F103C8T6最小系统板; 涂鸦wifi语音模组VWXR2; 涂鸦H-Bridge电机驱动板; 5V直流减速电机; 涂鸦IOT平台; keil5编程环境; 所采用的模组为涂鸦VWXR2,可以轻松实现配网,还具有语音功能。该wifi语音模组的链接如下: https://developer.tuya.com/cn/docs/iot/device-development/module/wifi-module/vwxr-series-module/vwxr2?id=K9eipxhzap92z 2 模组配网 对于WiFi模组而言,最重要的就是配网,所谓配网,就是让模组接入路由器,实现云端和模组的数据交互。通过USB/TTL将电脑和wifi模组连接。模组上用到的串口为TXD1和RXD1,需要和USB/TTL的串口交叉连接。 在配网的时候接上喇叭,可以发出相应的语音提示,非常的方便。 云串口助手的配网流程如链接所示: https://developer.tuya.com/cn/docs/iot/device-development/embedded-software-development/mcu-development-access/access-mode-simmulator/module-debugging-assistant-instruction?id=K9hs0cj3lf0au 涂鸦提供了云串口调试助手,技能实现云端的模拟,又能实现MCU的模拟。配网时,选择MCU模拟,联网协议选择Wi-Fi通用协议。 功能点调试文件,需要选择IOT平台所生产的json文件,这一点在后面的IOT平台会说到。json文件加载成功后,会显示16为的PID字符串,点击“开始调试”后会交互数据流,数据流都在左侧,这些数据流可以帮助开发者很快的了解“串口通讯协议”。在界面下方的操作-基础功能中,点击重置,会开始配网流程。这时候,打开手机“涂鸦智能”APP。 注意,目前只支持2.4G的路由器,如果路由器是5G的,需要根据提示设置一下。 3 IOT平台搭建 涂鸦智能可以做到“轻代码”设置“零代码”开发,因为在涂鸦的IOT平台上都给开发者配置好了,平台可以根据所用的IOT模组生成代码,开发者只需要移植代码就可以了。下面介绍详细的开发步骤。 首先注册IOT平台,之后选择右上角的“IOT平台”,如下图所示。 选择“创建产品”: 选择“小家电”,拉到底部选择“宠物喂食器”: 填写产品名称、产品型号等信息,通讯协议选择WI-Fi 之后,可以根据平台提供的功能裁剪自己所需要的功能,如喂食计划、开关、小夜灯等。 之后配置APP的界面,IOT平台提供了很多公版面板可供用户选择 之后,可以打开“涂鸦智能”APP扫面二维码,就可以在手机端生成界面。 手机端生成的界面如下图所示。 4 硬件配置&下载固件 在“硬件开发”界面,选择硬件,这里的硬件指的就是所使用的IOT模组,我所选用的模组是VWXR2模组,带语音功能。 硬件选择好之后,平台会自动生成基于该硬件的资料文档和SDK代码,需要开发者下载 下载开发资料,里面包含需要移植的mcu_sdk代码、json配置文件、串口通讯协议文件、云串口调试助手等文件。 其中json文件,就是《2-模组配网》中云串口助手索要加载的“功能点调试文件”。 5 mcu_sdk移植 在移植之前,我们需要一套代码,该代码能跑通串口程序。我上手有STM8和STM32的最小系统板,刚开始用STM8移植的,移植完后代码的大小为9K,而我的STM8只有8K的空间。所以,最后换成了STM32,开发环境为Keil5。 首先,把mcu_sdk文件复制到keil的工程目录下; 在左侧新建MCU_SDK工作组,并把mcu_sdk中的mcu_api.c、protocol.c以及system.c加载进去; 在keil中,右键属性或者点击菜单栏的魔法棒,在C/C++下添加mcu_sdk的路径。 之后按照开发者文档中MCU_SDK移植的操作流程进行移植,链接如下: https://developer.tuya.com/cn/docs/iot/device-development/embedded-software-development/mcu-development-access/wifi-mcu-sdk-solution/overview-of-migrating-tuyas-mcu-sdk?id=K9hhi0xr5vll9 通过研究protocol.c中的代码可以知道,IOT平台把功能都做成了单独的函数,函数的命名方式为: dp_download_xxx_handle(),xxx是不同的功能,如小夜灯为light,开关为switch。只需要在相应的函数下面添加操作就可以了,比如我的STM32最小系统板上有一个LED指示灯。我写的LED点亮函数为LED_Turn_ON(),LED熄灭函数为LED_Turn_OFF(),只需要把语句填上即可。 这时候,通过涂鸦智能APP就可以控制板子上灯的亮灭状态。 要实现宠物喂食器,还需要一个减速电机,减速电机还在购买中,没有到货。到货后继续。 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    时间:2021-03-31 关键词: AI 智能宠物喂食器 单片机

  • 爱普特,逆境涅槃的国产“芯”力量

    爱普特,逆境涅槃的国产“芯”力量

    2021年初,美国得州遭受暴风雪袭击大面积停电的新闻再次将芯片这个话题冲上热搜,不过这一次的关键词变成了“全球芯片短缺”。回顾过去三年来,科技战的步步紧逼,中国面临芯片荒的危机一直未曾解除,国产芯片行业的发展也随着技术封锁的缩紧,走得颇为艰难。 如今,因疫情带来的黑天鹅影响,全球供应链全线受到冲击,芯片告急的风险蔓延全球。而反观国内芯片产业,在持续加剧的封锁寒冬中,却凭借着顽强的自力更生,迎来升温的转机。 纯国产化的“芯”生力量 爱普特作为一家全国产芯片企业,自成立之初,一直坚持纯国产化发展理念。创始团队极具前瞻性的战略部署,稳步推进了公司在华产业链的阶段性布局。尽管细数8年的发展历程,纯国产化道路走得并不轻松,但是秉承着“自主可控,改变未来”的初心,即便是在遭遇行业封锁的危机之时,爱普特依然专注于技术创新,致力打造国产芯片生态圈,在全球普遍缺“芯”的逆境中焕发勃勃生机。 诚“芯”之道,方得始终 “全国产”的底气来自何处?悉数爱普特的设计团队,我们会发现,这是一支强有力的“国产生力军”。核心研发成员中大部分来自原三星半导体MCU的设计团队,曾参与并主导过数十款8Bit MCU、 32位MCU甚至是AP级MCU、车规级MCU的研发。整个团队从管理层至核心研发人员,都有着近二十年的半导体从业经验,不论是技术攻关还是市场把控,无需借助任何海外团队支持,爱普特都能做到游刃有余,把MCU做到了真正的“全国产”。 强大的团队背书,为爱普特赢得了高效的发展空间。依据自身丰富的设计经验和技术积累,团队已自研出拥有上百个IP的IP库。该IP库经过了亿级的批量验证,确保产品的架构稳定合理,提高性能的同时也缩小了IP面积,可实现高度客制化。如此爱普特团队不仅能够迅速捕获客户需求,提供全面的技术方案与支持,还能减少试错成本,缩短产出周期。与此同时,完全自主的知识产权,保障了客户的专利权益,规避了国外的专利限制所带来的风险。 爱普特团队通过极致的可靠性设计,坚持做到诚“芯”待人,一切以客户需求为己任,严格要求,细致把控,赢得了客户的认可。爱普特的产品已经得到美的、松下、小米、惠而浦等知名家电头部厂商及消费类电子客户的高度认同。2018年,爱普特与阿里巴巴携手,成为阿里巴巴平头哥在通用型MCU领域唯一的深度战略合作伙伴。 在业内发展举步维艰的局面下,爱普特抢眼的表现也引起各方关注,于2020年获得A轮上亿元的融资,整装待发,步入新的战略发展阶段。 国产匠“芯”,后来居上 自从业届一片“卡脖子”之声响起,全国人民似乎对于国产芯片的认知都处于焦虑的心态之中。而从爱普特身上,我们能够看到国产芯崛起的希望。纯国产化和全国产化,并非一个噱头。 多年来,爱普特专注于高性能32位MCU研发,已拥有完全自主知识产权的32Bit MCU系列产品。 区别于业内大部分芯片设计采用的ARM架构,爱普特则是于创立之初率先选用了RISC-V这一架构,并且已实现了基于RISC-V架构研发出来的芯片的千万颗级的量产。 在生产方面,爱普特合作方是国内知名晶圆厂,全产品线采用55nm工艺,力求在单位面积上加载更丰富的资源。在相同工作频率下,有效降低运行功耗,大幅提升产品性价比。 括而言之,爱普特全国产的设计生产,非但没有在严峻的行业形势下弱势,反而为国产芯片赢得了市场的认可和尊重,向世界证明了中国也能产出高品质的匠“芯”之作。 精“芯”部署,赢在未来 依托强大的管理和研发团队,死磕技术创新的匠心精神,爱普特一贯以着眼未来,提前部署的战略风格来争取发展先机。 坚持纯国产化道路,潜心自身技术创新,使得爱普特在面临技术封锁的危机时刻,成功摆脱对国外芯片产业的依赖。卓越的自主知识产权产品带来的巨大成本优势,为爱普特提供了强大的市场竞争力。自主研发的32位MCU仅售接近8位单片机的价格,集成了更丰富的资源外设,带来更高效的数据处理能力。值得一提的是,爱普特同时拥有多样化的封装选择,并基于自主产权研制的CDK自主编译器,打造了一系列产品工程模板,可支持客户自定义,为客户高效开发方案提供强有力的平台支撑。 回望过去两年全球局势与疫情的双重压力下,多数行业都因供应链断裂而受到巨大冲击。得益于中国强有力的抗疫措施,全国的产线迅速复苏,快速重新投入研发生产,也让人们感受到国产化的力量。爱普特从方案设计到生产,全线供给线均在国内完成,成功规避了大环境带来的风险,以安全稳定的供应链再次证明了其部署国产化道路的优越性。 逆风向阳,重获“芯”生 目前,美国及其盟友正在积极筹建“无中国”技术供应链,中国各个行业形势似乎更加严峻,但是却无法压制中国企业前进的决心。越封锁,越突破,纯国产化进程的不断加速,将带领整个行业涅槃“芯”生。 爱普特作为MCU行业的佼佼者,在逆境中上下求索,为单片机产业与市场源源不断输送新鲜的血液,带来延绵不绝的活力,凭着千磨万击还坚劲的意志,摆脱西方制裁的桎梏,助力国产单片机走出一条逆风向阳的翻盘之路。

    时间:2021-03-26 关键词: 半导体 MCU 爱普特 单片机 芯片

  • 为什么单片机不能直接驱动继电器和电磁阀?

    时间:2021-03-25 关键词: 继电器 电磁阀 单片机

  • 单片机到底是个什么东西?

    1 从电路到集成电路 1.1 电路发展变化的趋势 (1)功率。电子设备越来越省电,待机时间越来越长,工作电压越来越低。 (2)体积。体积越来越小。 (3)功能。功能越来越强大。 1.2 微器件的出现 (1)电路的核心:开关控制、倍率控制。 (2)电子管、晶体管等。 1.3 集成电路的出现 (1)IC(integrated circuit,集成电路),就是使用微器件为积木,去搭建具备一定功能的一个电路板。 (2)以前没有微器件的时候,必须很大一块电路板才能实现一个电路功能(譬如一个加法器,完成加法运算)。然后有了微器件之后,这个电路板的体积变小了,越来越小,最后小到mm级别甚至更小,我们就把这个电路做在一起,用塑料外壳封装起来就形成了大家看到的IC芯片。 (3)芯片(IC、集成电路)其实就是:里面馅是电路,外面的壳就是绝缘体壳,里面的电路通过外壳上引出来的一些引脚(金属材料的)来与IC外部接轨。 (4)IC有多少个引脚,每一个引脚的作用是干嘛的,是IC设计制造的时候就已经决定的,我们拿到IC使用时要去读IC的数据手册来知道这个引脚怎么用。 2 计算机的核心设备CPU CPU就是一块超大规模集成电路,CPU的本质就是电路。 2.1 CPU(Central Processing Unit,中央处理器) (1)CPU = 运算器 + 控制器 (2)CPU = ALU + cache + Bus (3)CPU = 汇编指令 + 寄存器 2.2 CPU的工作原理 (1)CPU通过总线从存储器取出指令到内部,然后译码,然后执行。 (2)一条指令包括:指令码+数据。 (3)执行指令反应为一个控制操作或者一个数学运算。 (4)给单片机编程其实就是给CPU写指令序列。 3 给单片机下个定义 3.1 计算机系统三大组成部分:CPU、内部存储器、IO (1)单片机属于计算机的一种。 (2)IO就是input/output,也就是输入输出。譬如键盘、鼠标、触摸屏等就是输入设备,而LCD显示器、声卡等就是输出设备。 3.2 单片机的结构框图分析 (1)我们来看单片机这个计算机系统的结构框图。 (2)框图中的方块是组成部件、箭头表示总线Bus。 (3)CPU处于单片机系统的核心位置,别的模块都通过总线和CPU进行关联。别的模块之间一般没有总线直接相连,有时候2个互相有关系的模块也会有总线直接相连。 (4)IO其实就是芯片上的引脚,不同的单片机型号有不同的IO数量和定义。 3.3 如何定义单片机 (1)单片机就是一台微型计算机。 (2)台式电脑或者笔记本电脑(这种计算机叫PC)也是一种计算机系统,这种计算机系统由很多个零部件组成。这些零部件由不同的厂商生产,可以去组合组装成一台电脑。 (3)单片机这台计算机的所有零件全部做在了一个IC内部,并且出厂前被塑料壳封装起来了。传统计算机中的主要部件单片机都有,都集成到内部去了。 (4)MCU的概念(参考百度百科词条:MCU),所以说大家看到:单片机、单片微型计算机、MCU、微控制器、微控制单元等,都是一个意思。 微控制单元(Microcontroller Unit;MCU) ,又称单片微型计算机(Single Chip Microcomputer )或者单片机,是把中央处理器(Central Process Unit;CPU)的频率与规格做适当缩减,并将内存(memory)、计数器(Timer)、USB、A/D转换、UART、PLC、DMA等周边接口,甚至LCD驱动电路都整合在单一芯片上,形成芯片级的计算机,为不同的应用场合做不同组合控制。诸如手机、PC外围、遥控器,至汽车电子、工业上的步进马达、机器手臂的控制等,都可见到MCU的身影 4 ROM与RAM 4.1 计算机中的2种存储器 (1)计算机要存储器干嘛 (2)内存:内存和CPU接轨比较紧密,内存可以被CPU直接访问,内存可以按照字节为单位来随机访问、程序运行时离不开内存、程序中的变量都是定义在内存中的。内存受限于物理技术和成本,容量比较小而贵;内存速度比外存快很多,CPU的速度比内存的速度快好多。 (3)外存:外存和CPU之间比较远,外存不可以被CPU直接访问,外存一般以块为单位来访问,不能以字节为单位随机访问。外存容量大而便宜,外存速度比内存慢好多。 (4)综合来说,计算机系统是这样工作的:文件和数据不用的时候就放在外存中,要用的时候从外存读取到内存,然后CPU再从内存中读取数据来直接使用。 4.2 ROM (1)read only memory,只读存储器,意思是只能读不能写。实际上世界上根本不存在真正的只能读不能写的器件,我们ROM这里的只读意思是:程序运行时只能通过程序自己本身的操作去读而不能写。 (2)常见的ROM:单片机中用来存储用户烧录的程序的器件就是ROM,烧录的过程其实就是在写ROM,但是程序运行时是不能修改ROM内容的。烧录程序一般要通过烧录器来完成。 (3)storage,存储器,含义有点像仓库存储东西。ROM就有点类似于仓库,用来存储程序代码。 (4)ROM有点像外存的概念,但是并不完全相等。主要是因为计算机系统有不同的设计方法,譬如PC机和单片机的设计就不相同。PC机中有外存没有ROM,单片机中有ROM没有外存。单片机中程序平时是存储在ROM中,运行时由ROM直接供给CPU。 4.3 RAM (1)random access memory,随机访问存储器。 (2)常见的RAM:从物理上来讲,主要分为SRAM和DRAM,单片机中一般使用的都是SRAM,嵌入式SoC中和PC机中用的都是DRAM。 (3)memory,存储器,专指的是计算机的内存。 4.4 单片机中的ROM和RAM (1)单片机中的ROM一般是Flash(闪存),有些地方会看到叫flash memory;单片机中的RAM一般都是SRAM;这两个共同构成单片机中的存储体系。 (2)ROM和RAM的协同工作方式是:ROM用来存储用户写好编译好的程序,运行时CPU直接从ROM中读取一条一条的指令来运行,指令运行过程中产生的临时数据放在RAM中。所以基本可以理解为:ROM是单片机用来放程序的,RAM是用来放数据的。 5 单片机的工作原理 5.1 主要器件负责干嘛?CPU、存储器、IO 5.2 统一的时钟节拍 (1)这里有一个概念叫:同步。同步就是好多个独立的部分按照同一个节奏步调来动,以此来实现一个配合。 (2)和同步相对的一个概念叫异步,异步就是各自干各自的。 (3)单片机的各个模块之间是同步工作的,CPU和存储器和IO和单片机中其他东西这些模块之间通过一个统一的节拍来同步工作,这个统一节拍就是单片机的时钟。 (4)这个时钟节拍对单片机很重要,单片机内部在一个时钟节拍中只能做一件事情。所以单片机要发生一些变化或者做一些事情,最小的时间单位就是1个时钟节拍。单片机的时间单位都是时钟节拍的整数倍。 (5)单片机中的CPU、存储器、IO等都是以时钟节拍为动作节拍的,所以单片机是一个同步系统。 (6)时钟周期的长度(时钟节拍的快慢)影响了单片机的速度,所以这个时钟就叫做单片机的主频。主频越高性能越高,一般PC的主频都是2G多3G多,51单片机的主频MHz级别。一般手机CPU的主频也在1G-2G左右。一般高级单片机如STM32的主频在百MHz级别。 6 外设与内部外设 6.1 什么是外设 (1)外设英文叫 peripheral ,全称为外部设备。属于单片机中的模块。 (2)单片机中除了三大部件(CPU、IO、存储器)外,还有一些别的东西,譬如串口控制器、譬如I2C控制器等····这些东西就叫外设。 (3)早期单片机功能很弱小,不具备很多功能(譬如中断功能、譬如串口通信功能),那我们用单片机做产品,只能外部扩展一些专用芯片(中断控制有中断控制器芯片,串口通信我们有串口通信芯片)来和单片机结合(做到一块电路板上用导线连接)起来工作。这种产品设计中核心部分就是单片机,外部配合的这些专用芯片就是外部设备,简称外设。 (4)后来随着半导体工业发展进化,集成电路的集成能力变强大了,我们干脆就把一些常用的外设直接集成到单片机里边去了。所以单片机里边就有了一些原来被称为外设的东西,但是叫法名称还是沿用了开始的名称。 6.2 什么叫内部外设 (1)我为了区分外设,将集成到单片机里边的外设叫做内部外设。 (2)还有外部外设,就是至今仍然没有集成到单片机内部,还在外部的那些外设。 7 单片机与电路板 7.1 什么是电路板(PCB printed circuit board,印刷电路板) (1)外观:PCB板 = 基板(绝缘)+电路。 (2)作用:PCB的作用就是骨架和连接。最终目的就是把所有的元件按照正确的电路图连接起来形成一个完整的可以工作的电路。 (3)构成和材质,常用的基板材质都是FR4(玻璃纤维),PCB板是由多层构成的(单面板、双面板、四层板、8层板、12层、16层、24层)。 (4)印刷电路其实就是在不导电的基板表面按照电路构成来印刷一层导电物质形成电路。最后形成的就是一个里面的芯是不导电的FR4,外面有一层构成了电路的铜(标准术语叫覆铜),为了避免铜氧化或者与外部导电外部还有一层油墨,刷油墨时要露出来焊接点(焊接点一般有2种:一种是插针式、一种是贴片式),焊接点上本来就是铜,但是我们为了方便焊接一般会做镀锡。 (5)PCB板其实就是硬件电路(元件和电路设计)的载体。 7.2 什么是芯片 (1)芯片就是:芯是半导体技术形成的电路,外面的壳是塑料绝缘壳,里面电路通过芯片引脚接出来用于连接外部电路。 7.3 芯片方式和电路板方式的关系 (1)相同点。芯片其实就是一个微型的电路板。这两个东西本身一模一样,早期只有电路板没有芯片,后来半导体工艺发展后有了微型器件,所以人把一些电路利用半导体工艺直接作死到一个芯片中去形成了IC。 (2)不同点。电路板体积较大,功率大;芯片体积小,功率小。 (3)我们做一个电子产品究竟应该如何去总体设计?现代的设计方案都是芯片+电路板。能做到芯片里面的都做进去(趋势是越来越进去的多),实在不能做成芯片的就只好放在外面。原来的产品,譬如老式大屁股电视机主板非常大,而新式的智能电视机主板就是一个大芯片+很少的外围设备。 (4)单片机开发板其实就是PCB板主板+单片机芯片+其他芯片+其他外围电路元器件总体构成的。这就是普遍的电子产品的结构。 8 软件与硬件的区别和联系 8.1 从产品角度 (1)硬件是?产品的载体和身体。 (2)软件是?产品的思维和灵魂、精神。 8.2 软硬结合 (1)物联网不能靠纯软件打造。 (2)纯硬件产品大部分都低端。 9 硬件工程师主要工作职责 电路图的分析和设计 原件的选择和参数确定 PCB的设计和样板焊接、调试 生产跟踪和问题解决 10 软件工程师主要工作职责 初级软件工程师:辅助测试、写代码、维护 中级软件工程师:独立工作、对产品负责、解bug 高级软件工程师:需求分析、框架设计、团队管理 软件工程师成长路线:学到基础(知识+能力)->找到工作->学习和锻炼->中级->高级/转方向 11 datasheet的重要性 11.1 什么是datasheet (1)datasheet就是数据手册,其实就是芯片的文档。 (2)数据手册中描述的都是这个芯片/器件的物理参数、电学参数、时序图、编程需要的信息、别的信息。总的来说这个芯片的所有有用的信息都在数据手册中,使用这颗芯片过程中的任何疑问都可以去datasheet中查询。 (3)我们学习单片机软件开发过程中,要不断去查询各种芯片的数据手册以获取一些有效信息来指导我们。 11.2 datasheet谁写的? (1)datasheet是由芯片厂商提供的。datasheet其实就是芯片的产品说明书。 11.3 datasheet从哪里来? (1)最官方最权威的途径就是到芯片厂商的官方网站去下载。 (2)开发板附带的光盘资料中一般也会有。 (3)将芯片型号信息敲到百度去搜索其数据手册。 11.4 datasheet应该怎么使用? (1)数据手册不是书,更不是教材,数据手册更像是一本字典。所以不是从第一页看到最后一页,更不用试图是记住。 (2)数据手册一定要先浏览一遍。尤其对于刚开始学习的人。浏览的目的是大概知道什么东西在哪里(将来用到时大概知道到哪里去找),里面一些概念基本理解,但是并不是为了记住。 (3)数据手册的正确用法就是:前面先简单看一遍(其中的前面一些可以认真看,后面的了解即可),用到某个具体知识时再根据前面浏览时的了解去具体查找数据手册中相关部分,这时候再去认真看。 12 原理图和PCB图 12.1 原理图 (1)原理图叫电路原理设计图,就是用符号来绘制出的电路连接的逻辑图。我们平时讲的电路图其实就是原理图。原理图不是实物。 (2)原理图由:线条、方框、圆圈、数字、字母等组成。看懂这些符号所对应的电路实物,就能看懂原理图。 (3)原理图中每一个符号表达一种含义,常见的有: 直线:表示导线,是用来连接元件构成电路的。 方框:表示器件,如IC、插座 常见符号:如电阻、电容、三极管等··· 特殊符号:不常见器件 (4)原理图中的每一个器件都有一个编号,如IC都用Un(U1、U2等),电容都用Cn(C1、C2)····这个编号在原理图中是唯一的,这个编号用来表示/记录这个元器件。 (5)原理图中芯片类型的器件还会有一个名字,名字一般是器件的型号。 (6)原理图中大多数器件还有一个参数值,譬如电容的容量、电阻的阻值等。 (7)有些器件(IC、插座)有引脚,引脚编号用数字表示。 (8)原理图中有个网络的概念,原理图上2个编号一样的节点其实在逻辑上是连在一起的。网络的发明纯粹是为了方便画图,让图不会导线连接的跟蜘蛛网一样。分析原理图时一定要注意网络,否则看到的可能就是一半的原理图。 12.2 PCB图 (1)硬件工程师在设计产品硬件时的步骤是:先有原理图,然后用原理图画出PCB图。 (2)PCB图是原理图和实际器件结合起来后,生成的PCB板的结构图纸,PCB图的作用就是拿给做PCB板的厂商去印刷电路板。 (3)对于软件工程师来说,PCB图完全不用去关注,我们只关注原理图。 12.3 BOM表 (1)BOM就是bills of meterials,就是物料表,物料表是整个电路中用到的所有物料的一张清单。 (2)BOM表是研发部门(硬件工程师)提供,一般是给生产部门来备料、记录用的。 (3)BOM中每个物料的记录和对应就靠物料编号。

    时间:2021-03-24 关键词: 软件 硬件 单片机

  • 深度:单片机到底是如何软硬件结合的

    我们通过IO和串口的软件开发,已经体验了嵌入式软件开发。不知道大家有没有疑惑,为什么软件能控制硬件?反正当年我学习51的时候,有这个疑惑。今天我们就暂停软件开发,分析单片机到底是如何软硬件结合的。并通过一个基本的程序,分析单片机程序的编译,运行。 软硬件结合 初学者,通常有一个困惑,就是为什么软件能控制硬件?就像当年的51,为什么只要写P1=0X55,就可以在IO口输出高低电平?要理清这个问题,先要认识一个概念:地址空间。 寻址空间 什么是地址空间呢?所谓的地址空间,就是PC指针的寻址范围,因此也叫寻址空间。 大家应该都知道,我们的电脑有32位系统和64位系统之分,为什么呢?因为32位系统,PC指针就是一个32位的二进制数,也就是0xffffffff,范围只有4G寻址空间。 现在内存越来越大,4G根本不够,所以需要扩展,为了能访问超出4G范围的内存,就有了64位系统。STM32是多少位的?是32位的,因此PC指针也是32位,寻址空间也就是4G。 我们来看看STM32的寻址空间是怎么样的。在数据手册《STM32F407_数据手册.pdf》中有一个图,这个图,就是STM32的寻址空间分配。所有的芯片,都会有这个图,名字基本上都是叫Memory map,用一个新芯片,就先看这个图。 最左边,8个block,每个block 512M,总共就是4G,也就是芯片的寻址空间。 block 0 里面有一段叫做FLASH,也就是内部FLASH,我们的程序就是下载到这个地方,起始地址是0X800 0000,大家注意,这个只有1M空间。现在STM32已经有2M flash的芯片了,超出1M的FLASH放在哪里呢?请自行查看对应的芯片手册。 3 在block 1 内,有两段SRAM,总共128K,这个空间,也就是我们前面说的内存,存放程序使用的变量。如果需要,也可以把程序放到SRAM中运行。407不是有196K吗? 其实407有196K内存,但是有64k并不是普通的SRAM,而是放在block 0 内的CCM。这两段区域不连续,而且,CCM只能内核使用,外设不能使用,例如DMA就不能用CCM内存,否则就死机。 block 2,是Peripherals,也就是外设空间。我们看右边,主要就是APB1/APB2、AHB1/AHB2,什么东西呢?回头再说。 block 3、block4、block5,是FSMC的空间,FSMC可以外扩SRAM,NAND FALSH,LCD等外设。 好的,我们分析了寻址空间,我们回过头看看,软件是如何控制硬件的。在IO口输出的例程中,我们配置IO口是调用库函数,我们看看库函数是怎么做的。 例如: GPIO_SetBits(GPIOG, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2| GPIO_Pin_3); 这个函数其实就是对一个变量赋值,对GPIOx这个结构体的成员BSRRL赋值。 void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {  /* Check the parameters */  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));  assert_param(IS_GPIO_PIN(GPIO_Pin));  GPIOx->BSRRL = GPIO_Pin; } assert_param:这个是断言,用于判断输入参数是否符合要求GPIOx是一个输入参数,是一个GPIO_TypeDef结构体指针,所以,要用->获取其成员 GPIOx是我们传入的参数GPIOG,具体是啥?在stm32f4xx.h中有定义。 #define GPIOG               ((GPIO_TypeDef *) GPIOG_BASE) GPIOG_BASE同样在文件中有定义,如下: #define GPIOG_BASE           (AHB1PERIPH_BASE + 0x1800) AHB1PERIPH_BASE,AHB1地址,有点眉目了吧?在进一步看看 /*!< Peripheral memory map */ #define APB1PERIPH_BASE       PERIPH_BASE #define APB2PERIPH_BASE       (PERIPH_BASE + 0x00010000) #define AHB1PERIPH_BASE       (PERIPH_BASE + 0x00020000) #define AHB2PERIPH_BASE       (PERIPH_BASE + 0x10000000) 再找找PERIPH_BASE的定义 #define PERIPH_BASE           ((uint32_t)0x40000000) 到这里,我们可以看出,操作IO口G,其实就是操作0X40000000+0X1800这个地址上的一个结构体里面的成员。说白了,就是操作了这个地方的寄存器。实质跟我们操作普通变量一样,就像下面的两句代码,区别就是变量i是SRAM空间地址,0X40000000+0X1800是外设空间地址。 u32 i; i = 0x55aa55aa; 这个外设空间地址的寄存器是IO口硬件的一部分。如下图,左边的输出数据寄存器,就是我们操作的寄存器(内存、变量),它的地址就是0X40000000+0X1800+0x14. 控制其他外设也类似,就是将数据写到外设寄存器上,跟操作内存一样,就可控制外设了。 寄存器,其实应该是内存的统称,外设寄存器应该叫做特殊寄存器。慢慢的,所有人都把外设的叫做寄存器,其他的统称内存或RAM。寄存器为什么能控制硬件外设呢?因为,初略的说,一个寄存器的一个BIT,就是一个开关,开就是1,关就是0。通过这个电子开关去控制电路,从而控制外设硬件。 纯软件-包罗万象的小程序 我们已经完成了串口和IO口的控制,但是我们仅仅知道了怎么用,对其他一无所知。程序怎么跑的?代码到底放在那里?内存又是怎么保存的?下面,我们通过一个简单的程序,学习嵌入式软件的基本要素。 分析启动代码 函数从哪里开始运行? 每个芯片都有复位功能,复位后,芯片的PC指针(一个寄存器,指示程序运行位置,对于多级流水线的芯片,PC可能跟真正执行的指令位置不一致,这里暂且认为一致)会复位到固定值,一般是0x00000000,在STM32中,复位到0X08000004。因此复位后运行的第一条代码就是0X08000004。前面我们不是拷贝了一个启动代码文件到工程吗?startup_stm32f40_41xxx.s,这个汇编文件为什么叫启动代码?因为里面的汇编程序,就是复位之后执行的程序。在文件中,有一段数据表,称为中断向量,里面保存了各个中断的执行地址。复位,也是一个中断。 芯片复位时,芯片从中断表中将Reset_Handler这个值(函数指针)加载到PC指针,芯片就会执行Reset_Handler函数了。(一个函数入口就是一个指针) ; Vector Table Mapped to Address 0 at Reset                 AREA    RESET, DATA, READONLY                 EXPORT  __Vectors                 EXPORT  __Vectors_End                 EXPORT  __Vectors_Size __Vectors       DCD     __initial_sp               ; Top of Stack                 DCD     Reset_Handler              ; Reset Handler                 DCD     NMI_Handler                ; NMI Handler                 DCD     HardFault_Handler          ; Hard Fault Handler                 DCD     MemManage_Handler          ; MPU Fault Handler                 DCD     BusFault_Handler           ; Bus Fault Handler                 DCD     UsageFault_Handler         ; Usage Fault Handler Reset_Handler函数,先执行SystemInit函数,这个函数在标准库内,主要是初始芯片时钟。然后跳到__main执行,__main函数是什么函数? 是我们在main.c中定义的main函数吗?后面我们再说这个问题。 ; Reset handler Reset_Handler    PROC                  EXPORT  Reset_Handler             [WEAK]         IMPORT  SystemInit         IMPORT  __main                  LDR     R0, =SystemInit                  BLX     R0                  LDR     R0, =__main                  BX      R0                  ENDP 芯片是怎么知道开始就执行启动代码的呢?或者说,我们如何把这个启动代码放到复位的位置?这就牵涉到一个一般情况下不关注的文件wujique.sct,这个文件在wujique\prj\Objects目录下,通常把这个文件叫做分散加载文件,编译工具在链接时,根据这个文件放置各个代码段和变量。 在MDK软件Options菜单Linker下有关于这个菜单的设置。 把Use Memory Layout from Target Dialog前面的勾去掉,之前不可设置的框都可以设置了。点击Edit进行编辑。 在代码编辑框出现了分散加载文件内容,当前文件只有基本的内容。 其实这个文件功能很强大,通过修改这个文件可以配置程序的很多功能,例如:1 指定FLASH跟RAM的大小于起始位置,当我们把程序分成BOOT、CORE、APP,甚至进行驱动分离的时候,就可以用上了。2 指定函数与变量的位置,例如把函数加载到RAM中运行。 从这个基本的分散加载文件我们可以看出: 第6行 ER_IROM1 0x08000000 0x00080000定义了ER_IROM1,也就是我们说的内部FLASH,从0x08000000开始,大小0x00080000。 第7行 .o (RESET, +First)从0x08000000开始,先放置一个.o文件, 并且用(RESET, +First)指定RESET块优先放置,RESET块是什么?请查看启动代码,中断向量就是一个AREA,名字叫RESET,属于READONLY。这样编译后,RESET块将放在0x08000000位置,也就是说,中断向量就放在这个地方。DCD是分配空间,4字节,第一个就是__initial_sp,第二个就是Reset_Handler函数指针。也就是说,最后编译后的程序,将Reset_Handler这个函数的指针(地址),放在0x800000+4的地方。所以芯片在复位的时候,就能找到复位函数Reset_Handler。 第8行 *(InRoot$$Sections)什么鬼?GOOGLE啊!回头再说。 第9行 .ANY (+RO)意思就是其他的所有RO,顺序往后放。就是说,其他代码,跟着启动代码后面。 第11行 RW_IRAM1 0x20000000 0x00020000定义了RAM大小。 第12行 .ANY (+RW +ZI)所有的RW ZI,全部放到RAM里面。RW,ZI,也就是变量,这一行指定了变量保存到什么地址。 分析用户代码 到此,基本启动过程已经分析完。下一步开始分析用户代码,就从main函数开始。1 程序跳转到main函数后:RCC_GetClocksFreq获取RCC时钟频率;SysTick_Config配置SysTick,在这里打开了SysTick中断,10毫秒一次。 Delay(5);延时50毫秒。 int main(void) {   GPIO_InitTypeDef GPIO_InitStructure; /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup files before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* SysTick end of count event each 10ms */ RCC_GetClocksFreq(&RCC_Clocks);   SysTick_Config(RCC_Clocks.HCLK_Frequency / 100); /* Add your application code here */ /* Insert 50 ms delay */ Delay(5); 2 初始化IO就不说了,进入while(1),也就是一个死循环,嵌入式程序,都是一个死循环,否则就跑飞了。 /*初始化LED IO口*/ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2| GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOG, &GPIO_InitStructure); /* Infinite loop */ mcu_uart_open(3); while (1) {   GPIO_ResetBits(GPIOG, GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);   Delay(100);   GPIO_SetBits(GPIOG, GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);   Delay(100);   mcu_uart_test();   TestFun(TestTmp2); } 3 在while(1)中调用TestFun函数,这个函数使用两个全局变量,两个局部变量。 /* Private functions ---------------------------------------------------------*/ u32 TestTmp1 = 5;//全局变量,初始化为5 u32 TestTmp2;//全局变量,未初始化 const u32 TestTmp3[10] = {6,7,8,9,10,11,12,13,12,13}; u8 TestFun(u32 x)//函数,带一个参数,并返回一个u8值 {  u8 test_tmp1 = 4;//局部变量,初始化 u8 test_tmp2;//局部变量,未初始化 static u8 test_tmp3 = 0;//静态局部变量 test_tmp3++;  test_tmp2 = x; if(test_tmp2> TestTmp1)   test_tmp1 = 10; else test_tmp1 = 5;  TestTmp2 +=TestTmp3[test_tmp1]; return test_tmp1; } 然后程序就一直在main函数的while循环里面执行。中断呢?对,还有中断。中断中断,就是中断正常的程序执行流程。我们查看Delay函数,uwTimingDelay不等于0就死等?谁会将uwTimingDelay改为0? /**   * @brief  Inserts a delay time.   * @param  nTime: specifies the delay time length, in milliseconds.   * @retval None   */ void Delay(__IO uint32_t nTime) {   uwTimingDelay = nTime; while(uwTimingDelay != 0); } 搜索uwTimingDelay变量,函数TimingDelay_Decrement会将变量一直减到0。 /**   * @brief  Decrements the TimingDelay variable.   * @param  None   * @retval None   */ void TimingDelay_Decrement(void) { if (uwTimingDelay != 0x00)   {     uwTimingDelay--;   } } 这个函数在哪里执行?经查找,在SysTick_Handler函数中运行。谁用这个函数? /**   * @brief  This function handles SysTick Handler.   * @param  None   * @retval None   */ void SysTick_Handler(void) {   TimingDelay_Decrement(); } 经查找,在中断向量表中有这个函数,也即是说这个函数指针保存在中断向量表内。当发生中断时,就会执行这个函数。当然,在进出中断会有保存和恢复现场的操作。这个主要涉及到汇编,暂时不进行分析了。有兴趣自己研究研究。通常,现在我们开发程序不用关心上下文切换了。 __Vectors       DCD     __initial_sp               ; Top of Stack                 DCD     Reset_Handler              ; Reset Handler                 DCD     NMI_Handler                ; NMI Handler                 DCD     HardFault_Handler          ; Hard Fault Handler                 DCD     MemManage_Handler          ; MPU Fault Handler                 DCD     BusFault_Handler           ; Bus Fault Handler                 DCD     UsageFault_Handler         ; Usage Fault Handler                 DCD 0 ; Reserved                 DCD 0 ; Reserved                 DCD 0 ; Reserved                 DCD 0 ; Reserved                 DCD     SVC_Handler                ; SVCall Handler                 DCD     DebugMon_Handler           ; Debug Monitor Handler                 DCD 0 ; Reserved                 DCD     PendSV_Handler             ; PendSV Handler                 DCD     SysTick_Handler            ; SysTick Handler 余下问题 1 __main函数是什么函数?是我们在main.c中定义的main函数吗?2 分散加载文件中*(InRoot$$Sections)是什么?3 ZI段,也就是初始化为0的数据段,什么时候初始化?谁初始化? 为什么这几个问题前面留着不说?因为这是同一个问题。顺藤摸瓜! 通过MAP文件了解代码构成 编译结果 程序编译后,在下方的Build Output窗口会输出信息: *** Using Compiler 'V5.06 update 5 (build 528)', folder: 'C:\Keil_v5\ARM\ARMCC\Bin' Build target 'wujique' compiling stm32f4xx_it.c... ... assembling startup_stm32f40_41xxx.s... compiling misc.c... ... compiling mcu_uart.c... linking... Program Size: Code=9038 RO-data=990 RW-data=40 ZI-data=6000 FromELF: creating hex file... ".\Objects\wujique.axf" - 0 Error(s), 0 Warning(s). Build Time Elapsed: 00:00:32 编译目标是wujique C文件compiling,汇编文件assembling,这个过程叫编译 编译结束后,就进行link,链接。 最后得到一个编译结果,9038字节code,RO 990,RW 40,ZI 6000。CODE,是代码,很好理解,那RO、RW、ZI都是什么? FromELF,创建hex文件,FromELF是一个好工具,需要自己添加到option中才能用 map文件配置 更多编译具体信息在map文件中,在MDK Options中我们可以看到,所有信息都放在\Listings\wujique.map 默认很多编译信息可能没钩,钩上所有信息会增加编译时间。 map文件 打开map文件,好乱?习惯就好。我们抓重点就行了。 map 总信息 从最后看起,看到没?最后的这一段map内容,说明了整个程序的基本概况。 有多少RO?RO到底是什么? 有多少RW?RW又是什么? ROM为什么不包括ZI Data?为什么包含RW Data? Image component sizes 往上,看看Image component sizes,这个就比刚刚的总体统计更细了。 这部分内容,说明了每个源文件的概况 首先,是我们自己的源码,这个程序我们的代码不多,只有main.o,wujique_log.o,和其他一些STM32的库文件。 第2部分是库里面的文件,看到没?里面有一个main.o。main函数是不是我们写的main函数?明显不是,我们的main函数是放在main.o文件。这么小的一个工程,用了这么多库,你以前关注过吗?估计没有,除非你曾经将一个原本在1M flash上的程序压缩到能在512K上运行。 第3部分也是库,暂时没去分析这两个是什么东西。 库文件是什么?库文件就是别人已经别写好的代码库。在代码中,我们经常会包含一些头文件,例如: #include #include #include 这些就是库的头文件。这些头文件保存在MDK开发工具的安装目录下。我们经常用的库函数有:memcpy、memcmp、strcmp等。只要代码中包含了这些函数,就会链接库文件。 文件map 再往上,就是文件MAP了,也就时每个文件中的代码段(函数)跟变量在ROM跟RAM中的位置。首先是ROM在0x08000000确实放的是startup_stm32f40_41xxx.o中的RESET 库文件是什么? 库文件就是别人已经别写好的代码库。 在代码中,我们经常会包含一些头文件,例如: #include #include #include 这些就是库的头文件。这些头文件保存在MDK开发工具的安装目录下。 我们经常用的库函数有: memcpy、memcmp、strcmp等。 只要代码中包含了这些函数,就会链接库文件。 文件map 再往上,就是文件MAP了,也就时每个文件中的代码段(函数)跟变量在ROM跟RAM中的位置。首先是ROM在0x08000000确实放的是startup_stm32f40_41xxx.o中的RESET 每个文件有有多行,例如串口,4个函数。 然后是RAM的,main.o中的变量,放在0x20000000,总共有0x0000000c,类型是Data、RW。串口有两种变量,data和bss,什么是bss?这两个名称,是section name,也就是段的意思。看前面type和Attr, RW Data,放在.data段;RW Zero放在.bss段,RW Zero,其实就是ZI。到底哪些变量是RW,哪些是ZI? Image Symbol Table 再往上就是Image Symbol Table,就更进一步到每个函数或者变量的信息了 例如,全局变量TestTmp1,是Data,4字节,分配的位置是0x20000004。 TestTmp3数组放在哪里?放在0X080024E0这个地方,这可是代码区额。因为我们用const修饰了这个全局变量数组,告诉编译器,这个数组是不可以改变的,编译器就将这个数组保存到代码中了。程序中我们经常会使用一些大数组数据,例如字符点阵,通常有几K几十K大,不可能也没必要放到RAM区,整个程序运行过程这些数据都不改变,因此通过const修饰,将其存放到代码区。 const的用处比较多,可以修饰变量,也可以修饰函数。更多用法自行学习 那局部变量存放在哪里呢?我们找到了test_tmp3, 没找到test_tmp1/test_tmp2,为什么呢?在定义时,test_tmp3增加了static定义,意思就是静态局部变量,功能上,相当于全局变量,定义在函数内,限制了这个全局变量只能在这个函数内使用。哪test_tmp1、test_tmp2放在哪里呢? 局部变量,在编译链接时,并没有分配空间,只有在运行时,才从栈分配空间。 u8 TestFun(u32 x)//函数,带一个参数,并返回一个u8值 {  u8 test_tmp1 = 4;//局部变量,初始化 u8 test_tmp2;//局部变量,未初始化 static u8 test_tmp3 = 0;//静态局部变量 上一部分,我们留了一个问题,哪些变量是RW,哪些是ZI?我们看看串口变量的情况,UartBuf3放在bss段,其他变量放在.data段。为什么数组就放在bss?bss是英文Block Started by Symbol的简称。 到这里,我们可解释下面几个概念了: Code就是代码,函数。 RO Data,就是只读变量,例如用const修饰的数组。 RW Data,就是读写变量,例如全局变量跟static修饰的局部变量。 ZI Data,就是系统自动初始化为0的读写变量,大部分是数组,放在bss段。 RO Size等于代码加只读变量。 RW Size等于读写变量(包括自动初始化为0的),这个也就是RAM的大小。 ROM Size,也就是我们编译之后的目标文件大小,也就是FLASH的大小。但是?为什么会包含RW Data呢?因为所有全局变量都需要一个初始化的值(就算没有真正初始化,系统也会分配一个初始化空间),例如我们定义一个变量u8 i = 8;这样的全局变量,8,这个值,就需要保存在FALSH区。 我们看看函数的情况,前面我们不是有一个问题吗?__main和main是一个函数吗?查找main后发现,main是main,放在0x08000579 main是main,放在0x08000189 __main到main之间发生了什么?还记得分散加载文件中的这句吗? *(InRoot$$Sections) __main就在这个段内。下图是__main的地址,在0x08000189。__Vectors就是中断向量,放在最开始。 在分散加载文件中,紧跟RESET的就是*(InRoot$$Sections)。 而且,RESET段正好大小0x00000188。 巧合?参考PPT文档《ARM嵌入式软件开发.ppt》,或自行GOOGLE。 这一段代码都完成什么功能呢?主要完成ZI代码的初始化,也就是将一部分RAM初始化为0。其他环境初始化。。。。通常,我们不用管这一部分。 其他再往上,就是其他信息了,例如优化了哪些东西,移除了哪些函数。 最后 到这里,一个程序,是怎么组成的,程序是如何运行的,基本有一个总体印象了。不过,对于中断,后面还会进行详细说明。

    时间:2021-03-24 关键词: 嵌入式 IO 单片机

  • 基于AT89C51 单片机的节拍器

    基于AT89C51 单片机的节拍器

    1 硬件电路原理 节拍器以AT89C51 单片机为控制中心,由LED 显示模块、调节键盘模块、声音输出模块组成。图1 是节拍器的电路原理图。ATMEL 公司生产的AT89C51 单片机与MCS51指令系统兼容,40 脚结构,是系统的控制中心。显示模块由四位一体的共阳极蓝色LED 显示器构成,采用动态扫描显示方式, Q11~ Q14是LED 的位选择开关三极管, R6~ R13是数码管段发光二极管的限流电阻。四位一体的LED 数码管完成显示节拍数、各功能代码及参数值的功能。键盘调节模块由4 只按键构成,分别是功能选择键A、设置参数选择键B、参数增加键C和参数减少键D ,4 只按键可以完成各种功能的选择和各参数的设置。声音输出模块由以Q1、Q2、Q3和扬声器为中心的功率放大电路组成,不同频率的脉冲从单片机的P2.6口输出, 经R14限流和功率放大后,推动扬声器发出洪亮的声音。由于输出的音频信号是脉冲波,三极管工作在开关状态,损耗小发热量不大, Q2、Q3使用小功率管C8050和C8550 即可。整个系统硬件结构简单。由外部提供12 V直流电直接供音频功放模块使用,经LM7805 稳压成5 V 后供单片机及LED 显示用。 2 软件说明 软件系统采用模块化结构设计,分别是主程序模块、节拍器模块、键盘识别和参数设置模块等。其中每个模块又由若干个子模块构成。上电或复位后进入调节功能,重复按A键在调节功能、节拍器功能之间轮换。当进入调节功能后,重复按B 键可选中不同的调节对象,再按C 或D 键增加或减少调节对象的参数值,调节时显示调节对象的代码和参数值。 2.1 主程序模块 在主程序模块中完成存储单元的初始化、定时器计数器的初始化、中断初始化、标志位的初始化、扫描键盘,并根据功能选择键A 的值启动以下功能模块之一:参数设置功能、节拍器功能。 2.2 节拍器功能模块 节拍速度在24~400 拍/min 范围内可调,节拍误差小于2%,节拍数为1~9可调。显示器显示节拍数,扬声器发出节拍声,显示节拍数1 时发出600 Hz 的高频声0.1 s ,显示其他节拍数时发出300 Hz 的低频声0.1 s。该模块由节拍延时部分、节拍数显示部分、音频脉冲形成部分组成。节拍功能模块程序流程图如图2 所示。 2.3 参数调节模块 按A 键选择进入参数调节功能模块后,重复按B 键,可以依次选择节拍速度、节拍分度参数的设置,LED 显示器上显示参数类型代码和该参数的数字,按C 或B 键则在该参数的取值范围内循环增加或减少一个单位值。代码1 是节拍数,取值范围1~9。代码2 是节拍速度,取值范围是24~400拍/min。该模块程序由键盘扫描识别部分、参数显示部分、A键处理部分、B 键处理部分和C、D 键处理等子程序组成。 图2 节拍器模块流程图 3 实验 从显示、按键、声音和节拍精度等方面进行测试。 显示观察:处于节拍工作状态时4 个数码管同时循环显示节拍数,练琴时眼睛的余光就能看清节拍数。处于调节模式时,最高位显示待调节的参数代码,其余3 位显示参数值,当参数高位为零时不显示。显示正确。 按键测试:按下功能键A ,可以在参数调节和节拍模式之间转换。当处于参数调节模式时,按下参数更改键B ,可以在节拍数和节拍速度之间转换;按下增加键C 或减少键D ,参数值在当前值基础上增加或减少1 ,并且在参数的调节范围内循环变化。当处于节拍工作模式时,BCD 键不起作用。键盘工作正常。 声音观测:节拍音短促有力,起始拍与其余拍音调区别明显。在钢琴弹奏的环境中清晰可闻。 节拍精度测量:用秒表测量节拍器500 拍所用时间。节拍速度分别为72、112、144 拍/min 的时候, 用时分别为418.1 s、268.9 s、210.5 s ,误差分别为0.29%、0.35%、1.1%。节拍精度达到设计要求。 4 结束语 节拍器的起始拍的声音和其它拍的声音不同,听觉和视觉效果好,节拍精度高,调节方便。多名琴童使用该节拍器练钢琴均取得很好的效果。硬件成本低廉,不易损坏,可以将外形设计成工艺品。基于AT89C51 单片机的节拍器具有较好的应用价值。

    时间:2021-03-23 关键词: 节拍器 AT89C51 单片机

  • 基于Atmegal6单片机的通用电机控制装置的设计

    基于Atmegal6单片机的通用电机控制装置的设计

    0 引言 电机的驱动与控制是现代电子技术中一个重要的研究课题,不同种类的电动机需要有不同的控制和驱动方法。使用高性能单片机作为电机控制驱动装置的核心,可以有效降低电机驱动器的成本,扩展应用范围,提高使用灵活性。 ATmegal6单片机是ATMEL公司的一款高性能8位AVR单片机,它内部带有功能强大的可编程定时和计数单元,通过编程可以很容易地产生各类交、直流电机以及步进电机的驱动波形,因此,利用这类功能强大的单片机作为电机控制器的核心,可以使控制器应用更加灵活、应用范围更广、维护成本更低。本文设计出的电机通用控制装置功能齐全,其液晶显示装置和按键可以控制并显示电机的运行状态,而数字化的温度传感器则能有效准确地监控电机的运行温度,RS485/232总线通信接口可以将多个控制器进行联网。从而实现电机的智能化远程控制。 1 电机控制及驱动电路设计 图l所示是一种通用电机控制装置系统的总体结构图。其整个单片机系统以ATmegal6单片机为控制核心,其中从单片机和主单片机利用I2C总线进行通信。从单片机连接按键和液晶屏,可以实现人机接口的功能,这样即可以为主单片机节约宝贵的I/O资源,又可以提高系统的运行效率。另外,DSl8820采用单总线结构采集温度,可以实现对电机温度的监控。 1.1 ATmegal6主控电路 ATmegal6单片机具有3个PWM功能的定时器/计数器T/C0、T/Cl和T/C2,其中T/C0和T/C2是两个8位的定时器/计数器,而T/Cl是16位具有输入捕获功能的定时器/计数器。 本系统的主控单片机电路如图2所示。它以megal6单片机为核心,配有外围复位电路和振荡器电路,单片机所有I/0都可独立引出,以便与外部电路的连接和扩展。 1.2 电机温度监测电路 电机的表面温度是衡量电机是否在安全状态下工作的一个重要指标。本系统的电机温度监测电路利用美国DALLAS半导体公司推出的单总线数字化测温集成电路DSl8820来实现。该数字化传感器具有很宽的测温范围(-55℃~+125℃),工作时只需要三根引线,而且多只DSl8820可以并行连接,以实现对多个电动机的温度监控。 系统工作时,DSl8820可把测得的温度数据传给单片机。如果超过用户设定,系统还可执行电机保护和报警等程序。电机温度监测系统的结构如图3所示,图4所示是其温度监控电路。 1.3 键盘及LCD接口电路 本系统的按键和LCD接口控制电路以单片机AT89S51为核心,该电路使用I2C总线与主单片机进行通信。利用这种主从单片机分离的设计可将一些大量占用IO端口资源的低速设备进行集中管理,从而为主单片机节约硬件资源和程序开销,提高系统的使用灵活性和运行效率。其LCD显示和键盘处理电路如图5所示。 1.4 RS-232/485通信电路 为了适应电机控制的网络化、智能化需求,本电机控制器带有RS232/RS485数据接口。用户利用这两种总线接口可以方便地将多个电机控制器连接成网,以方便电机系统的集中化管理。RS485接口电路使用收发控制的“透明化”管理,MAX485芯片的收发切换由NE555组成的单稳态电路自动完成,当单片机需要向RS485总线传输数据时,NE555可自动将MAX485切换至发送状态,数据传送完毕后,MAX485又将恢复至接收状态。RS-232/485总线驱动电路如图6所示。 1.5 电机驱动电路 本控制器的驱动部分使用凌阳SPGT62C19B电机驱动芯片来实现对直流电机和步进电机的驱动。SPGT62C19B是低电压单片式步进电机驱动 器集成电路芯片,其输出电压可达40 V,输出电流可达750mA。设计时,可由输入的逻辑电平来决定输出脉冲的宽度及频率。由该芯片组成的电机驱动系统将脉冲发生器、脉冲分配器、脉冲放大器合为一体,故可省去很多外围器件。与其它部件一样,主控电路也被设计成为一个独立的模块.以方便更换,而且该模块还可用于别的场合。其电机驱动电路图如图7所示。 1.6 转速测量电路 转速测量可采用一组鼠标上用的红外对管来实现,其电路原理如图8所示。当红外发射管与红外接收管之间被直流电机光栅转盘的不透明部分遮挡时,红外接收管处于截止状态,此时图中的SPEED输出高电平。反之,当光栅转盘的通光槽转至红外对管之间时,红外接收管处于导通状态,此时SPEED输出低电平。这样,将SPEED连接到单片机的I/O口,即可通过定时计数的方法计算出电机的转动速度。 2 单片机程序设计 2.1 主程序 本驱动器的程序设计使用模块化编程思想,其主程序用于完成对各子程序的调用。系统工作后,首先调用初始化子程序,以完成具有复用功能的I/0脚的选择和设置、各种中断功能的选择及其设置、AT89S51和ATmegal6的初始化、中断屏蔽寄存器的设置、中断寄存器的清零、系统变量的初始化等,最后完成开中断。初始化完成之后,系统将调用驱动程序,并完成系统的起动。系统起动之后,即进入正常运行状态。系统的全部运行过程均可由键盘进行实时控制和调节。 2.2 初始化程序 系统的初始化程序流程图如图9所示。该程序中包括LCD显示器、键盘等人机接口部分的初始化。主要功能是对具有复用功能引脚的选择和设置,以及各种中断功能的选择及设置(如外部键盘的中断选择等),同时包括AT89S5l的初始化、键盘的方式选择、工作时间的确定、显示方式的设定等。而系统变量的初始化包括温度的设定,转速初值的设定等。 2.3 控制程序 系统起动后即进入控制程序。控制程序是系统程序的主要部分,主要用来保证系统在给定的转速下正常运行,该程序主要调节单片机PWM口的占空比,从而调节电机绕组两端的平均电压,达到调速的目的,其控制程序流程如图10所示。 3 结束语 本设计实现了一种以ATmega16单片机为核心的电机控制装置。该装置具有各类电机驱动脉冲的输出、电机温度监测与保护、人机操作界面和长距离工业总线通信等功能。利用AVR单片机具备的软硬件特点,可实现对多种电机的驱动与控制,以用于电机驱动研究、网络化电机集中控制等领域。由于该控制器采用主从单片机设计,系统的运行得以很好地分工,其中从单片机实现低速人际交互,主单片机则实现高速的电机驱动与控制,主从单片机各司其职,故可使系统的运行效率达到最高。本电机控制装置的架构开放,使用灵活,可以很好地应用于直流电机的调速控制,交流电机的变频驱动,步进电机的步距细分等多种电机驱动和控制领域。

    时间:2021-03-22 关键词: Atmegal6 通用电机控制装置 单片机

  • pic16f877单片机TMR1的使用笔记

    pic16f877单片机TMR1的使用笔记

    一、结构 1、TMR1可以作为通用的定时器和计数器,也可以利用内置的低频时基振荡器实现实时时钟RTC功能;通过TMR1与CCP模块的配合使用,TMR1还可以实现输入捕捉和输出比较功能。 TMR1是一个16位的可读可写的计数寄存器,由高低两字节组成(TMR1H和TMR1L)16位寄存器从0000H到FFFFH加1计数,然后回到0000H。在从FFFFH到0000H的过程中,置位中断标志位TMR1。 TMR1带有一个3位的可编程预分频器和一个低功耗低频时基振荡器。 二、特点 1、由16位的时钟信号上升沿触发的累加计数寄存器对 TMR1H,TMR1L; 2、TMR1H和TMR1L是在RAM中统一编址的寄存器对,地址为0EH和0FH,可用软件的方式读/写TMR1寄存器对的内容; 3、一个可选用的3位可编程的预分频器; 4、累加计数的信号源可以选择内部系统时钟、外部触发信号或自带时基振荡器信号; 5、既可工作于定时器模式,又可以工作于计数器模式,还可以用作实时时钟RTC; 6、在计数溢出时,相应的溢出中断标志自动置位,并可产生溢出中断。 三、相关寄存器 1、中断控制寄存器 INTCON 2、第一外设中断标志寄存器 PIR1 3、第一外设中断使能寄存器 PIE1 4、计数寄存器 TMR1H和TMR1L 5、控制寄存器 T1CON 四、工作方式 TMR1两种工作方式:定时器方式和计数器方式,其中计数器方式又分为同步计数器方式和异步计数器方式。 TMR1的时钟信号或者触发信号共有3种获取方式: 1、有内部系统时钟4分频后获取,即取自指令周期 2、从RC0/T1OSO/T1CKI和RC1/T1OSI/CCP2引脚获取 3、振荡器产生 五、使用定时器TMR1注意事项 1、当对寄存器TMR1H和TMR1L进行初始化时,预分频器将会自动清零 2、在寄存器对TMR1H和TMR1L进行写操作时,可以使预分频器清零。当TMR1处于运行状态时,对于寄存器TMR1H和TMR 1L值进行的写操作,可能会写入不希望的值 3、TMR1工作于异步计数器方式时,不能作为CCP模块的输入捕捉或输出比较的时间基准。 4、在上电复位(POR)或者其他复位时,TMR1H和TMR1L的内容保持原有数值,不会复位到0000H 5、在上电复位或掉电复位时,控制寄存器T1CON的内容将回到00H,并关闭TMR1,且预分频器的分频比设定为缺省值 1:1。在所有的其他复位时,均不会影响T1CON寄存器的值。 6、如果在复位时需要将TMR1H和TMR1L的内容回到00H,可以用程序实现,即先将TMR1关闭,然后分别将寄存器TMR1H和TMR1L清零 六、使用方式 1 void main() 2 { 3 unsigned int num; 4 /* 5 预分频器1:256,赋值61 256-61=195 6 */ 7 INTCON = 0xc0;//开总中断,开第一外设中断 8 PIE1 = 0x01;//使能定时器1中断 9 //赋值 50ms 10 TMR1H = (65536-50000)/256; 11 TMR1L = (65536-50000)%256; 12 T1CON = 0x01;//启动定时器,不使用预分频器 13 14 while(1) 15 { 16 if(20 == num) 17 { 18 num = 0;//计数清零 19 //功能1 20 { 21 22 } 23 } 24 } 25 } 26 27 void interrupt timer1() //中断函数不需要调用 28 { 29 //注意进入中断T0IF已经置1 30 TMR1IF = 0//标志位清零 31 //重新赋值 32 TMR1H = (65536-50000)/256; 33 TMR1L = (65536-50000)%256; 34 num++; 35 } 使用预分频器 1 void main() 2 { 3 unsigned int num; 4 /* 5 预分频器1:8 6 */ 7 INTCON = 0xc0;//开总中断,开第一外设中断 8 PIE1 = 0x01;//使能定时器1中断 9 //赋值 50ms 10 TMR1H = (65536-50000)/256; 11 TMR1L = (65536-50000)%256; 12 T1CON = 0x31;//启动定时器,预分频器1:8 13 14 while(1) 15 { 16 if(20 == num)//8s 17 { 18 num = 0;//计数清零 19 //功能1 20 { 21 22 } 23 } 24 } 25 } 26 27 void interrupt timer1() //中断函数不需要调用 28 { 29 //注意进入中断T0IF已经置1 30 TMR1IF = 0//标志位清零 31 //重新赋值 32 TMR1H = (65536-50000)/256; 33 TMR1L = (65536-50000)%256; 34 num++; 35 }

    时间:2021-03-22 关键词: pic16f877 TMR1 单片机

首页  上一页  1 2 3 4 5 6 7 8 9 10 下一页 尾页
发布文章

技术子站

更多

项目外包