51/AVR单片机技术驿站!  <在线翻译>     便利工具    特色网址   无弹窗、无插件的绿色站点...  英才招聘   学历查询  喜欢>>收藏我站 

当前位置:首页 > 取经杂谈 > 详细内容
关于编译软件KEILC51的应用,各类问题的总结
发布时间:2009/6/2  阅读次数:789  字体大小: 【】 【】【

  

       STC单片机程序开发有两种选择,一种是汇编语言,另一种是C语言。目前的主流是C语言,至于C语言的优点(易阅读,易移植等)不用我多说了。

初学者用KEIL写STC单片机程序的时候还是会遇到很多问题,在这里我列举一些我遇到的问题和大家分享。

  1. Keil C51编译器中无STC单片机型号,怎么办?可以把STC单片机,当成Intel的8052/87C52/87C54/87C58,或Philips的P87C52/P87C54/P87C58就可以了。也可安装STC仿真器的驱动程序,这样就看到型号了。总的原则是程序存储器(FLASH)和数据存储器(ram)要匹配。特别是数据存储器,如果编译用到数据寄存器超出芯片实际的容量,肯定会出错的,而且错误很难发现。
  2. C语言是区分大小写的,如果前面你定义的是大写函数名或者变量,后面引用的时候用小写,肯定是不对的。
  3. 关于子函数交叉调用的问题,一般原则是禁止这样做。举例来说一个子函数在主程序里被调用,同时在定时器中断里也被调用,则子函数所用的变量会发生冲突。解决的方法就是写2个相同的子函数,函数名区分开,用在不同的地方。
  4. 数组的使用。用不好也会出问题。例如这样的情况,你一个数据是10个char变量,结果程序里你往数组的第十一位或者更大的地方写数据,KEIL软件发现不了,运行起来却是不对的。
  5. 写程序要不怕麻烦,要细心,写的多了就提高了。

这里是从网上找的一点资料,讲述一些初学者学习C51的一些误区和注意事项。      
1)C忌讳绝对定位。
常看见初学者要求使用_at_,这是一种谬误,把C当作ASM看待了。在C中变量的定位是编译器的事情,初学者只要定义变量和变量的作
用域,编译器就把一个固定地址给这个变量。怎么取得这个变量的地址?要用指针。比如unsigned char data x;后,x的地址就是&x,
你只要查看这个参数,就可以在程序中知道具体的地址了。所以俺一看见要使用绝对定位的人,第一印象就是:这大概是个初学者。

2)设置SP的问题。
原因和1差不对,编译器在把所有变量和缓冲区赋予地址后,自动把最后一个字节开始的地方,作为SP的开始位置,所以初学者是不必
要去理会的。这体现C的优越性,很多事情C编译时候做了。

3)用C的主程序结构:
#include <reg52.h>

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文件的内部函数和变量,外部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 <reg52.h> /*C编译器内部自带的H文件,使用<>*/

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

  

我要评论
  • 匿名发表
  • [添加到收藏夹]
  • 发表评论:(匿名发表无需登录,已登录用户可直接发表。) 登录状态:未登录
最新评论
所有评论[0]
    暂无已审核评论!

网站导航 管理登陆 ┊ 免责声明 问题反馈  友链说明
本站部分内容来自网络共享资源,如有冒犯您的权利请来信告之删除或纠正!
不得对本站进行复制、盗链或镜像,转载内容须获得同意或授权;欢迎友情链接、站务合作!

    我要报警 Alexa
 mcusy_cn#126.com (请把#改成@) 交流:522422171
本站学习交流群:138..158(高级群1-)、77930286(高级群2)、61804809(群3)
Copyright© MCUSY All Rights Reserved
本站网警备案号: WZ36040002485
  ICP备案证书号:粤ICP备09034963号