当前位置:首页 > 单片机开发
  • 实例学习 Keil 软件的使用

    单片机开发中除必要的硬件外,同样离不开软件,我们写的汇编语言源程序要变为 CPU 可以执行的机器码有两种方法,一种是手工汇编,另一种是机器汇编,目前已极少使用手工 汇编的方法了。机器汇编是通过汇编软件将源程序变为机器码,用于 MCS-51 单片机的汇编 软件有早期的 A51,随着单片机开发技术的不断发展,从普遍使用汇编语言到逐渐使用高级 语言开发,单片机的开发软件也在不断发展,Keil 软件是目前最流行开发 MCS-51 系列单片 机的软件,这从近年来各仿真机厂商纷纷宣布全面支持 Keil 即可看出。Keil 提供了包括 C 编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通 过一个集成开发环境(uVision)将这些部份组合在一起。运行 Keil 软件需要 Pentium 或以 上的 CPU,16MB 或更多 RAM、20M 以上空闲的硬盘空间、WIN98、NT、WIN2000、WINXP 等操作系统。掌握这一软件的使用对于使用 51 系列单片机的爱好者来说是十分必要的,如 果你使用 C 语言编程,那么 Keil 几乎就是你的不二之选(目前在国内你只能买到该软件、 而你买的仿真机也很可能只支持该软件),即使不使用 C 语言而仅用汇编语言编程,其方便 易用的集成环境、强大的软件仿真调试工具也会令你事半功倍。 我们将通过一些实例来学习 Keil 软件的使用,在这一部份我们将学习如何输入源程序, 建立工程、对工程进行详细的设置,以及如何将源程序变为目标代码。图 1 所示电路图使用 89C51 单片机作为主芯片,这种单片机性属于 MCS-51 系列,其内部有 4K 的 FLASH ROM,可以反复擦写,非常适于做实验。89C51 的 P1 引脚上接 8 个发光二极管,P3.2~P3.4 引脚上接 4 个按钮开关,我们的第一个任务是让接在 P1 引脚上的发光二极管依次循环点亮。 一、Keil 工程的建立 首先启动 Keil 软件的集成开发环境,这里假设读者已正确安装了该软件,可以从桌面 上直接双击 uVision 的图标以启动该软件。 UVison 启动后,程序窗口的左边有一个工程管理窗口,该窗口有 3 个标签,分别是Files、Regs、和 Books,这三个标签页分别显示当前项目的文件结构、CPU 的寄存器及部份特殊 功能寄存器的值(调试时才出现)和所选 CPU 的附加说明文件,如果是第一次启动 Keil, 那么这三个标签页全是空的。 1、源文件的建立     ? 使用菜单“File->New ”或者点击工具栏的新建文件按 钮,即可在项目窗口的右侧打开一个新的文本编缉窗口, 在该窗口中输入以下汇编语言源程序,例 1: MOV A,#0FEH MAIN: MOV P1,A RL A LCALL DELAY AJMP MAIN DELAY: MOV R7,#255 D1: MOV R6,#255 DJNZ R6,$ 图 1 简单的键盘、显示板 END DJNZ R7,D1 RET 保存该文件,注意必须加上扩展名(汇编语言源程序一般用 asm 或 a51 为扩展名),这里假定将文件保存为 exam1.asm。 需要说明的是,源文件就是一般的文本文件,不一定使用 Keil 软件编写,可以使用任意 文本编缉器编写,而且,Keil 的编缉器对汉字的支持不好,建议使用 UltraEdit 之类的编缉 软件进行源程序的输入。 2、建立工程文件 在项目开发中,并不是仅有一个源程序就行了,还要为这个项目选择 CPU(Keil 支持数 百种 CPU,而这些 CPU 的特性并不完全相同),确定编译、汇编、连接的参数,指定调试 的方式,有一些项目还会有多个文件组成等,为管理和使用方便,Keil 使用工程(Project) 这一概念,将这些参数设置和所需的所有文件都加在一个工程中,只能对工程而不能对单一 的源程序进行编译(汇编)和连接等操作,下面我们就一步一步地来建立工程。     ? 点击“Project->New Project… ”菜单,出现一个对话框,要求给将要建立的工程起一个 名字,你可以在编缉框中输入一个名字 (设为 exam1),不需要扩展名。点击“保 存”按钮,出现第二个对话框,如图 2 所示,这个对话框要求选择目标 CPU(即 你所用芯片的型号),Keil 支持的 CPU 很多,我们选择 Atmel 公司的 89C51 芯 片。点击 ATMEL 前面的“+”号,展开 该层,点击其中的 89C51,然后再点击 “确定”按钮,回到主界面,此时,在 工程窗口的文件页中,出现了“Target 1”,前面有“+”号,点击“+”号展开, 可以看到下一层的“ Source Group1”,这 时的工程还是一个空的工程,里面什么 文件也没有,需要手动把刚才编写好的 源程序加入,点击“Source Group1”使 其反白显示,然后,点击鼠标右键,出现一个下 拉菜单,如图 3 所示。选中其中的“Add file to Group”Source Group1”,出现一个对话框,要求 寻找源文件,注意,该对话框下面的“文件类型” 默认为 C source file(*.c),也就是以 C 为扩展名 的文件,而我们的文件是以 asm 为扩展名的, 所以在列表框中找不到 exam1.asm,要将文件类 型改掉,点击对话框中“文件类型”后的下拉列 表,找到并选中“Asm Source File(*.a51,*.asm), 这样,在列表框中就可以找到 exam1.asm 文件 了。 双击 exam1.asm 文件,将文件加入项目,注 图 2 选择目标 CPU     图 3 加入文件 意,在文件加入项目后,该对话框并不消 失,等待继续加入其它文件,但初学时常 会误认为操作没有成功而再次双击同一文 件,这时会出现如图 4 所示的对话框,提 示你所选文件已在列表中,此时应点击“确 定”,返回前一对话框,然后点击“Close” 即可返回主界面,返回后,点击“Source Group 1”前的加号,会发现 exam1.asm 文 件已在其中。双击文件名,即打开该源程 序。 二、工程的详细设置     图 4 重复加入文件的错误 工程建立好以后,还要对工程进行进一步的设置,以满足要求。 首先点击左边 Project 窗口的 Target 1,然后使用菜单“Project->Option for target ‘target1’” 即出现对工程设置的对话框,这个对话框可谓非常复杂,共有 8 个页面,要全部搞清可不容 易,好在绝大部份设置项取默认值就行了。     ? 设置对话框中的 Target 页面,如 图 5 所示,Xtal 后面的数值是晶振频 率值,默认值是所选目标 CPU 的最高 可用频率值,对于我们所选的 AT89C51 而言是 24M,该数值与最终 产生的目标代码无关,仅用于软件模 拟调试时显示程序执行时间。正确设 置该数值可使显示时间与实际所用时间一致,一般将其设置成与你的硬件 图 5 对目标进行设置 所用晶振频率相同,如果没必要了解程序执行的时间,也可以不设,这里设置为 12。 Memory Model 用于设置 RAM 使用情况,有三个选择项,Small 是所有变量都在单片 机的内部 RAM 中;Compact 是可以使用一页外部扩展 RAM,而 Larget 则是可以使用全部 外部的扩展 RAM。Code Model 用于设置 ROM 空间的使用,同样也有三个选择项,即 Small 模式,只用低于 2K 的程序空间;Compact 模式,单个函数的代码量不能超过 2K,整个程序 可以使用 64K 程序空间;Larget 模式,可用全部 64K 空间。Use on-chip ROM 选择项,确认 是否仅使用片内 ROM(注意:选中该项并不会影响最终生成的目标代码量);Operating 项 是操作系统选择,Keil 提供了两种操作系统:Rtx tiny 和 Rtx full,关于操作系统是另外一个 很大的话题了,通常我们不使用任何操作系统,即使用该项的默认值:None(不使用任何 操作系统);Off Chip Code memory 用以确定系统扩展 ROM 的地址范围,Off Chip xData memory 组用于确定系统扩展 RAM 的地址范围,这些选择项必须根据所用硬件来决定,由 于该例是单片应用,未进行任何扩展,所以均不重新选择,按默认值设置。 设置对话框中的 OutPut 页面,如图 6 所示,这里面也有多个选择项,其中 Creat Hex file 用于生成可执行代码文件(可以用编程器写入单片机芯片的 HEX 格式文件,文件的扩展名 为.HEX),默认情况下该项未被选中,如果要写片做硬件实验,就必须选中该项,这一点是 初学者易疏忽的,在此特别提醒注意。选中 Debug information 将会产生调试信息,这些信 息用于调试,如果需要对程序进行调试,应当选中该项。Browse information 是产生浏览信 息,该信息可以用菜单 view->Browse 来查看,这里取默认值。按钮“ Select Folder for objects ” 是用来选择最终的目标文件所在的 文件夹,默认是与工程文件在同一 个文件夹中。Name of Executable 用 于指定最终生成的目标文件的名 字,默认与工程的名字相同,这两 项一般不需要更改。 工程设置对话框中的其它各页 面与 C51 编译选项、A51 的汇编选 项、BL51 连接器的连接选项等用法 有关,这里均取默认值,不作任何     图 6 对输出进行控制 修改。以下仅对一些有关页面中常用的选项作一个简单介绍。 Listing 标签页用于调整生成的列表文件选项。在汇编或编译完成后将产生(*.lst)的列 表文件,在连接完成后也将产生(*.m51)的列表文件,该页用于对列表文件的内容和形式 进行细致的调节,其中比较常用的选项是“C Compile Listing”下的“Assamble Code”项, 选中该项可以在列表文件中生成 C 语言源程序所对应的汇编代码。     ? C51 标签页用于对 Keil 的 C51 编译器的编译过程进行控制,其中比较常用的是“Code Optimization”组,如图 7 所示,该组中 Level 是优化等级,C51 在对源程序进行编译时,可 以对代码多至 9 级优化,默认使用 第 8 级,一般不必修改,如果在编 译中出现一些问题,可以降低优化 级别试一试。Emphasis 是选择编 译优先方式,第一项是代码量优化 (最终生成的代码量小);第二项 是速度优先(最终生成的代码速度快);第三项是缺省。默认的是速 度优先,可根据需要更改。 图 7 代码生成控制 设置完成后按确认返回主界面,工程文件建立、设置完毕。 三、编译、连接     ? 在设置好工程后,即可进行编译、连接。选择菜单 Project->Build target,对当前工程进 行连接,如果当前文件已修改,软件会先对该文件进行编译,然后再连接以产生目标代码; 如果选择 Rebuild All target files 将会 对当前工程中的所有文件重新进行编 译然后再连接,确保最终生产的目标 代码是最新的,而 Translate … .项则仅 对该文件进行编译,不进行连接。 以上操作也可以通过工具栏按钮直 接进行。图 8 是有关编译、设置的工具 栏按钮,从左到右分别是:编译、编译 连接、全部重建、停止编译和对工程进 行设置。 编译过程中的信息将出现在输出窗 口中的 Build 页中,如果源程序中有语 图 8 有关编译、连接、项目设置的工具条     图 9 正确编译、连接之后的结果 法错误,会有错误报告出现,双击该行,可以定位到出错的位置,对源程序反复修改之后, 最终会得到如图 9 所示的结果,提示获得了名为 exam1.hex 的文件,该文件即可被编程器读 入并写到芯片中,同时还产生了一些其它相关的文件,可被用于 Keil 的仿真与调试,这时 可以进入下一步调试的工作。

    时间:2019-04-15 关键词: 单片机开发 汇编语言 keil单片机

  • 单片机开发中为什么要用到仿真和仿真机

    仿真是单片机开发过程中非常重要的一个环节,除了一些极简单的任务,一般产品开发过程中都要进行仿真,仿真的主要目的是进行软件调试,当然借助仿真机,也能进行一些硬件排错。一块单片机应用电路板包括单片机部份及为达到使用目的而设计的应用电路,仿真就是利用仿真机来代替应用电路板(称目标机)的单片机部份,对应用电路部份进行测试、调试。仿真有CPU仿真和ROM仿真两种,所谓CPU仿真是指用仿真机代替目标机的CPU,由仿真机向目标机的应用电路部份供给各种信号、数据,进行调试的办法。这种仿真能通过单步运行、连续运行等多种办法来运行程序,并能观察到单片机内部的变化,便于改正程序中的错误。所谓ROM仿真,就是用仿真机代替目标机的ROM,目标机的CPU工作时,从仿真机中读取程序,并执行。这种仿真其实就是将仿真机当成一片EPROM,只是省去了擦片、写片的麻烦,并没有多少调试手段可言。常常这是二种不一样类型的仿真机,也就是说,一台仿真机不能既做CPU仿真,又做ROM仿真。可能的情况下,当然以CPU仿真好。以上是本人对单片机的理解,如有不对之处,请诸位大侠多多指点。发表您的高论。

    时间:2018-12-20 关键词: 仿真 仿真机 单片机开发

  • Microchip最新MPLAB REAL ICE仿真系统助力PIC单片机开发..

    单片机和模拟半导体供应商——microchip technology(美国微芯科技公司)近日宣布推出mplab real ice仿真系统,为采用其pic单片机和dspic数字信号控制器(dsc)进行应用开发的客户创优增值。该系统为microchip的高速单片机和dsc提供低成本的新一代仿真支持,满足客户希望控制器存储速度更高和电缆互连距离更长的需求。 mplab real ice仿真系统能够支持标准和先进的调试功能,如复杂断点、应用代码的追踪和数据采集、代码执行计时及实时变量监控。这套仿真系统完全整合于microchip的mplab集成开发环境(ide)中,用户可在该环境内编写代码、建立项目以及进行测试、检验和编程。系统充分利用mplab ide的功能,把硬件和软件应用设计工具融会贯通,让用户在统一框架内快速开发和部署所需应用。mplab ide随mplab real ice仿真系统免费供应。 嵌入式工程设计人员的需求不断提高,他们希望在简化代码开发的同时降低设计软件的成本。为此,microchip在设计新一代单片机和dsc的同时,开发了这套mplab real ice仿真系统,确保仿真功能的完美整合。系统通过专有的片上资源缔造仿真空间,既可进行全速调试,又可对变量进行实时监控。其高速数据接口更可迅速上载大量追踪记录,并能快速监控和瞬时调节应用参数。 mplab real ice仿真系统具备以下先进功能: 全速实时仿真; 耐用的探针接口: 探针驱动器加入保护电路,可防御来自目标板的功率冲击; 传统及高速连接: mplab real ice 仿真系统配备标准接口,能后向兼容以microchip mplab icd 2在线调试器开发的应用;用户更可选用一对高速驱动器/接收器插件,在主机和目标板之间实现抗噪声的高速通信,电缆可长达三米; 为外部触发器而设的逻辑探针:系统包含逻辑探针,可连接装置上的14引脚接头;有关输出更可触发外部逻辑分析器或示波器; 追踪执行和分析: mplab real ice 仿真系统有多种途径对运行中的应用有效地追踪其执行情况并记录相关数据,包括实时监控、数据捕捉和串流并行追踪,这主要通过器件i/o口或基于spi/uart的串流串行追踪来实现; 轻巧便携、以usb驱动,并符合ce和rohs标准。 供货情况 mplab real ice在线仿真器(部件编号dv244005),为全面而先进的在线仿真器确立了新的价格定位。mplab real ice高性能套件(perforance pak)(部件编号ac244002)通过高速驱动器插板,扩展mplab real ice仿真系统的功能和应用。这两款产品现通过microchip的代理商和microchipdirect供应。可供选配的处理器扩展套件(optional processor extension pak)将稍后推出。该套件配备处理器扩展板,可直接插入目标单片机插座,以便腾出调试引脚支持有关应用,为用户带来更大便利。

    时间:2018-12-12 关键词: 助力 系统 嵌入式开发 最新 单片机开发

  • 基于PIC单片机开发的高精度数据采集器

    基于PIC单片机开发的高精度数据采集器

      1ADS1210引脚及功能  ADS1210是一种高精度、宽动态范围,采用单5V电源供电,具有24位分辨率的新型A/D转换器。封装形式有18脚双列直插式和18线贴片式,引脚功能描述如表1。  ●指令寄存器(INSR)  指令寄存器是一个8位寄存器,它指明了系统是进行读操作还是写操作,并确定读/写操作的字节长度以及读/写操作寄存器的起始地址。?  ●命令寄存器(CMR)  命令寄存器是ADS1210的关键,它控制着ADS1210的所有特性功能。一旦串口时钟的下降沿将数据字节的最后一位写入命令寄存器,新的模式就开始生效。命令寄存器控制ADS1210所选用的选项和操作模式,包括可编程增益放大器的增益(G)设置、增强模式(TMR)、输出数据率(Decimation)和校正方式等等。  ●数据输出寄存器(DOR)  数据输出寄存器保存最近的转换结果。“数据准备就绪信号”变为低电平前,寄存器的内容被一个新的结果更新。  ●失调寄存器(OCR)  失调寄存器对放入数据输出寄存器前的转换结果进行失调校正。在这种应用中,失调寄存器的内容可能是自校正结果,也可能是系统校正结果,通过串行口可以对失调寄存器进行读写。?  ●满刻度校正寄存器(FCR)  满刻度校正寄存器对放入数据输出寄存器前的转换结果进行满刻度校正。实际的失调寄存器值和满刻度校正寄存器值随结构、温度和电源的变化而改变。因此,任何状态下的失调寄存器和满刻度校正寄存器的实际值都不能精确地预测,也就是说,给定系统的校正不能简单地通过外部误差的测量来获得某一结果,将其写入寄存器作为校正因子。  与ADS1210的通信是在数据转换完成之后,即电平为低的时候开始进行的。通常首先是对指令寄存器进行写操作,指明下一步要进行操作的寄存器的起始地址和字节长度以及系统是进行读操作还是写操作,由此决定接下来进行什么类型的通信。之后随着合适的时钟脉冲产生(SCLK时钟的周期数是由指令寄存器指定的字节长度所决定的),对指令寄存器指定的寄存器进行操作,完毕后等待引脚的下一个低电平产生,如此反复直到数据采集完成。?  在实际的测量中,电源是影响精度的重要因素。为了减小其影响,电源必须稳定,噪声小,因此,使用MAX666作+5V电压的稳压芯片,以及利用外围电容的作用减少电压波动。此外,ADS1210可使用本身的校正寄存器,通过编程对A/D转换的数据进行校正,进一步提高测量精度。通过CMR的设置,使用者可自行选择合适的校正模式。在背景校正下,校正以固定的时间间隔重复不断地进行,其他的几种类型,一旦校正运行完成就恢复正常运行。本设计采用背景校正模式。??  PIC系列单片机硬件系统设计简洁,指令系统设计精炼。PIC单片机集成了丰富的外围模块,可以通过对内部的寄存器操作实现对外围模块的控制。  串行扩展通信接口是单片机与其他计算机或模块之间进行数据交换的重要渠道。PIC16F87X系列单片机主要配置有2种形式的串口通信模块,即主控同步串行通信MSSP和通用同步/异步收发器USART。其中,MSSP模块主要应用于系统内部近距离的串行通信,如SPI和I2C模式;USART模块主要应用于系统之间的远距离的串口通信。  SPI(Serial Peripheral Interface)是一种单片机外设芯片同步串行扩展接口,由于ADS1210自带一个灵活的同步串行接口与SPI通信模式兼容,故本设计中PIC单片机与ADS1210进行的所有数据交换都采用SPI的通信模式。PIC单片机的SPI模块电路包含3个主要部分:发送缓冲器、接收缓冲器和移位寄存器。  USART在异步模式下采用的数据格式为1位起始位、8位或9位数据位和1位停止位,无奇偶位校验码,常用的数据为8位。片内提供的8位波特率发生器BRG,可以利用系统时钟信号产生标准的波特率频率为串行传送所用。USART具有分别独立的发送器和接收器,但它们所采用的数据格式和波特率是相同的。本设计运用单片机的USART异步发送功能通过MAX232芯片进行必要的电平转换后向上位机传送所采集的数据。?  ADS1210与外部器件接口形式有双线制、三线制、四线制和多线制,此处采用的是四线制实现与单片机的接口,接口信号是数据准备就绪信号(),数据输入/输出线(SDIO)、数据输出线(SDOUT)、时钟信号线(SCLK)。具体见图1。  PIC单片机程序的流程图如图2。  图3是用来从串口接收数据的软件运行界面,作为本设计的测试软件。接收区内显示的 数据是使用本数据采集器所采集的几组数据,而界面下端的状态栏RX显示的是接收数据的组 数,实验表明,本设计完全可以达到20位以上的精度。  本设计可用于工业过程控制、仪器仪表、血液分析、智能发射机、电位计、质量标准、 压力转换等高分辨率测量场合,例如可用于精度要求较高的电容式测压微传感器的性能测试 ,具有一定的通用性。?

    时间:2018-12-10 关键词: 数据 pic 嵌入式开发 采集器 单片机开发

  • PIC单片机开发过程中的一些经验、技巧

    由美国Microchip公司生产的PIC系列单片机,由于其超小型、低功耗、低成本、多品种等特点,已广泛应用于工业控制、仪器、仪表、通信、家电、玩具等领域,本文总结了作者在PIC单片机开发过程中的一些经验、技巧,供同行参考。1怎样进一步降低功耗  功耗,在电池供电的仪器仪表中是一个重要的考虑因素。PIC16C××系列单片机本身的功耗较低(在5V,4MHz振荡频率时工作电流小于 2mA)。为进一步降低功耗,在保证满足工作要求的前提下,可采用降低工作频率的方法,工作频率的下降可大大降低功耗(如PIC16C××在 3V,32kHz下工作,其电流可减小到15μA),但较低的工作频率可能导致部分子程序(如数学计算)需占用较多的时间。在这种情况下,当单片机的振荡 方式采用RC电路形式时,可以采用中途提高工作频率的办法来解决。  具体做法是在闲置的一个I/O脚(如RB1)和OSC1管脚之间跨接一电阻(R1),如图1所示。低速状态置RB1=0。需进行快速运算时先置 RB1=1,由于充电时,电容电压上升得快,工作频率增高,运算时间减少,运算结束又置RB1=0,进入低速、低功耗状态。工作频率的变化量依R1的阻值 而定(注意R1不能选得太小,以防振荡电路不起振,一般选取大于5kΩ)。  另外,进一步降低功耗可充分利用“sleep”指令。执行“sleep”指令,机器处于睡眠状态,功耗为几个微安。程序不仅可在待命状态使用 “sleep”指令来等待事件,也可在延时程序里使用(见例1、例2)。在延时程序中使用“sleep”指令降低功耗是一个方面,同时,即使是关中断状 态,Port B端口电平的变化可唤醒“sleep”,提前结束延时程序。这一点在一些应用场合特别有用。同时注意在使用“sleep”时要处理好与WDT、中断的关 系。例1(用Mplab-C编写)例2(用Masm编写)  Delay() Delay  {;此行可加开关中断指令  /*此行可加开关中断指令*/ movlw.10  for (i=0; i

    时间:2018-10-23 关键词: pic 单片机开发

  • Linux上进行单片机开发

    linux上可以使用sdcc进行单片机开发ubuntu使用apt-get install sdcc即可安装。附一个比较通用的MakefilePRJ := testSRC := $(wildcard *.c)HEX := $(PRJ).hexIHX := obj/$(PRJ).ihxOBJ := $(foreach i, $(SRC), obj/$(i:.c=.rel))MCU := -mmcs51CC := sdcc $(MCU)AS := asx8051 #可能是sdas8051LD := sdccPACKIHX := packihxCFLAG :=ASFLAG := -losLDFLAG :=all: obj $(HEX)obj: @mkdir obj$(HEX): $(IHX) @echo "Create hex file ..." @$(PACKIHX) $< > $@$(IHX): $(OBJ) @echo -ne "Linking ..." @$(LD) $(LDFLAG) $^ -o $@ @echo "OK"obj/%.rel: %.c @echo -ne "Compiling $< ..." @$(CC) -c $(CFLAG) $< -o $@ @echo "OK".PHONY: cleanclean: @echo "Clear project ..." @-rm -f obj/* @echo "OK"

    时间:2018-08-31 关键词: Linux 单片机开发

  • C语言在单片机开发中的优势

    汇编语言是一种用文字助记符来表示机器指令的符号语言,是最接近机器码的一种语言。其主要优点是占用资源少、程序执行效率高。但是不同的CPU,其汇编语言可能有所差异,所以不易移植。对于目前普遍使用的RISC架构的8bit MCU来说,其内部ROM、RAM、STACK等资源都有限,如果使用C语言编写,一条C语言指令编译后,会变成很多条机器码,很容易出现ROM空间不够、堆栈溢出等问题。而且一些单片机厂家也不一定能提供C编译器。而汇编语言,一条指令就对应一个机器码,每一步执行什么动作都很清楚,并且程序大小和堆栈调用情况都容易控制,调试起来也比较方便。所以在资源较少单片机开发中,我们还是建议采用汇编语言比较好。而C语言是一种编译型程序设计语言,它兼顾了多种高级语言的特点,并具备汇编语言的功能。C语言有功能丰富的库函数、运算速度快、编译效率高、有良好的可移植性,而且可以直接实现对系统硬件的控制。C语言是一种结构化程序设计语言,它支持当前程序设计中广泛采用的由顶向下结构化程序设计技术。此外,C语言程序具有完善的模块程序结构,从而为软件开发中采用模块化程序设计方法提供了有力的保障。因此,使用C语言进行程序设计已成为软件开发的一个主流。用C语言来编写目标系统软件,会大大缩短开发周期,且明显地增加软件的可读性,便于改进和扩充,从而研制出规模更大、性能更完备的系统。综上所述,用C语言进行单片机程序设计是单片机开发与应用的必然趋势。所以作为一个技术全面并涉足较大规模的软件系统开发的单片机开发人员最好能够掌握基本的C语言编程。

    时间:2018-08-23 关键词: C语言 单片机开发

  • C语言和汇编语言在单片机开发中的特点分别是什么

    汇编语言是一种用文字助记符来表示机器指令的符号语言,是最接近机器码的一种语言。其主要优点是占用资源少、程序执行效率高。但是不同的CPU,其汇编语言可能有所差异,所以不易移植。C语言是一种结构化的高级语言。其优点是可读性好,移植容易,是普遍使用的一种计算机语言。缺点是占用资源较多,执行效率没有汇编高。对于目前普遍使用的RISC架构的8bit MCU来说,其内部ROM、RAM、STACK等资源都有限,如果使用C语言编写,一条C语言指令编译后,会变成很多条机器码,很容易出现ROM空间不够、堆栈溢出等问题。而且一些单片机厂家也不一定能提供C编译器。而汇编语言,一条指令就对应一个机器码,每一步执行什幺动作都很清楚,并且程序大小和堆栈调用情况都容易控制,调试起来也比较方便。所以在单片机开发中,我们还是建议采用汇编语言比较好。

    时间:2018-08-16 关键词: C语言 单片机开发 汇编语言

  • 单片机学习记录——开发总流程

     开发总流程 1.打开keil,建立新的工程。 2.新建 .c 文件和 .h 文件,再把.c文件添加到工程中。 3.在新建的.c文件中编辑c代码就可以了。 4.编译程序,生成.hex可执行文件。 所需查看的文档 查看原理图,了解硬件如何接线,知道控制哪几个IO口 查看单片机的datasheet和各个外设芯片的datasheet,了解如何编程,尤其是外设芯片的工作时序。 如何烧录程序至单片机? 答:编译编写好的单片机程序,生成.hex文件,打开烧录软件,选择单片机型号和COM端口,再选择.hex文件,点击下载,然后打开开发板的电源。至此,程序就已烧录进单片机。

    时间:2018-08-08 关键词: 单片机 单片机开发

  • 在单片机开发中NOR_FLASH的应用

     在单片机开发中,NOR_FLASH常用的有4M和8M的大小: 4M的FLASH在程序中可以这样表示:Ptr < 0x220000 8M的FLASH在程序中可以这样表示:Ptr < 0x400000(最大只能读到0x3fffff) 有了这个关系,在判断NOR_FLASH好坏的方法上我们可以采用计算checksum的方式来校验。 在程序中,我们一般把地址的指针定义为unsigned short *ptr 类型。然后通过指针不断的往后移动可以简引用获取到FLASH中的每一个byte,如果此时定义成unsigned short类型,那么用一个temp变量来接收的话,一次是可以接收到2个byte的数据,如果此时定义成unsigned long类型,同样用temp变量来接收这时一次性可以读到4个byte的数据,所以在处理数据方面可以采用位运算来进行处理。 以下这段程序是每1024byte获取前16个byte的数据依次累加返回,注意,这里累加是以word的形式累加,1 word = 2byte,所以读512相当于读了1024byte 注意,这里的单片机是16位的,其它的可能不同,不要类比,需要重新计算相应数据类型的值。

    时间:2018-07-06 关键词: 单片机 单片机开发

  • 单片机实战开发细节:如何为单片机的按键加一个锁防止多次触发

     最近一直在做凌阳的GPL32001的单片机开发,主打产品是一架钢琴。 在这架钢琴上,我们可以看到遍布着很多按键,有琴键,也有功能选择的按键,面对如此多的按键,对于一个刚出来工作的小伙伴肯定压力比较大,琴键的特征和普通按键不太一样,琴键的一个按键由两个按键组成,一个按键储存着两样信息,力度和键值。 那么在我写的程序的项目要求是这样的,要求每个按键一次只能触发一次,并且触发的时候要发出不同的键码,通过音频解码盒将该键码值读出来,比如第一个白色琴键是key01--->对应的键值就是0000 0001 也就是0x01,而功能按键的编排和琴键有所不同,功能按键的编排从序号key55开始,键值也和琴键的不一样。鉴于这样的特征,即可以鉴别机器是否出现短路,断路等硬件是否损坏的情况。 那么,今天我提出的一个问题也是在单片机开发中常见的,也就是按键,学过单片机的同学都玩过按键,一开始都是这样的代码: if(key == 0) bell = 0 ; else bell = 1 ; 但是如果这样的话,假设是在一个死循环里面,按键如果检测到低电平为按下,按键就会一直触发,bell=0的分支就会被不断的执行。 于是我想到一个好的办法,我项目里是这么写的。 定义一个 static int lock ;然后做以下的操作,当然这个操作是在一个死循环内操作的: //获取按键状态 data = *P_IOE_Data; if((data&0x0080)) { IOE_lock = 0 ; } if((data&0x0080) == 0) { if(IOE_lock == 0) { play_sound_hightolow(0x33,Vol_value); } IOE_lock = 1 ; } if((data & 0x0080))表示按键没有被按下,此时按键锁标志为0,staic类型将记录这个标志变量的值,当if((data & 0x0080) == 0)时,按键此时被按下了,我要判断按键锁标志是否为0,如果为1,那么程序肯定不会运行play_sound_hightolow();这个函数,所以当按下按键的时候,锁的初始化值为0,喇叭发出声音码,音频解码器读出对应的键值为0x33。读完之后立马的将锁标志置1,如果此时一直按住按键不放,因为锁标志等于1,所以无效,程序不进入发码的状态。当松开后,按键的状态由1变成0,此时再按下按键,又有效,然后锁住。 这样做的好处就是使按键按下的时候,发码的状态只触发一次,就不会连着发出0x33的声音码了,只发了一次。在合适的开发利用好标志锁,可以很方便的高效解决很多问题。

    时间:2018-07-06 关键词: 单片机 单片机开发

  • 51c单片机开发

    //TX-1C实验板 //芯片 STC89C52RC //晶振频率 11.0592MHz //=====一个LED灯闪 #include #define uint unsigned int sbit led1=P1^0; void delay1s(); void main() { while(1) { led1=0; delay1s(); led1=1; delay1s(); } } void delay1s() { uint i,j; for(i=500;i>0;i--) for(j=110;j>0;j--); } //======流水灯程序 #include #include #define uint unsigned int #define uchar unsigned char void delayms(uint xms); uchar aa; void main() { aa=0xfe; while(1) { P1=aa;; delayms(500); aa=_crol_(aa,1); } } void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } //=====启动蜂鸣 #include #include #define uint unsigned int #define uchar unsigned char sbit beep=P2^3; void delay(uint z); void main() { while(1) { beep=0; delay(100); beep=1; delay(10000000); } } void delay(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } //======数码管的显示;数字6 #include sbit dula=P2^6; sbit wela=P2^7; void main() { wela=1; P0=0xfe; wela=0; dula=1; P0=0x7d; dula=0; while(1); } //======数码管的静态显示 #include #define uint unsigned int #define uchar unsigned char sbit dula=P2^6; sbit wela=P2^7; uchar num; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71 }; void delayms(uint); void main() { wela=1; P0=0xc0; wela=0; while(1) { for(num=0;num0;x--) for(y=110;y>0;y--); } //======数码管的动态显示 #include #define uint unsigned int #define uchar unsigned char sbit dula=P2^6; sbit wela=P2^7; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71 }; void delayms(uint); void main() { while(1) { dula=1; P0=table[1]; dula=0; P0=0xff; wela=1; P0=0xfe; wela=0; delayms(500); dula=1; P0=table[2]; dula=0; P0=0xff; wela=1; P0=0xfd; wela=0; delayms(500); dula=1; P0=table[3]; dula=0; P0=0xff; wela=1; P0=0xfb; wela=0; delayms(500); dula=1; P0=table[4]; dula=0; P0=0xff; wela=1; P0=0xf7; wela=0; delayms(500); dula=1; P0=table[5]; dula=0; P0=0xff; wela=1; P0=0xef; wela=0; delayms(500); dula=1; P0=table[6]; dula=0; P0=0xff; wela=1; P0=0xdf; wela=0; delayms(500); } } void delayms(uint xms) { uint x,y; for(x=xms;x>0;x--) for(y=110;y>0;y--); } //======定时器0工作方式1===== #include #define uchar unsigned char #define uint unsigned int uchar num; void main() { P1=0x55; TMOD=0x01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; EA=1; ET0=1; TR0=1; while(1) { if(num==20) { num=0; P1=~P1; } } } void t0_time() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; num++; } //=======用定时器0的方式1实现第一个发光管以ms间隔闪烁,用定时器1的方式1实现数码管前两位59s循环计时。 #include #define uchar unsigned char #define uint unsigned int sbit dula=P2^6; sbit wela=P2^7; sbit led1=P1^0; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void delayms(uint); void display(uchar,uchar); uchar num,num1,num2,shi,ge; void main() { led1=0; TMOD=0x11;//00010001 TH0=(65536-50000)/256; TL0=(65539-50000)%256; TH1=(65536-50000)/256; TL1=(65539-50000)%256; EA=1; ET0=1; ET1=1; TR0=1; TR1=1; while(1) { display(shi,ge); } } void display(uchar s,uchar g) { dula=1; P0=table[s]; dula=0; P0=0xff; wela=1; P0=0xfe; wela=0; delayms(5); dula=1; P0=table[g]; dula=0; P0=0xff; wela=1; P0=0xfd; wela=0; delayms(5); } void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } void t0_time() interrupt 1 { TH0=(65536-50000)/256; TL0=(65539-50000)%256; num1++; if(num1==20) { num1=0; led1=~led1; } } void t1_time() interrupt 3 { TH1=(65536-50000)/256; TL1=(65539-50000)%256; num2++; if(num2==20) { num2=0; num++; if(num==60) nu

    时间:2018-07-04 关键词: 51 c 单片机开发

  • C语言在单片机开发中的几个问题

    在单片机的开发应用中,已逐渐开始引入高级语言,C语言就是其中的一种。对用惯了汇编的人来说,总觉得高级语言’可控性’不好,不如汇编那样随心所欲。但是只要我们掌握了一定的C语言知识,有些东西还是容易做出来的,以下是笔者实际工作中遇到的几个问题,希望对初学C51者有所帮助。 一、C51热启动代码的编制 对于工业控制计算机,往往设有有看门狗电路,当看门狗动作,使计算机复位,这就是热启动。热启动时,一般不允许从头开始,这将导致现有的已测量到或计算到的值复位,导致系统工作异常。因而在程序必须判断是热启动还是冷启动,常用的方法是:确定某内存单位为标志位(如0x7f位和0x7e位),启动时首先读该内存单元的内容,如果它等于一个特定的值(例如两个内存单元的都是0xaa),就认为是热启动,否则就是冷启动,程序执行初始化部份,并将0xaa赋与这两个内存单元。 根据以上的设计思路,编程时,设置一个指针,让其指向特定的内存单元如0x7f,然后在程序中判断,程序如下: void main() { char data *HotPoint=(char *)0x7f; if((*HotPoint==0xaa)&&(*(--HotPoint)==0xaa)) { /*热启动的处理 */ } else { HotPoint=0x7e; /*冷启动的处进 *HotPoint=0xaa; *(++HotPoint)=0xaa; } /*正常工作代码*/ } 然而实际调试中发现,无论是热启动还是冷启动,开机后所有内存单元的值都被复位为0,当然也实现不了热启动的要求。这是为什么呢?原来,用C语言编程时,开机时执行的代码并非是从main()函数的第一句语句开始的,在main()函数的第一句语句执行前要先执行一段’起始代码’。正是这段代码执行了清零的工作。C编译程序提供了这段起始代码的源程序,名为CSTARTUP.A51,打开这个文件,可以看到如下代码: . IDATALEN EQU 80H ; the length of IDATA memory in bytes. . STARTUP1: IF IDATALEN <> 0 MOV R0,#IDATALEN - 1 CLR A IDATALOOP: MOV @R0,A DJNZ R0,IDATALOOP ENDIF . 可见,在执行到判断是否热启动的代码之前,起始代码已将所有内存单元清零。如何解决这个问题呢?好在启动代码是可以更改的,方法是:修改 startup.a51源文件,然后用编译程序所附带的a51.exe程序对 startup.a51编译,得到startup.obj文件,然后用这段代码代替原来的起始代码。具体步骤是(设C源程序名为HOTSTART.C): 修改startup.a51源文件(这个文件在C51LIB目录下)。 执行如下命令: A51 startup.a51 得到startup.obj文件。将此文件拷入HOTSTART.C所在目录。 将编好的C源程序用C51.EXE编译好,得到目标文件HOTSTART.OBJ。 用 L51 HOTSTART, STARTUP.OBJ 命令连接,得到绝对目标文件HOTSTART。 用 OHS51 HOTSTART 得到HOTSTART.HEX文件,即可。 对于startup.a51的修改,根据自已的需要进行,如将IDATALEN EQU 80H中的80H改为70H,就可以使6F到7F的16字节内存不被清零。 二、直接调用EPROM中已固化的程序 笔者用的仿真机,由6位数码管显示,在内存DE00H处放显示子程序,只要将要显示的数放入显示缓冲区,然后调用这个子程序就可以使用了,汇编指令为: LCALL 0DEOOH 在用C语言编程时,如何实现这一功能呢?C语言中有指向函数的指针这一概念,可以利用这种指针来实现用函数指针调用函数。指向函数的指针变量的定义格式为: 类型标识符 (*指针变量名)(); 在定义好指针后就可以给指针变量赋值,使其指向某个函数的开始存地址,然后用 (*指针变量名)()即可调用这个函数。如下例: void main(void) { void (*DispBuffer)(); /*定义指向函数指针*/ DispBuffer=0xde00; /*赋值*/ for(;;) { Key(); DispBuffer(); } } 三、将浮点数转化为字符数组 笔者在编制应用程序时有这样的要求:将运算的结果(浮点数)存入EEPROM中。我们知道,浮点数在C语言中是以IEEE格式存储的,一个浮点数占用四个字节,例如浮点数34.526存为(160,26,10,66)这四个数。要将一个浮点数存入EEPROM,实际上就是要存这四个数。那么如何在程序中得到一个浮点数的组成数呢? 浮点数在存储时,是存储连续的字节中的,只要设法找到存储位置,就可以得到这些数了。可以定义一个void的指针,将此指针指向需要存储的浮点数,然后将此指针强制转化为char型,这样,利用指针就可以得到组成该浮点数的各个字节的值了。具体程序如下: #define uchar unsigned char#define uint unsigned intvoid FtoC(void) { float a; uchar i,*px uchar x[4]; /*定义字符数组,准备存储浮点数的四个字节*、 void *pf; px=x; /*px指针指向数组x*/ pf=&a; /*void 型指针指向浮点数首地址*/ a=34.526; for(i=0;i<4;i++) { *(px+i)=*((char *)pf+i); /*强制void 型指针转成char型,因为*/ } /*void型指针不能运算*/ } 如果已将数存入EEPROM,要将其取出合并,方法也是一样,可参考下面的程序。 #define uchar unsigned char#define uint unsigned int void CtoF(void) { float a; uchar i,*px uchar x[4]={56,180,150,73}; void *pf; px=x; pf=&a; for(i=0;i<4;i++) { *((char *)pf+i)=*(px+i); } } 以上所用C语言为FRANKLIN C51 VER 3.2。来源:过往烟云0次

    时间:2018-06-05 关键词: 语言 几个问题 单片机开发

  • 高手分享一些对单片机的经验理解

     单片机,single chip microcomputer,单芯片微型计算机。总体来说,他就是一个芯片。但是他是一个特殊的芯片,因为他不是实现单独的逻辑功能。他是将一个整体的计算机系统集成到这个芯片上。这个计算机系统包括运算器,控制器,存储器,输入设备和输出设备。 其实单片机的学习,和计算机的学习差别不是太大。包括运算器,控制器,存储器,以及输入输出设备的学习。 运算器 运算器由运算部件--算术逻辑单元(alu)、累加器、计算器等部件组成。 控制器 学习的难点在于涉及到指令方面的操作。控制器由程序计数器,指令寄存器,指令译码器,时序发生器和操作控制器。 单片机的开发过程: 这里所说的开发过程并不是一般书中所说的从任务分析开始,我们假设已设计并制作好硬件,下面就是编写软件的工作。在编写软件之前,首先要确定一些常数、地址,事实上这些常数、地址在设计阶段已被直接或间接地确定下来了。如当某器件的连线设计好后, 其地址也就被确定了,当器件的功能被确定下来后,其控制字也就被确定了。然后用文本编辑器(如EDIT、CCED等)编写软件,编写好后,用编译器对源程序文件编译,查错,直到没有语法错误,除了极简单的程序外,一般应用仿真机对软件进行调试,直到程序运行正 确为止。运行正确后,就可以写片(将程序固化在EPROM中)。在源程序被编译后,生成了扩展名为HEX的目标文件,一般编程器能够识别这种格式的文件,只要将此文件调入即可写片。 开发语言的选择 目前,很多人对汇编语言并不认可。可以说,掌握用C语言单片机编程很重要,可以大大提高开发的效率。不过初学者可以不了解单片机的汇编语言,但一定要了解单片机具体性能和特点,不然在单片机领域是比较致命的。如果不考虑单片机硬件资源,在KEIL中用C 胡乱编程,结果只能是出了问题无法解决!可以肯定的说,最好的C语言单片机工程师都是从汇编走出来的编程者,因为单片机的C语言虽然是高级语言,但是它不同于台式机个人电脑上的VC++什么的。单片机的硬件资源不是非常强大,不同于我们用VC、VB等高级语言在 台式PC上写程序,毕竟台式电脑的硬件非常强大,所以才可以不考虑硬件资源的问题。还有就是在单片机编程中C语言虽然编程方便,便于人们阅读,但是在执行效率上是要比汇编语言低10%到20%,所以用什么语言编写程序是要看具体用在什么场合下。总的来说做单片机 编程要灵活使用汇编语言与C语言,让单片机的强大功能以最高是效率展示给用户。 常用的单片机类型 STC单片机 STC公司的单片机主要是基于8051内核,是新一代增强型单片机,指令代码完全兼容传统8051,速度快8~12倍,带ADC,4路PWM,双串口,有全球唯一ID号,加密性好,抗干扰强. PIC单片机: 是MICROCHIP公司的产品,其突出的特点是体积小,功耗低,精简指令集,抗干扰性好,可靠性高,有较强的模拟接口,代码保密性好,大部分芯片有其兼容的FLASH程序存储器的芯片. EMC单片机: 是台湾义隆公司的产品,有很大一部分与PIC 8位单片机兼容,且相兼容产品的资源相对比PIC的多,价格便宜,有很多系列可选,但抗干扰较差. ATMEL单片机(51单片机): ATMEl公司的8位单片机有AT89、AT90两个系列,AT89系列是8位Flash单片机,与8051系列单片机相兼容,静态时钟模式;AT90系列单片机是增强RISC结构、全静态工作方式、内载在线可编程Flash的单片机,也叫AVR单片机. PHLIPIS 51LPC系列单片机(51单片机): PHILIPS公司的单片机是基于80C51内核的单片机,嵌入了掉电检测、模拟以及片内RC振荡器等功能,这使51LPC在高集成度、低成本、低功耗的应用设计中可以满足多方面的性能要求. HOLTEK单片机: 台湾盛扬半导体的单片机,价格便宜,种类较多,但抗干扰较差,适用于消费类产品. TI公司单片机(51单片机): 德州仪器提供了TMS370和MSP430两大系列通用单片机.TMS370系列单片机是8位CMOS单片机,具有多种存储模式、多种外围接口模式,适用于复杂的实时控制场合;MSP430系列单片机是一种超低功耗、功能集成度较高的16位低功耗单片机,特别适用于要求功耗低的场合 松翰单片机(SONIX): 是台湾松翰公司的单片,大多为8位机,有一部分与PIC 8位单片机兼容,价格便宜,系统时钟分频可选项较多,有PMW ADC 内振 内部杂讯滤波。缺点RAM空间过小,抗干扰较好。 三星单片机 三星单片机有KS51和KS57系列4位单片机,KS86和KS88系列8位单片机,KS17系列16位单片机和KS32系列32位单片机,三星还为ARM公司生产ARM单片机,常见的S344b0等.三星单片机为OTP型ISP在片编程功能. SST 单片机 美国SST公司推出的SST89系列单片机为标准的51系列单片机,包括SST89E/V52RD2, SST89E/V54RD2,SST89E/V58RD2,SST89E/V554RC,SST89E/V564RD等.它与8052系列单片机兼容.提供系统在线编程(ISP功能).内部flash擦写次数1万次以上,程序保存时间可达100年. 还有很多优秀的单片机生产企业这里没有收集,每个企业都有自己的特点,大家根据需要选择单片机,在完全实现功能的前提下追求低价位,当然并不是这样最好,实际中选择单片机跟开发者的应用习惯和开发经验是密不可分的。 单片机与嵌入式系统: 嵌入式系统源于计算机的嵌入式应用,早期嵌入式系统为通用计算机经改装后嵌入到对象体系中的各种电子系统,如舰船的自动驾驶仪,轮机监测系统等。嵌入式系统首先是一个计算机系统,其次它被嵌入到对象体系中、在对象体系中实现对象要求的数据采集、处理、状态显示、输出控制等功能,由于嵌入在对象体系中,嵌入式系统的计算机没有计算机的独立形式及功能。单片机完全是按照嵌入式系统要求设计的,因此单片机是最典型的嵌入式系统。早期的单片机只是按嵌入式应用技术要求设计的计算机单芯片集成,故名单片机。随后,单片机为满足嵌入式应用要求不断增强其控制功能与外围接口功能,尤其是突出控制功能,因此国际上已将单片机正名为微控制器(MCU,Microcontroller Unit)。

    时间:2018-05-02 关键词: 单片机 单片机开发

  • 单片机编程开发技巧经验分享

     工作了7个月之久,对单片机的编程也开始慢慢熟悉起来,以前总是知道单片机就是定时器,状态机,中断这些东西结合起来效率是相当高的,但是自从接手开发GPF这个芯片之后,我发现了另外一种单片机的开发技巧,高手请绕道。 我们都知道,在程序中,延时会影响单片机的实时性能,导致效率明显降低,但是在GPF这个芯片的开发中,系统延时和初始化被供应商做到了一块,所以调用程序,必须要做一定的loop才能使得程序能够正常的跑起来,其实我也不知道她们为什么要这么做。 在工作中,改一份源码不是随随便便就可以改的,当时做了这么一个程序,源码我就不公开了,写个案例解释: void test() { int i = 0 ; int tick ; int BatteryStatus = 0; int Voltage ; int count = 0 ; int Voltage_value ; char ch ; scanf("%d",&BatteryStatus); while(1) { delay_20ms(); switch(BatteryStatus) { case 1: if(count == 50) { printf("0x%x\n",0xE1); count = 0 ; };break ; case 2: if(count == 50) { printf("0x%x\n",0x90); //发通用'1'信号 count = 0 ; };break ; default: break ; } count++ ; #if 0 ch = getch(); //假设我在这设立一个按键 if(ch == 'q') { printf("%x",0x48); break ; } #endif } } 在while循环中,首先进去是延时20个ms,然后count计数器加加,当加到50次也就是一秒钟了,然后清零。此时若按下按键,不会受到干扰,程序正常运行,效率依然很高。如果这时候delay_20ms改成delay_1000ms,程序扫描按键每次就要等待1s钟,影响效率。计数值可以自我估计一下,不需要太准,这样的程序在延时不需要太精准的可以实现和定时器差不多一样的功能。

    时间:2018-04-27 关键词: 单片机 编程 单片机开发

  • MSP430单片机开发总结

    1.#i nclude<>指要在编辑器设定目录下,#i nclude""指的是在当前工程目录下。 2.要调用另一个文件中的函数,要把这个函数文件放到当前工程目录下,并且在工程中添加此文件。 3.命名中不能有-,比如:byq-ee会认为是错误的,要用下划线。 4.用IAR软件仿真时,可以加入变量,如果是查看I/O信息只需加入PXIN,PXOUT即可。 5.IAR在处理字符时,要注意,是字符处理结尾标志,他和其他编辑软件是不同的。比如我们长用字符处理会自动在结尾处加,但IAR有些是不加的,这就要十分注意。 6.如果只用到LFX1的低速时钟,9600bit/s传输的话,接收会出现问题,原因是误差太大,可以设置到4800以下。 7.在写FLASH时要注意其工作频率在257K~476k之间,如果不是,则会出现错误。而且FLAGH只能写入0,这样就出现了必须先擦除在写入的模式。 8.当IO口作为输入时,要根据平时的状态加电阻,平时为高时,加个上拉电阻,平时为低时加个下拉电阻以增加稳定性。 9.在FLASH写时一定要关外部中断。 10.MSP430一般是不要RC复位的,一般只要接个100K左右电阻就可以了,如果要加电容,它的大小要根据以下两个标准选择: 下载程序不会出现下载不了 程序上电会能稳定复位 11.用&表达式作为判断时,不要忘记加括号。 12.不要使用中断嵌套。同时,为了使用C语言来编写MSP430的高质量代码需要注意,微处理器一般用于特定环境和特定用途,出于成本、功耗和体积的考虑,一般都要求尽量节省使用资源,并且,由于微处理器硬件一般都不支持有符号数、浮点数的运算,且运算位有限,因此,分配变量时必须仔细。另外要说明的是,速度和存储器的消耗经常是2个不可兼顾的目标,在多数情况下,编程者必须根据实际情况作出权衡和取舍。需要注意的事项如下: 1) 通常在满足运算需求的前提下,尽量选择为变量定义字节少的数据类型。比如最常用的int和char,int是16位的,char是8位的,如果没有必要,不要使用int,而且使用char也最好使用unsigned char。运行时,可以在变量窗口看到,使用类型为unsigned char的变量是16进 制的格式,而使用int的是十进制格式,如果char没有定义为unsigned,会出现负号,如果没有必要的话,在430中是不需要负数的。 2) 尽量不用过长的数据类型,如long、long long和double 3) MSP430的C编译器不支持位寻址,所以运算中尽量减少位操作,对于只有“是”和“否”的变量,如果RAM容量允许,则可分配为unsigned char类型,可提高运算速度。如果分配为某字节的某个位,可以减少存储器的消耗,但是会降低运算速度 4) 避免使用浮点数,尽量使用定点数进行小数运算。如果必须使用浮点数,则尽量用32位的float,而不是64位的double 5) 尽量将变量分配为无符号数据类型 6) 对于指针变量,如果声明后其值不再改变,则声明为const类型,这样编译器编译时能更好的优化生成的代码 7) 尽可能的使用局部变量而非全局变量或者静态变量(static)。这样有利于编译器编译时更好的优化生成的代码 8) 避免对局部变量使用 &取地址符。因为这样会使编译器无法把此变量放在CPU的寄存器中,而是放在RAM中,从而失去了优化的机会 9) 仅在模块内使用的变量声明为static,有利于优化代码 10) 如果堆栈空间有限,尽量减少函数调用的层次和递归调用 11) 如果传送参数过多,可将参数组成一个数组或者结构体,然后用指针传递 12) 某些变量在中断程序和普通级别程序中都会被用到,所以必须加以保护。将变量声明为volatile类型,编译器优化时就不会移动它,对它的访问不会被延迟。为保证对volatile的变量不被打断,为此,可以在访问它的部分(即访问它的函数)前面加上__moniter的声明。

    时间:2013-09-05 关键词: msp 430 单片机开发

  • 关于51和AVR单片机开发的一些看法

    本人原来使用过的芯片有:AT89C51、2051、PIC16C711、16F84、LPC76X、ADuC812/834 但是看到AVR以后觉得AVR有不少优点: 1.带10位A/D,一般满足工业控制的基本要求; 2.带FLASH和EEPROM,特别是EEPROM,可以放逻辑炸弹,防止某些人用上了不付钱; 3.引脚少,没有外扩总线,抗干扰性能还可以; 4.开发容易,开发硬件成本低(我现在采用的是汇编语言,我不用C语言,C语言对于高速实时控制太慢了),采用汇编语言来说,写一个比较复杂的控制程序(比如大功率焊接设备SCR调压器控制器),连键显、PID、触发和保护一起,4K*16位足够了,就算开发很复杂的工控系统,16K*8位的ATmega16都绰绰有余,关键在于你的编程水平够不够; 5.加密性能比较好; 6.价格便宜,对于大功率工业控制的设备而言(至少1万元以上的),那点成本根本不算什么; 7.原来想采用uPD7810或者68HC11A8,开发系统的价格实在太高了,受不了,而且没有几天工夫你根本不可能使用它的。 所以,现在我还在用51,主要是软件仿真和专用仿真器一起上,AVR我用软件仿真,因为JTAG口实在太占用资源,而且修改程序不如ISP来得快捷方便。 AVR就是我现在想要的片子,基本功能全都有了,没有外部总线,被别人破解的可能性也远远比51小,PIC我实在看不惯它的分页,实在太讨厌了,AVR的工作温度范围也能很好满足我的工业控制要求,所以,现在在继续搞51的同时,学习AVR。 DSP对于真正的工业控制来说,除了空间矢量变换和复杂的信号解算,其余根本就是无用的东西,还浪费钱钱和国家资源:)而且加工不容易,量不大根本划不来,所以我不用320LF3407/2812、ARM等等。 看一种芯片是否有用,我认为主要看以下几点: 1.能不能满足市场对你的产品的要求; 2.成本比较低; 3.开发费用低;包括硬件成本和软件成本; 4.印刷板设计容易; 5.加密性能优良; 6.有一定的升级余地; 7.可以放逻辑炸弹(没办法,适合中国这种“欠钱的是老子,讨债的是孙子”国情); 8.引脚驱动能力大,可以尽量少的外扩器件; 9.开发语言可以很容易加入软件抗干扰,而且占用的代码资源少; 10.工作温度范围宽,电源适应能力强。 我不是开发火星车或者“神舟”号宇宙飞船,我最多只接触到军用电子设备中的一些简单的设备(可不是相控阵雷达火控系统或者声纳处理设备),所以根本用不着VXworks或者uC-OSII什么“花里胡哨”的东西,程序的移植其实对于一个好的汇编语言系统而言,只要你把程序模块化,仔细分配资源,并不难实现,但是,我现在倒还没看到哪位大虾能把C51直接移植到AVR上的,移植很多时候的意思是指对本系列芯片的兼容性而言,可不是对于不同MCU而言的,可能以后会统一,但是现在至少还没统一,所以忍忍吧,呵呵。而且对于一个自己的公司来说,比如说你原来是做手机的充电器,而现在突然要你去做250KW的大功率焊接设备,好像没有3年5载的你是根本入不了门的,更别说赚钱了,开公司的或者给公司打工的,如果什么都做,那肯定什么都不能做到最好,就像中国的海尔电器。 所以,我现在依然使用汇编语言,依然不用C语言,依然搞大功率电子设备控制,虽然开发速度慢一些(比C语言),但是至少不会让用户把我发的货退掉了,这就是市场生存法则,不是学术骗子们的生存法则。 扩展阅读:AVR,C51和PIC八位单片机性能比较

    时间:2013-02-22 关键词: AVR 单片机开发

  • PIC单片机开发的一些问题

    由美国Microchip公司生产的PIC系列单片机,由于其超小型、低功耗、低成本、多品种等特点,已广泛应用于工业控制、仪器、仪表、通信、家电、玩具等领域,本文总结了作者在PIC单片机开发过程中的一些经验、技巧,供同行参考。 1 怎样进一步降低功耗 功耗,在电池供电的仪器仪表中是一个重要的考虑因素。PIC16C××系列单片机本身的功耗较低(在5V,4MHz振荡频率时工作电流小于2mA)。为进一步降低功耗,在保证满足工作要求的前提下,可采用降低工作频率的方法,工作频率的下降可大大降低功耗(如PIC16C××在3V,32kHz下工作,其电流可减小到15μA),但较低的工作频率可能导致部分子程序(如数学计算)需占用较多的时间。在这种情况下,当单片机的振荡方式采用RC电路形式时,可以采用中途提高工作频率的办法来解决。 具体做法是在闲置的一个I/O脚(如RB1)和OSC1管脚之间跨接一电阻(R1),如图1所示。低速状态置RB1=0。需进行快速运算时先置RB1=1,由于充电时,电容电压上升得快,工作频率增高,运算时间减少,运算结束又置RB1=0,进入低速、低功耗状态。工作频率的变化量依R1的阻值而定(注意R1不能选得太小,以防振荡电路不起振,一般选取大于5kΩ)。 另外,进一步降低功耗可充分利用“sleep”指令。执行“sleep”指令,机器处于睡眠状态,功耗为几个微安。程序不仅可在待命状态使用“sleep”指令来等待事件,也可在延时程序里使用(见例1、例2)。在延时程序中使用“sleep”指令降低功耗是一个方面,同时,即使是关中断状态,Port B端口电平的变化可唤醒“sleep”,提前结束延时程序。这一点在一些应用场合特别有用。同时注意在使用“sleep”时要处理好与WDT、中断的关系。   图1 提高工作频率的方法 例1(用Mplab-C编写) 例2(用Masm编写) Delay() Delay { ;此行可加开关中断指令 /*此行可加开关中断指令*/ movlw.10 for (i=0; i<=10; i++) movwf Counter SLEEP(); Loop1 } Sleep decfsz Counter goto Loop1 return 2 注意INTCON中的RBIF位 INTCON中的各中断允许位对中断状态位并无影响。当PORT B配置成输入方式时,RB<7:4>引脚输入在每个读操作周期被抽样并与旧的锁存值比较,一旦不同就产生一个高电平,置RBIF=1。在开RB中断前,也许RBIF已置“1”,所以在开RB中断时应先清RBIF位,以免受RBIF原值的影响,同时在中断处理完成后最好是清RBIF位。 3 用Mplab-C高级语言写PIC单片机程序时要注意的问题 3.1 程序中嵌入汇编指令时注意书写格式 见例3。 例3 …… …… while(1) {#asm while(1) { …… #asm /*应另起一行*/ #endasm …… }/*不能正确编译*/ #endasm …… }/*编译通过*/ …… 当内嵌汇编指令时,从“#asm”到“endasm”每条指令都必须各占一行,否则编译时会出错。 3.2 加法、乘法的最安全的表示方法 见例4。 例4 #include<16c71.h> #include unsigned int a, b; unsigned long c; void main() { a=200; b=2; c=a*b; } /*得不到正确的结果c=400*/ 原因是Mplab-C以8×8乘法方式来编译c=a*b,返回单字节结果给c,结果的溢出被忽略。改上例中的“c=a*b;”表达式为“c=a;c=c*b;”,最为安全(对加法的处理同上)。 3.3 了解乘除法函数对寄存器的占用 由于PIC单片机片内RAM仅几十个字节,空间特别宝贵,而Mplab-C编译器对RAM地址具有不释放性,即一个变量使用的地址不能再分配给其它变量。如RAM空间不能满足太多变量的要求,一些变量只能由用户强制分配相同的RAM空间交替使用。而Mplab-C中的乘除法函数需借用RAM空间来存放中间结果,所以如果乘除法函数占用的RAM与用户变量的地址重叠时,就会导致出现不可预测的结果。如果C程序中用到乘除法运算,最好先通过程序机器码的反汇编代码(包含在生成的LST文件中)查看乘除法占用地址是否与其它变量地址有冲突,以免程序跑飞。Mplab-C手册并没有给出其乘除法函数对具体RAM地址的占用情况。例5是乘法函数对0×13、0×14、0×19、0×1A地址占用情况。 例5 部分反汇编代码 #include 01A7 081F MOVF 1F,W #include 01A8 0093 MOVWF 13 ;借用 unsigned long Value @0x1 01A9 0820 MOVF 20,W char Xm @0x2d; 01AA 0094 MOVWF 14 ;借用 void main() 01AB 082D MOVF 2D,W {Value=20; 01AC 0099 MOVWF 19 ;借用 Xm=40; 01AD 019A CLRF1A ;借用 Value=Value*Xm 01AE 235F CALL 035Fh ;调用乘法函数 …… 01AF 1283 BCF 03,5 } 01B0 009F MOVWF 1F ;返回结果低字节 01B1 0804 MOVF 04,W 01B2 00A0 MOVWF 20 ;返回结果高字节 4 对PIC单片机芯片重复编程 对无硬件仿真器的用户,总是选用带EPROM的芯片来调试程序。每更改一次程序,都是将原来的内容先擦除,再编程,其过程浪费了相当多的时间,又缩短了芯片的使用寿命。如果后一次编程的结果较前一次,仅是对应的机器码字节的相同位由“1”变成“0”,就可在前一次编程芯片上再次写入数据,而不必擦除原片内容。 在程序的调试过程中,经常遇到常数的调整,如常数的改变能保证对应位由“1”变“0”,都可在原片内容的基础继续编程。另外,由于指令“NOP”对应的机器码为“00”,调试过程中指令的删除,先用“NOP”指令替代,编译后也可在原片内容上继续编程。 另外,在对带EPROM的芯片编程时,特别注意程序保密状态位。厂家对新一代带EPROM芯片的保密状态位已由原来的EPROM可擦型改为了熔丝型,一旦程序代码保密熔丝编程为“0”,可重复编程的 EPROM 芯片就无法再次编程了。使用时应注意这点,以免造成不必要的浪费(Microchip 资料并未对此做出说明)。

    时间:2012-12-19 关键词: pic 单片机开发

  • 单片机开发中应掌握的基本技巧

    在单片机应用开发中,代码的使用效率问题、单片机抗干扰性和可靠性等问题仍困扰着 工程师。为帮助工程师解决单片机设计上的难题,《电子工程专辑》网站特邀Holtek香 港分公司工程部处长邓宏杰先生担任《单片机应用编程技巧》专题讨论的嘉宾,与广大 设计工程师交流单片机设计开发经验。现根据论坛中的讨论归纳出单片机开发中应掌握 的几个基本技巧。 一、 如何提高C语言编程代码的效率 邓宏杰指出,用C语言进行单片机程序设计是单片机开发与应用的必然趋势。他强调:“ 如果使用C编程时,要达到最高的效率,最好熟悉所使用的C编译器。先试验一下每条C语 言编译以后对应的汇编语言的语句行数,这样就可以很明确的知道效率。在今后编程的 时候,使用编译效率最高的语句。” 他指出,各家的C编译器都会有一定的差异,故编译效率也会有所不同,优秀的嵌入式系 统C编译器代码长度和执行时间仅比以汇编语言编写的同样功能程度长5-20%。他说:“ 对于复杂而开发时间紧的项目时,可以采用C语言,但前提是要求你对该MCU系统的C语言 和C编译器非常熟悉,特别要注意该C编译系统所能支持的数据类型和算法。虽然C语言是 最普遍的一种高级语言,但由于不同的MCU厂家其C语言编译系统是有所差别的,特别是 在一些特殊功能模块的操作上。所以如果对这些特性不了解,那么调试起来问题就会很 多,反而导致执行效率低于汇编语言。” 二、 如何减少程序中的bug? 对于如何减少程序的bug,邓宏杰给出了一些建议,他指出系统运行中应考虑的超范围管 理参数有: 1.物理参数。这些参数主要是系统的输入参数,它包括激励参数、采集处理中的运行参 数和处理结束的结果参数。合理设定这些边界,将超出边界的参数都视为非正常激励或 非正常回应进行出错处理。 2.资源参数。这些参数主要是系统中的电路、器件、功能单元的资源,如记忆体容量、 存储单元长度、堆叠深度。在程式设计中,对资源参数不允许超范围使用。 3.应用参数。这些应用参数常表现为一些单片机、功能单元的应用条件。如E2PROM的擦 写次数与资料存储时间等应用参数界限。 4.过程参数。指系统运行中的有序变化的参数。   三、如何解决单片机的抗干扰性问题 邓宏杰指出:防止干扰最有效的方法是去除干扰源、隔断干扰路径,但往往很难做到, 所以只能看单片机抗干扰能力够不够强了。单片机干扰最常见的现象就是复位;至于程 序跑飞,其实也可以用软件陷阱和看门狗将程序拉回到复位状态;所以单片机软件抗干 扰最重要的是处理好复位状态。 一般单片机都会有一些标志寄存器,可以用来判断复位原因;另外你也可以自己在RAM中 埋一些标志。在每次程序复位时,通过判断这些标志,可以判断出不同的复位原因;还 可以根据不同的标志直接跳到相应的程序。这样可以使程序运行有连续性,用户在使用 时也不会察觉到程序被重新复位过。 四、 如何测试单片机系统的可靠性 有读者希望了解用用什么方法来测试单片机系统的可靠性,邓宏杰指出:“当一个单片 机系统设计完成,对于不同的单片机系统产品会有不同的测试项目和方法,但是有一些 是必须测试的: 1.测试单片机软件功能的完善性。这是针对所有单片机系统功能的测试,测试软件是否 写的正确完整。 2.上电、掉电测试。在使用中用户必然会遇到上电和掉电的情况,可以进行多次开关电 源,测试单片机系统的可靠性。 3.老化测试。测试长时间工作情况下,单片机系统的可靠性。必要的话可以放置在高温 ,高压以及强电磁干扰的环境下测试。 4、ESD和EFT等测试。可以使用各种干扰模拟器来测试单片机系统的可靠性。例如使用静 电模拟器测试单片机系统的抗静电ESD能力;使用突波杂讯模拟器进行快速脉冲抗干扰E FT测试等等。 邓宏杰强调:“还可以模拟人为使用中,可能发生的破坏情况。例如用人体或者衣服织 物故意摩擦单片机系统的接触端口,由此测试抗静电的能力。用大功率电钻靠近单片机 系统工作,由此测试抗电磁干扰能力等。”  

    时间:2012-08-18 关键词: 基本技巧 单片机开发

  • 单片机开发中的基本技巧简介

      在单片机应用开发中,代码的使用效率问题、单片机抗干扰性和可靠性等问题仍困扰着 工程师。为帮助工程师解决单片机设计上的难题,《电子工程专辑》网站特邀Holtek香 港分公司工程部处长邓宏杰先生担任《单片机应用编程技巧》专题讨论的嘉宾,与广大 设计工程师交流单片机设计开发经验。现根据论坛中的讨论归纳出单片机开发中应掌握 的几个基本技巧。 一、 如何提高C语言编程代码的效率 邓宏杰指出,用C语言进行单片机程序设计是单片机开发与应用的必然趋势。他强调:“ 如果使用C编程时,要达到最高的效率,最好熟悉所使用的C编译器。先试验一下每条C语 言编译以后对应的汇编语言的语句行数,这样就可以很明确的知道效率。在今后编程的 时候,使用编译效率最高的语句。” 他指出,各家的C编译器都会有一定的差异,故编译效率也会有所不同,优秀的嵌入式系 统C编译器代码长度和执行时间仅比以汇编语言编写的同样功能程度长5-20%。他说:“ 对于复杂而开发时间紧的项目时,可以采用C语言,但前提是要求你对该MCU系统的C语言 和C编译器非常熟悉,特别要注意该C编译系统所能支持的数据类型和算法。虽然C语言是 最普遍的一种高级语言,但由于不同的MCU厂家其C语言编译系统是有所差别的,特别是 在一些特殊功能模块的操作上。所以如果对这些特性不了解,那么调试起来问题就会很 多,反而导致执行效率低于汇编语言。” 二、 如何减少程序中的bug? 对于如何减少程序的bug,邓宏杰给出了一些建议,他指出系统运行中应考虑的超范围管 理参数有: 1.物理参数。这些参数主要是系统的输入参数,它包括激励参数、采集处理中的运行参 数和处理结束的结果参数。合理设定这些边界,将超出边界的参数都视为非正常激励或 非正常回应进行出错处理。 2.资源参数。这些参数主要是系统中的电路、器件、功能单元的资源,如记忆体容量、 存储单元长度、堆叠深度。在程式设计中,对资源参数不允许超范围使用。 3.应用参数。这些应用参数常表现为一些单片机、功能单元的应用条件。如E2PROM的擦 写次数与资料存储时间等应用参数界限。 4.过程参数。指系统运行中的有序变化的参数。      三、如何解决单片机的抗干扰性问题 邓宏杰指出:防止干扰最有效的方法是去除干扰源、隔断干扰路径,但往往很难做到, 所以只能看单片机抗干扰能力够不够强了。单片机干扰最常见的现象就是复位;至于程 序跑飞,其实也可以用软件陷阱和看门狗将程序拉回到复位状态;所以单片机软件抗干 扰最重要的是处理好复位状态。 一般单片机都会有一些标志寄存器,可以用来判断复位原因;另外你也可以自己在RAM中 埋一些标志。在每次程序复位时,通过判断这些标志,可以判断出不同的复位原因;还 可以根据不同的标志直接跳到相应的程序。这样可以使程序运行有连续性,用户在使用 时也不会察觉到程序被重新复位过。 四、 如何测试单片机系统的可靠性 有读者希望了解用用什么方法来测试单片机系统的可靠性,邓宏杰指出:“当一个单片 机系统设计完成,对于不同的单片机系统产品会有不同的测试项目和方法,但是有一些 是必须测试的: 1.测试单片机软件功能的完善性。这是针对所有单片机系统功能的测试,测试软件是否 写的正确完整。 2.上电、掉电测试。在使用中用户必然会遇到上电和掉电的情况,可以进行多次开关电 源,测试单片机系统的可靠性。 3.老化测试。测试长时间工作情况下,单片机系统的可靠性。必要的话可以放置在高温 ,高压以及强电磁干扰的环境下测试。 4、ESD和EFT等测试。可以使用各种干扰模拟器来测试单片机系统的可靠性。例如使用静 电模拟器测试单片机系统的抗静电ESD能力;使用突波杂讯模拟器进行快速脉冲抗干扰E FT测试等等。 邓宏杰强调:“还可以模拟人为使用中,可能发生的破坏情况。例如用人体或者衣服织 物故意摩擦单片机系统的接触端口,由此测试抗静电的能力。用大功率电钻靠近单片机 系统工作,由此测试抗电磁干扰能力等。”

    时间:2012-07-18 关键词: 基本技巧 单片机开发

首页  上一页  1 2 下一页 尾页
发布文章

技术子站

更多

项目外包