C51的一些误区和注意事项

发布者:数据旅人最新更新时间:2013-02-05 来源: 21IC 关键字:C51  绝对定位  文件块 手机看文章 扫描二维码
随时随地手机看文章

C51的一些误区和注意事项

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,如果你明白它的特性。

关键字:C51  绝对定位  文件块 引用地址:C51的一些误区和注意事项

上一篇:51单片机编程技巧整理
下一篇:由专家提出的51系列单片机指令速记法

推荐阅读最新更新时间:2024-03-16 13:17

C51---15 LED呼吸灯&直流电机调速
LED呼吸灯 代码 通过LED亮灭延迟时间的变化,实现LED呼吸灯效果 #include REGX52.H sbit LED=P2^0; void Delay(unsigned int t) { while(t--); } void main() { unsigned char Time,i; while(1) { for(Time=0;Time 100;Time++) //改变亮灭时间,由暗到亮 { for(i=0;i 20;i++) //计次延时 { LED=0; //LED亮 Delay(Time); //延时Time LED=1;
[单片机]
C51---15 LED呼吸灯&直流电机调速
Keil C51中变量和函数的绝对地址定位问题
1、变量绝对地址定位 1) 在定义变量时使用 _at_ 关键字加上地址就可。 unsigned char idata myvar _at_ 0x40; 把变量 myvar 定义在 idata 的 0x40 处, 在 M51 文件中可以找到这麽一行 IDATA 0040H 0001H ABSOLUTE ;表示有变量在 idata 的 0x0040 处绝对地址定位. 2) 使用 KeilC 编译器定义绝对地址的变量, 方法待查. 2、函数绝对地址定位 1) 在程序中编写一函数 myTest void myTest(void) {   // Add your code here } 2)
[单片机]
你不得不知的C51指针小结
一. 指针变量的定义 指针变量定义与一般变量的定义类似,其形式如下: 数据类型 * 标识符; 表示被定义为基于存储器的指针,无此选项时,被定义为一般指针。这两种指针的区别在于它们的存储字节不同。一般指针在内存中占用三个字节,第一个字节存放该指针存储器类型的编码(由编译时由编译模式的默认值确定),第二和第三字节分别存放该指针的高位和低位地址偏移量。存储器类型的编码值如下: 存储类型I Idata/data/bdata xdata pdata Code 编码值 0x00 0x01 0xFE 0xFF 用于指定指针本身的存储器空间。 char * c_ptr; int * i_ptr; long * l_ptr;
[单片机]
关于C51的中断编程的一点探讨(转)
8051 系列 MCU 的基本结构包括:32 个 I/O 口(4 组8 bit 端口);两个16 位定时计数器;全双工串行通信;6 个中断源(2 个外部中断、2 个定时/计数器中断、1 个串口输入/输出中断),两级中断优先级;128 字节内置RAM;独立的 64K 字节可寻址数据和代码区。中断发生后,MCU 转到 5 个中断入口处之一,然后执行相应的中断服务 处理程序。中断程序的入口地址被编译器放在中断向量中,中断向量位于程序代码段的最低地址处,注意这里的串口输入/输出中断共用一个中断向量。8051的中断向量表如下: 中断源 中断向量 --------------------------- 上电复位 0000H 外部中断0 0003
[单片机]
C51学习心得体会,递归调用程序设计举例
迭代(循环)与递归(调用)对比 (1)二者都是建立在控制结构基础上的,迭代使用的是循环结构,递归使用的是选择机构; (2)二者都用到了循环,迭代明确使用循环结构,递归通过反复调用函数实现循环; (3)二者都用到了终止条件测试,迭代在继续循环条件为假时结束,递归在到达基本实例时终止的。 (4)二者都可能是无限的。 递归举例 1、阶乘 N!=N*(N-1)*...*2*1 long factorial(long number) { if(number =1) return 1; else return (number*factorial(number-1)); } 2、求和N+(N-1)+(N-2)+...+2+1 int s
[单片机]
C51编程14-中断篇(定时器中断1)
在MCS-51的中断系统中,除了有外部中断以外,还有定时器/计数器中断、串行中断,本章节将会说明定时器/计数器中断,以及它的四种方式 MCS-51单片机中,内部有两个16位的可以选择的定时器/计数器,称为定时器0(T0)或者定时器1(T1),它们用来做定时器或者计数器。 定时器/计数器工作原理: 作为定时器使用时,输入的时钟脉冲是由晶体振荡器的输出12分频后得到的,所以定时器是对机器周期的计数器,每一个机器周期+1,因此它的定时频率为晶振频率的1/12;当设置了定时器工作方式并启动定时器后,定时器就会按照被设定的工作方式独立工作,不再占用CPU时间。当计数器计满时溢出时向CPU请求中断。 作为计数器工作使用时,计数器
[单片机]
<font color='red'>C51</font>编程14-中断篇(定时器中断1)
C51 DS1302芯片+lcd12864 显示时间
1.原理图 1302芯片部分 lcd12864部分 2.代码部分 config.h #ifndef __CONFIG_H #define __CONFIG_H #include reg51.h #include lcd12864.h #include intrins.h #define uchar unsigned char #define uint unsigned int #endif lcd12864.c #include lcd12864.h void lcdinit(void) //初始化LCD { write(0,0x30); //功能设定 write(0,0x0c); //显示开
[单片机]
<font color='red'>C51</font> DS1302芯片+lcd12864 显示时间
一种基于C51的多任务机制及应用
引言   传统的单片机程序一般采用单任务机制,单任务系统具有简单直观、易于控制的优点。然而由于程序只能按顺序依次执行,缺乏灵活性,只能使用中断函数实时地处理一些较短的任务,在较复杂的应用中使用极为不便。嵌入式多任务操作系统的出现解决了这个问题。在多任务系统中,可以同时执行多个并行任务,任务之间可以相互跳转。但是嵌入式操作系统在提供强大功能的同时,也带来了代码量大、结构复杂、对硬件要求较高、开发难度大且成本高等问题。而很多时候只需要实现简单的多任务操作就可以满足实际需要,本文设计的这种简单的多任务机制,在只增加极少量C语言代码的前提下,不需使用汇编,无需对原本的程序进行大改动,就可以实现多任务操作。   实时操作系统RTOS的核心
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved