tag 标签: Keil

相关帖子
相关博文
  • 热度 8
    2020-2-13 15:24
    2404 次阅读|
    1 个评论
    工作之后用的最多的51单片机AT89C2051 (2)
    最近的工作主要内容是写文件,准确的说是修改文件,真的很。。。 单位文件挺乱的,关键是制度流程乱,没啥可操作性,也没培训。。。全靠个人水平编。。。 再来一个没看出有啥水平的老巫婆河东狮吼。。。 我就奇怪了,领导们就没一个实实在在能解决问题吗?还是都坏掉了? ---------------------------------------------------------------------------------------------- 说正题,AT89C2051的比较器,官网手册里,特性 On-chip Analog Comparator,片上模拟比较器 然后有框图 输入连的是P1.0、P1.1,输出连的是P3.6 然后有具体描述 P1.0、P1.1要外部上拉电阻,要写1 英文自己看哈。。。不要懒 程序挺简单的 P3.7是一个工作指示灯 P1.7也是一个指示灯,用来指示比较结果 ~~~~~~~~~~~~~~~ 没有试过比较器的精度,个人觉得,做个简单的电量指示还是可以的 AT89C2051手册的页数挺少的,也许可以参考C51的看看 ~~~~~~~~~~~~~~~ DIP-20的AT89C2051,是用下载器离线下载程序的的,用着很麻烦,而且连底座一起高度太高了 虽然,今天再看手册,发现还有个SOIC的矮很多,但是,个人觉得下载程序用的引脚太多,留插座也很占地方,还得做转接线 所以,准备换掉 看上了AT89LP4052,但是一年了一直没有时间买来试,还得先打听好买不,会不会断货等等,好多麻烦事。。。 朋友们,有其他型号推荐吗?
  • 热度 3
    2019-6-26 16:22
    6218 次阅读|
    3 个评论
    【零基础】入门51单片机图文教程(Proteus+Keil)
    参考资料: https://www.jianshu.com/p/88dfc09e7403 https://blog.csdn.net/feit2417/article/details/80890218 零、前言   我一直认为看资料还不如先动手试试,在“做”的过程中“学”,先打下基础、建立兴趣,再戒骄戒躁好好看看书,搞明白一些常识。但是网上的教程往往都比较片面,要么给几张图、几段代码就算完事了,环境如何安装、细节小问题是怎么回事都讲的不是很详细,所以这篇文章就是要把每一步都讲的详细了,真正0基础也能看得懂、学的会,不用再去搜其他资料,真的手把手也就这个效果了。 一、准备    1 硬件: 需要有一台电脑,笔记本、台式机都行    2 环境: 请使用官方原版(不要用ghost、精简系统)的XP或WIN7,很多莫名其妙的问题都是缺少一些dll文件,所以一定要用官方原版的系统,若不想重装电脑可以使用VMware安装虚拟机。另外尽量使用32位的系统,毕竟这些软件都比较老了    3 软件:     1) Proteus 8.4 SP0          下载地址:http://www.ddooo.com/softdown/26979.htm 注意看破解方法,其中针对WIN7 X64有部分有误的地方:       1)第七步:正确路径可能是“C:\Program Files(x86)\Labcenter Electronics\Proteus 8 Professional”,将破解包中的BIN目录覆盖到这里即可       2)第八步:正确路径可能是“C:\ProgramData\Labcenter Electronics\Proteus 8 Professional”,将破解包中的MODELS目录覆盖到这里即可       (不要修改默认安装位置,找不到正确路径的话可以搜索下“Proteus 8 Professional”这个关键词)     2) Proteus 8.4 汉化包          下载地址:本文末尾处     3) Keil 5               下载地址:http://www.ddooo.com/softdown/79273.htm 需要注意的是:       1)使用注册机生成注册码时,因为现在Keil 5是针对ARM的所以在注册机的Target栏需选择为ARM而不是C51     4) Keil 5 C51依赖包          下载地址:https://share.weiyun.com/5WSwsJv(密码:0000)       (Keil 5是默认不支持51单片机的,但是可以通过依赖包实现,安装和使用方法:https://blog.csdn.net/feit2417/article/details/80890218)    4 安装: 按下载页面的方法安装好,如果安装过程中有什么问题,一定要注意你操作系统的版本,以及是否是原生系统 二、在proteus绘制硬件电路   这里我们只实现最简单的功能:点亮一个LED灯    1、打开proteus,点击首页的“新建工程”新建一个项目    2、在新建工程向导里依次操作如下:   1)输入项目名称、选择项目存储位置   2)原理图:DEFAULT   3)PCB布板设计:不创建   4)固件:没有固件的项目   5)点击“完成”按钮完成新项目的创建    3、在电路图中放置我们需要的三个器件:51单片机、LED灯、电源并连线   1)51单片机   在界面中点击“P”(P和L代表的是元件模式)   在元器件选择窗口中输入51单片机的型号进行搜索,关键字“C52”(51单片机的常用型号是AT89C52)。   选择需要的型号后点击右下角的“确认”按钮,然后将其放置到电路图中即可   2)LED   重复前面的操作,关键字改为“LED”即可,这里选择的是“LED-YELLOW”,将LED放到单片机旁边   3)电源   电源在界面左侧选择“终端模式”,然后找到POWER这个元件即是电源。将电源也拖到单片机旁边   4)连接电路   使用鼠标将LED一端与电源连接,另一端连接单片机的P0.1,要注意LED的方向不要接反了。 三、Keil编写控制代码    1、启动Keil   2、新建项目 New μVersion Project”   2)输入项目名称   3)在新窗口中Search关键字“C51”,找到Atmel下的AT89C51,点击OK按钮完成项目创建    3、添加代码文件   1)右键“Source Group 1”   2)点击下图中画红线的地方   3)新弹出的窗口中选择C File,Name栏输入“main”   4)在main.c中输入下述代码,然后保存(画红圈的地方)    4、生成HEX文件(单片机运行使用的文件格式)   1)右键左侧的Target按钮,选择Opention for Target 'Target 1'   2)新弹出的窗口中选择Output选项卡,把“Creat HEX File”勾上,点击OK按钮即可(这一步是设置程序编译时要输出HEX文件)   3)点击下图画红线的按钮,编译程序,注意下侧“Build Output”栏是否有提示错误,输出 0 Error即是OK了   4)找到生成的HEX文件备用(在项目目录下的Objects目录内) 四、Proteus仿真运行    1、导入HEX文件   1)再次打开Proteus,右键单片机,点击“编辑属性”按钮   2)新窗口中点击“Program File”会弹出寻找HEX文件的小窗口,找到前面生成的HEX文件    2、点击Proteus左下角的启动按钮,开始仿真    3、运行结果:LED灯被点亮啦! 五、思考   1、为什么代码中LED=0,电源要加在LED的一侧   实际上,代码中LED=1,电路中LED旋转180度,LED一侧接地而不是电源也可以将LED点亮。但一般不这么做,因为单片机启动时会进行初始化,初始化过程中各引脚会出现瞬间的通电、断电,如果LED一侧不接电源而接地,单片机初始化时会导致LED闪烁。   2、代码中引用的reg52.h是什么文件   C语言中.h是头文件,reg52.h是51单片机的通用头文件,里面是单片机的寄存器声明 六、相关资料   看完本文你就已经学会了如何使用Proteus+Keil进行51单片机的开发啦!不过这只是最最基础的内容,后面进阶的学习还需要你多多动手,不过毛大闲已经为你准备了后续学习的必备资料。   关注公众号 “零基础爱学习”回复“51” 可获得下面的资料    1、本文所述的Proteus8安装包、Proteus8汉化包、Keil5安装包、Keil5 C51支持包   2、上述软件安装方法的PDF文档   3、Proteus8中文使用手册   4、AT89C52中文说明书   5、51单片机入门实例(仿真电路图+C代码)   后续还会继续补充更多学习资料,敬请关注“ 零基础爱学习 ”!
  • 热度 3
    2019-5-10 16:04
    27678 次阅读|
    4 个评论
    前言 IAP(In-application-programming),即在应用中编程。当产品发布之后,可以通过网络方便的升级固件程序,而不需要拆机下载程序。IAP系统的固件一般由两部分组成,即BootLoader Code和Application Code,并存储在不同起始地址的空间里: 系统运行时,先运行Bootloader程序,检测状态,判断是执行应用程序还是升级固件。在实际开发过程中,这两段程序一般是单独编写,然后生成两个Bin文件,为了方便下载程序,可以把两个文件合并为一个文件,这样会节省很多时间。本文将介绍如何使用JFlash来合并两个Bin文件或者两个Hex文件, 准备 要合并的文件1:bootloader.hex,起始地址:0x8000000 要合并的文件2:app.hex,起始地址:0x20001000,如果是Bin文件要先确定起始地址。 JFlash软件 创建工程 和之前下载程序一样,首先要新建一个工程。 1.打开JFlash 2.创建新工程 NewProject 3.选择芯片的型号 这里支持很多ARM Cortex内核的芯片,选择对应的芯片,我这里选择的是STM32F103RE系列。 4.打开要合并的程序文件1:bootloader.hex Open data file,打开bootloader程序。 5.打开要合并的程序文件2:app.hex Merge data file,打开app程序。 要保证,bootloader程序起始地址+bootloader代码大小不超过app程序的起始地址,如下图示意: 6.保存合并后的文件 Save data file as,将合并后的文件另存,可根据需要选择要保存的文件类型。 注意 如果要合并的文件为bin文件,自身不带地址信息,所以会让你指定地址,注意不要互相重叠地址。所以最好各种文件生成的时候就保存为带地址信息的格式,比如hex。关于Hex文件和Bin文件的区别,可以参考文章: BIN、HEX、AXF、ELF文件格式有什么区别 JLink软件的下载 JLink_Windows_V614b软件下载链接: JLink_Windows_V614b.exe(https://wcc-blog.oss-cn-beijing.aliyuncs.com/BlogFile/JLink_Windows_V614b.exe)
  • 热度 1
    2015-9-6 18:12
    384 次阅读|
    0 个评论
    Keil C51总线外设操作问题的深入分析 1问题回顾和分析 在实际工作中遇到对同一端口反复连续读取,Keil C51编译并未达到预期的结果。对C编译出来的汇编程序进行分析发现,对同一端口的第二次读取语句并未被编译。 对此问题,翻阅Keil C51的手册很容易发现:KeilC51的编译器有一个优化设置,不同的优化设置,会产生不同的编译结果。一般情况缺省编译优化设置被设定为8级优化,实际最高可设定为9级优化: 1. Dead code elimination。 2.Data overlaying。 3.Peephole optimization。 4.Register variables。 5.Common subexpression elimination。 6.Loop rotation。 7.Extended Index Access Optimizing。 8.Reuse Common Entry Code。 9.Common Block Subroutines。 而以上的问题,正是由于Keil C51编译优化产生的。因为在原文程序中将外设地址直接按如下定义: unsigned char xdata MAX197 _at_ 0x8000 采用_at_将变量MAX197定义到外部扩展RAM指定地址0x8000。因此,Keil C51优化编译理所当然认为重复读第二次是没有用的,直接用第一次读取的结果就可以了,因此编译器跳过了第二条读取语句。至此,问题就一目了然了。 2解决方法 由以上分析很容易就能提出很好的解决办法。 2.1最简单最直接的办法 程序一点都不用修改,将Keil C51的编译优化选择设置为0(不优化)就可以了。选择project窗口的Target,然后打开“Options for Target”设置对话框,选择“C51”选项卡,将“Code Optimiztaion”中的“Level”选择为“0:Costant folding”。再次编译后,大家会发现编译结果为: CLR MAXHBEN MOV DPTR,#MAX197 MOVX A,@DPTR MOV R7,A MOV down8,R7 SETB MAXHBEN MOV DPTR,#MAX197 MOVX A,@DPTR MOV R7,A MOV up4,R7 两次读取操作都被编译出来了。 2.2最好的方法 告诉Keil C51,这个地址不是一般的扩展RAM,而是连接的设备,具有“挥发”特性,每次读取都是有意义的。可以修改变量定义,增加“volatile”关键字说明其特征: unsigned char volatile xdata MAX197 _at_ 0x8000; 也可以在程序中包含系统头文件;“#includeabsacc.h”,然后在程序中修改变量,定义为直接地址: #define MAX197 XBYTE 这样,Keil C51的设置仍然可以保留高级优化,且编译结果中,同样两次读取并不会被优化跳过。 2 .3硬件解决方法 原文中将MAX197的数据直接连接到数据总线,而对地址总线并未使用,采用一根端口线选择操作高低字节。很简单的修改方法就是使用一根地址线选择操作高低字节即可。比如:将P2.0(A8)连接到原来P1.0连接的HBEN脚(MAX197的5脚).在程序中分别定义高低字节的操作地址: unsigned char volatile xdata MAX197_L _at_ 0x8000; unsigned char volatile xdata MAX197_H _at_ 0x8100; 将原来的程序: MAXHBEN =0; down8=MAX197;//读取低8位 MAXHBEN =1; up4=MAX197;//读取高4位 改为以下两句即可 down8= MAX197_L;//读取低8位 up4=MAX197_H;//读取高4位 3小结 Keil C51经过长期考验和改进以及大量开发人员的实际使用,已经克服了绝大多数的问题,并且其编译效率也非常高。对于一般的使用.很难再发现什么问题。笔者曾经粗略研究过一下Keil C51优化编洋的结果.非常佩服Keil C51设计者的智慧,一些C程序编译产生的汇编代码.甚至比一般程序员直接用汇编编写的代码还要优秀和简练通过研读Kell C51编译产生的汇编代码.对提高汇编语言编写程序的水平都是很有帮助的。 由本文中的问题可以看出:在设计中遇到问题时.一定不要被表面现象蒙蔽,不要急于解决,应该认真分析,找出问题的原因.这样才能从根本上彻底解决问题。 转自畅学电子网。
  • 2013-10-10 00:42
    2994 次阅读|
    0 个评论
      移植过程基于 STM32 标准外设库,在库内提供的例程基础上,将 FreeRTOS 移植进去。     相关资源:   1.STM32 标准外设库 V3.5.0 ( 直接下载地址 http://www.st.com/st-web-ui/static/active/en/st_prod_software_internet/resource/technical/software/firmware/stsw-stm32054.zip )。   2.FreeRTOS V7.5.2 ( 直接下载地址 http://jaist.dl.sourceforge.net/project/freertos/FreeRTOS/V7.5.2/FreeRTOSV7.5.2.zip )。   3.FreeRTOS Real Time Kernel (RTOS) 最新版本下载地址( http://sourceforge.net/projects/freertos/files/ )。   4.STM32F10x standard peripheral library 最新相关信息地址( http://www.st.com/web/cn/catalog/tools/FM147/CL1794/SC961/SS1743/PF257890 )。     移植过程:   以下以 STM32F103VCT6 为例进行移植,其他型号类似。   解压 FreeRTOS,打开关于 STM32F103 的例程(Keil版本),目录“..\FreeRTOSV7.5.2\FreeRTOS\Demo\CORTEX_STM32F103_Keil”。   解压 STM32 标准外设库,进入工程模板目录“..\STM32F10x_StdPeriph_Lib_V3.5.0\Project”,复制“STM32F10x_StdPeriph_Template”并根据项目重命名。进入目录“..\STM32F10x_StdPeriph_Lib_V3.5.0\Project\ProjectRoot\MDK-ARM” 下打开工程文件,对应STM32F103VCT6,选择“STM3210E-EVAL”。   目录“..\STM32F10x_StdPeriph_Lib_V3.5.0\Project\ProjectRoot\” (以下用..\ProjectRoot\表示)下新建“FreeRTOS”文件夹,拷贝Source(直接copy FreeRTOS源码Source目录)、Common(直接copy FreeRTOS源码\demo\Common目录)到”..\ProjectRoot\FreeRTOS\”下。   在Source/portable目录下,保留RVDS和MemMang目录,其余删除。复制 FreeRTOS目录\Demo\CORTEX_STM32F103_Keil\FreeRTOSConfig.h 到 ..\ProjectRoot\ 下。   在 MDK-ARM 中进行设置: Target options -Device中,选择STM32F103VC。 Target options - C/C++ 中 Preprocessor Symbols 中 Include path 设定头文件路径: ..\ ..\..\..\Libraries\CMSIS\CM3\CoreSupport ..\..\..\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x ..\..\..\Libraries\STM32F10x_StdPeriph_Driver\inc ..\..\..\Utilities\STM32_EVAL ..\..\..\Utilities\STM32_EVAL\Common ..\..\..\Utilities\STM32_EVAL\STM3210E_EVAL ..\FreeRTOS\Source\include ..\FreeRTOS\Source\portable\RVDS\ARM_CM3 ..\FreeRTOS\Common\include   复制 Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm\startup_stm32f10x_hd.s 至 ..\ProjectRoot\ 。若使用其他容量器件,请自行选择对应的startup files。   参照 FreeRTOS 中的 STM32F10x.s 修改startup_stm32f10x_hd.s 在 __heap_limit 区段添加: IMPORT xPortPendSVHandler IMPORT xPortSysTickHandler IMPORT vPortSVCHandler ;IMPORT vUARTInterruptHandler ;IMPORT vTimer2IntHandler 后两个不要添加,因为这不是 FreeRTOS 核心代码,是他demo用到的。   __Vectors区段中断向量表,将SVCall Handler、PendSV_Handler、SysTick Handler更名,改由 RTOS 管理,这样 stm32f10x_it.c 就不会影响到这三个中断。后面相应的中断入口地址需要更改 DCD     vPortSVCHandler           ; SVCall Handler ... DCD     xPortPendSVHandler        ; PendSV Handler DCD     xPortSysTickHandler       ; SysTick Handler 两者还有一点小小的不同,复位时进入main函数之前的那段代码,新版本外设库的启动代码中,在进入main()函数之前执行函数SystemInit()初始化了时钟,这个根据目标板不同,注意此段代码。   使用修改后的 startup_stm32f10x_hd.s 替换MDK-ARM组下的同名文件。参照 FreeRTOS 例程在 STM32 的外设库例程中加入 FreeRTOS 组,并加入文件: tasks.c、list.c、queue.c、port.c、heap_2.c,截图如下。     至此,设定完成,修改 main.c 文件,内容如下。需根据使用的开发板修改相关外设设置。因为 FreeRTOS 使用 configTOTAL_HEAP_SIZE 为 0x4400,IRAM的 SIZE 需超过 0x4400(17K),所以选择STM32要注意RAM大小是否满足。 /* main.c */ /* Standard includes. */ #include stdio.h   /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "misc.h"     /* Library includes. */ #include "stm32f10x_it.h" #include "stm32f10x_rcc.h" #include "stm32f10x_gpio.h" #include "stm32f10x_usart.h"   #define LED0_ON()   GPIO_ResetBits(GPIOA,GPIO_Pin_8); #define LED0_OFF()  GPIO_SetBits(GPIOA,GPIO_Pin_8); #define LED0B()     GPIOA-ODR ^= 0x0100;   #define LED1_ON()   GPIO_ResetBits(GPIOD,GPIO_Pin_2); #define LED1_OFF()  GPIO_SetBits(GPIOD,GPIO_Pin_2); #define LED1B()     GPIOD-ODR ^= 0x04;   static void prvSetupHardware( void );   /* Two demo Tasks*/       static void vLEDTask( void *pvParameters ); static void vCOMMTask( void *pvParameters );   void Led_Init(void); void Comm_Init(void);   int main( void ) {     prvSetupHardware();       xTaskCreate( vLEDTask, ( signed portCHAR * ) "LED", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+3, NULL );     xTaskCreate( vCOMMTask, ( signed portCHAR * ) "COMM", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+2, NULL );       /* Start the scheduler. */     vTaskStartScheduler();             return 0; } /*-----------------------------------------------------------*/   void vLEDTask( void *pvParameters ) {     Led_Init();     LED0_ON();     LED1_OFF()       for( ;; )     {           LED0B();           LED1B();         vTaskDelay( 100 / portTICK_RATE_MS);     } }   void vCOMMTask( void *pvParameters ) {     Comm_Init();     for(;;)     {         USART_SendData(USART1, '@');         vTaskDelay(1000 / portTICK_RATE_MS);     } } /*-----------------------------------------------------------*/   static void prvSetupHardware( void ) {     SystemInit(); } /*-----------------------------------------------------------*/   void Led_Init(void) {     GPIO_InitTypeDef GPIO_InitStructure;         RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOD, ENABLE );       /*LED0 @ PA8*/     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     GPIO_Init( GPIOA, GPIO_InitStructure );          /*LED0 @ PD2*/     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     GPIO_Init( GPIOD, GPIO_InitStructure );      }   void Comm_Init(void) {     USART_InitTypeDef USART_InitStructure;     GPIO_InitTypeDef GPIO_InitStructure;     NVIC_InitTypeDef NVIC_InitStructure;       RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);        /*UART1 TX @ PA9*/     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     GPIO_Init( GPIOA, GPIO_InitStructure );            /*UART1 RX @ PA10*/     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;     GPIO_Init( GPIOA, GPIO_InitStructure );           /*UART1 Cfg.*/     USART_InitStructure.USART_BaudRate = 57600;      USART_InitStructure.USART_WordLength = USART_WordLength_8b;     USART_InitStructure.USART_StopBits = USART_StopBits_1;     USART_InitStructure.USART_Parity = USART_Parity_No;      USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;     USART_Init(USART1, USART_InitStructure);     USART_ClearFlag(USART1, USART_FLAG_TC);       /*UART1 NIVC Cfg.*/     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     NVIC_Init(NVIC_InitStructure);       USART_Cmd(USART1, ENABLE); }
相关资源
广告