在板子上的话,只能看现象了。比如接一个LED,或者把串口接出来,然后程序串口输出你关心的东西是否正确。
或者买一个51仿真器,可以单步运行仿真,比较方便。
或者用proteus搭建一个51环境,调试
VISHAY Intertechnology 推出将遥控接收器与 IrDA 收发器整合到单个 3 透镜表面贴装封装中的新型器件以面向 PC 市场的需求,从而扩展了其光电子产品系列。
当装配到笔记本电脑或多媒体计算机中时,新型 TFDU7100 可实现多个功能,包括遥控视频或音乐播放,以及、MP3 及其它文件格式的无线共享。通过将所有这些功能整合到一个封装中,TFDU7100 可使 PC 机架设计人员限制日光过滤窗口的数目,从而避免遥控器与 IrDA 功能之间的权衡。
TFDU7100 的 8 引脚封装整合了两个高速 PIN 光电二极管、一个红外线发射器、一个 IrDA 控制 IC 和一个遥控器 IC。对于遥控器,TFDU7100 可在 5 米的最短距离接收载频介于 20kHz~60kHz 的信号,因此符合 Microsoft® 的 Media Center 规范。在 36kHz~38kHz 的频率范围内,其最长接收距离为 18 米。对于 IrDA 通信,TFDU7100 在 1 米的自身安全
距离支持高达 4Mbit/s 的所有 IrDA 数据速率。
为简化过渡到 TFDU7100 的过程,该封装的尺寸及焊垫间距与在 80% 的支持 IrDA 的当今笔记本电脑中使用的 Vishay 4Mbit/s 收发器相同。该器件具有更高的灵活性,安装该器件时可使透镜方向位于侧面或顶部。TFU7100 IrDA 及 RC 收发器的工作电压介于 27V~55V,温度范围介于 -25℃~+85℃。该器件不含铅 (Pb),可进行无铅处理,并且符合 RoHS 2002/95/EC 及 WEEE 2002/96/EC 标准。
2006-9-7
89s52的串口调试 [原]
#include<regx52h>
#include<datatypeh>
void main()
{
INT8U a,b;
bit abit;
a=5;
b=13;
SCON=0;
IE=0;
while(1)
{/////////////////////////////////////////////////
TI=0; /////////////注释点
///////////////////////////////////////////////
SBUF=a;
do{
abit=TI;
}while(abit==1);
TI=0;
SBUF=b;
do{
abit=TI;
}while(abit==1);
//////////////////////////////////////////
TI=0;//////////注释2;
/}///////////////////
}这段程序中注释点处,一定要有,//TI=0;则只执行一次while(1)函数,虽然SCON=0时,TI已经是0了,为什么一定要在循环体中再写一遍TI=0,末尾也有TI=0阿?费解。
注释2也一样,如果//TI=0,则同注释1处一样,只执行一次while(1)函数。
liuph 发表于 >2006-9-7 14:35:09 [全文] [评论] [引用] [推荐] [档案] [推给好友] [收藏到网摘]
2006-9-1
调试经验 [原]
Keil c 中最后一句不管是什么语句,编译后传入89s52中后,都会一直执行最后一句。因此,最好加一句while(1);不至于影响别的程序。
while(P1^1&0x01)语句会修改P1^1的值,最好设一个bit a;让a去替代a=P1^1&0x01;while(a),这样更保险。
keil c编译器中在while语句的}后加一分号居然不报错,在vc中是不可想象的,但keil c中就会出现,但应不影响程序还不清楚。
liuph 发表于 >2006-9-1 14:12:21 [全文] [评论] [引用] [推荐] [档案] [推给好友] [收藏到网摘]
2006-8-22
Keil C51 vs 标准C [原]
深入理解并应用C51对标准ANSIC的扩展是学习C51的关键之一。因为大多数扩展功能都是直接针对8051系列CPU硬件的。大致有以下8类:
8051存储类型及存储区域 , 存储模式 , 存储器类型声明 , 变量类型声明 , 位变量与位寻址 ,特殊功能寄存器(SFR) ,C51指针
l 函数属性
具体说明如下(8031为缺省CPU)。
第一节 Keil C51扩展关键字
C51 V40版本有以下扩展关键字(共19个):
_at_ idata sfr16 alien interrupt small
bdata large _task_ Code bit pdata
using reentrant xdata compact sbit data sfr
第二节 内存区域(Memory Areas):
1 Pragram Area:
由Code说明可有多达64kBytes的程序存储器
2 Internal Data Memory:
内部数据存储器可用以下关键字说明:
data:直接寻址区,为内部RAM的低128字节 00H~7FH
idata:间接寻址区,包括整个内部RAM区 00H~FFH
bdata:可位寻址区, 20H~2FH
3 External Data Memory
外部RAM视使用情况可由以下关键字标识: xdata:可指定多达64KB的外部直接寻址区,地址范围0000H~0FFFFH
pdata:能访问1页(25bBytes)的外部RAM,主要用于紧凑模式(Compact Model)。
4 Speciac Function Register Memory
8051提供128Bytes的SFR寻址区,这区域可位寻址、字节寻址或字寻址,用以控制定时器、计数器、串口、I/O及其它部件,可由以下几种关键字说明:
sfr:字节寻址 比如 sfr P0=0x80;为PO口地址为80H,“=”后H~FFH之间的常数。
sfr16:字寻址,如sfr16 T2=0xcc;指定Timer2口地址T2L=0xcc T2H=0xCD
sbit:位寻址,如sbit EA=0xAF;指定第0xAF位为EA,即中断允许
还可以有如下定义方法:
sbit 0V=PSW^2;(定义0V为PSW的第2位)
sbit 0V=0XDO^2;(同上)
或bit 0V-=0xD2(同上)。
第三节 存储模式
存储模式决定了没有明确指定存储类型的变量,函数参数等的缺省存储区域,共三种:
1 Small模式
所有缺省变量参数均装入内部RAM,优点是访问速度快,缺点是空间有限,只适用于小程序。
2 Compact模式
所有缺省变量均位于外部RAM区的一页(256Bytes),具体哪一页可由P2口指定,在STARTUPA51文件中说明,也可用pdata指定,优点是空间较Small为宽裕速度较Small慢,较large要快,是一种中间状态。
3 large模式
所有缺省变量可放在多达64KB的外部RAM区,优点是空间大,可存变量多,缺点是速度较慢。
提示:存储模式在C51编译器选项中选择。
第四节 存储类型声明
变量或参数的存储类型可由存储模式指定缺省类型,也可由关键字直接声明指定。各类型分别用:code,data,idata,xdata,pdata说明,例:
data uar1
char code array[ ]=“hello!”;
unsigned char xdata arr[10][4][4];
第五节 变量或数据类型
C51提供以下几种扩展数据类型:
bit 位变量值为0或1
sbit 从字节中定义的位变量 0或1
sfr sfr字节地址 0~255
sfr16 sfr字地址 0~65535
其余数据类型如:char,enum,short,int,long,float等与ANSI C相同。
第六节 位变量与声明
1 bit型变量
bit型变量可用变量类型,函数声明、函数返回值等,存贮于内部RAM20H~2FH。
注意:
(1) 用#pragma dISAble说明函数和用“usign”指定的函数,不能返回bit值。
(2) 一个bit变量不能声明为指针,如bit ptr;是错误的
(3) 不能有bit数组如:bit arr[5];错误。
2 可位寻址区说明20H-2FH
可作如下定义:
int bdata i;
char bdata arr[3],
然后:
sbit bito=in0;sbit bit15=I^15;
sbit arr07=arr[0]^7;sbit arr15=arr[i]^7;
第七节 Keil C51指针
C51支持一般指针(Generic Pointer)和存储器指针(Memory_Specific Pointer)
1 一般指针
一般指针的声明和使用均与标准C相同,不过同时还可以说明指针的存储类型,例如:
long state;为一个指向long型整数的指针,而state本身则依存储模式存放。
char xdata ptr;ptr为一个指向char数据的指针,而ptr本身放于外部RAM区,以上的long,char等指针指向的数据可存放于任何存储器中。
一般指针本身用3个字节存放,分别为存储器类型,高位偏移,低位偏移量。 2 存储器指针
基于存储器的指针说明时即指定了存贮类型,例如:
char data str;str指向data区中char型数据
int xdata pow; pow指向外部RAM的int型整数。
这种指针存放时,只需一个字节或2个字节就够了,因为只需存放偏移量。
3 指针转换
即指针在上两种类型之间转化:
l 当基于存储器的指针作为一个实参传递给需要一般指针的函数时,指针自动转化。
l 如果不说明外部函数原形,基于存储器的指针自动转化为一般指针,导致错误,因而请用“#include”说明所有函数原形。
l 可以强行改变指针类型。
第八节 Keil C51函数
C51函数声明对ANSI C作了扩展,具体包括:
1 中断函数声明:
中断声明方法如下:
void serial_ISR () interrupt 4 [using 1]
{
/ ISR /
}
为提高代码的容错能力,在没用到的中断入口处生成iret语句,定义没用到的中断。
/ define not used interrupt, so generate "IRET" in their entrance /
void extern0_ISR() interrupt 0{} / not used /
void timer0_ISR () interrupt 1{} / not used /
void extern1_ISR() interrupt 2{} / not used /
void timer1_ISR () interrupt 3{} / not used /
void serial_ISR () interrupt 4{} / not used /
2 通用存储工作区
3 选通用存储工作区由using x声明,见上例。
4 指定存储模式
由small compact 及large说明,例如:
void fun1(void) small { }
提示:small说明的函数内部变量全部使用内部RAM。关键的经常性的耗时的地方可以这样声明,以提高运行速度。
5 #pragma dISAble
在函数前声明,只对一个函数有效。该函数调用过程中将不可被中断。
6 递归或可重入函数指定
在主程序和中断中都可调用的函数,容易产生问题。因为51和PC不同,PC使用堆栈传递参数,且静态变量以外的内部变量都在堆栈中;而51一般使用寄存器传递参数,内部变量一般在RAM中,函数重入时会破坏上次调用的数据。可以用以下两种方法解决函数重入:
a、在相应的函数前使用前述“#pragma dISAble”声明,即只允许主程序或中断之一调用该函数;
b、将该函数说明为可重入的。如下:
void func(param) reentrant;
KeilC51编译后将生成一个可重入变量堆栈,然后就可以模拟通过堆栈传递变量的方法。
由于一般可重入函数由主程序和中断调用,所以通常中断使用与主程序不同的R寄存器组。
另外,对可重入函数,在相应的函数前面加上开关“#pragma noaregs”,以禁止编译器使用绝对寄存器寻址,可生成不依赖于寄存器组的代码。
7 指定PL/M-51函数
由alien指定。
liuph 发表于 >2006-8-22 11:33:13 [全文] [评论] [引用] [推荐] [档案] [推给好友] [收藏到网摘]
2006-8-22
单片机C51编程规范 [原]
1单片机C51编程规范- 前言
为了提高源程序的质量和可维护性,从而最终提高软件产品生产力,特编写此规范。
2 单片机C51编程规范-范围
本标准规定了程序设计人员进行程序设计时必须遵循的规范。本规范主要针对C51编程语言和keil编译器而言,包括排版、注释、命名、变量使用、代码可测性、程序效率、质量保证等内容。
3 单片机C51编程规范-总则
l 格式清晰
l 注释简明扼要
l 命名规范易懂
l 函数模块化
l 程序易读易维护
l 功能准确实现
l 代码空间效率和时间效率高
l 适度的可扩展性
4 单片机C51编程规范-数据类型定义
编程时统一采用下述新类型名的方式定义数据类型。
建立一个datatypeh文件,在该文件中进行如下定义:
typedef bit BOOL; // 位变量 //
typedef unsigned char INT8U; // 无符号8位整型变量 //
typedef signed char INT8S; // 有符号8位整型变量 //
typedef unsigned int INT16U; // 无符号16位整型变量 //
typedef signed int INT16S; // 有符号16位整型变量 //
typedef unsigned long INT32U; // 无符号32位整型变量 //
typedef signed long INT32S; // 有符号32位整型变量 //
typedef float FP32; // 单精度浮点数(32位长度) //
typedef double FP64; // 双精度浮点数(64位长度) //
5 单片机C51编程规范-标识符命名
51 命名基本原则
l 命名要清晰明了,有明确含义,使用完整单词或约定俗成的缩写。通常,较短的单词可通过去掉元音字母形成缩写;较长的单词可取单词的头几个字母形成缩写。即"见名知意"。
l 命名风格要自始至终保持一致。
l 命名中若使用特殊约定或缩写,要有注释说明。
l 除了编译开关/头文件等特殊应用,应避免使用以下划线开始和/或结尾的定义。
l 同一软件产品内模块之间接口部分的标识符名称之前加上模块标识。
52 宏和常量命名
宏和常量用全部大写字母来命名,词与词之间用下划线分隔。对程序中用到的数字均应用有意义的枚举或宏来代替。
53 变量命名
变量名用小写字母命名,每个词的第一个字母大写。类型前缀(u8\s8 etc)全局变量另加前缀g_。
局部变量应简明扼要。局部循环体控制变量优先使用i、j、k等;局部长度变量优先使用len、num等;临时中间变量优先使用temp、tmp等。
54 函数命名
函数名用小写字母命名,每个词的第一个字母大写,并将模块标识加在最前面。
55 文件命名
一个文件包含一类功能或一个模块的所有函数,文件名称应清楚表明其功能或性质。
每个c文件应该有一个同名的h文件作为头文件。
6 单片机C51编程规范-注释
61 注释基本原则
l 有助于对程序的阅读理解,说明程序在"做什么",解释代码的目的、功能和采用的方法。
l 一般情况源程序有效注释量在30%左右。
l 注释语言必须准确、易懂、简洁。
l 边写代码边注释,修改代码同时修改相应的注释,不再有用的注释要删除。
62 文件注释
文件注释必须说明文件名、函数功能、创建人、创建日期、版本信息等相关信息。
修改文件代码时,应在文件注释中记录修改日期、修改人员,并简要说明此次修改的目的。所有修改记录必须保持完整。
文件注释放在文件顶端,用"/……/"格式包含。
注释文本每行缩进4个空格;每个注释文本分项名称应对齐。
/
文件名称:
作 者:
版 本:
说 明:
修改记录:
/
63 函数注释
631 函数头部注释
函数头部注释应包括函数名称、函数功能、入口参数、出口参数等内容。如有必要还可增加作者、创建日期、修改记录(备注)等相关项目。
函数头部注释放在每个函数的顶端,用"/……/"的格式包含。其中函数名称应简写为FunctionName(),不加入、出口参数等信息。
/
函数名称:
函数功能:
入口参数:
出口参数:
备 注:
/
632 代码注释
代码注释应与被注释的代码紧邻,放在其上方或右方,不可放在下面。如放于上方则需与其上面的代码用空行隔开。一般少量注释应该添加在被注释语句的行尾,一个函数内的多个注释左对齐;较多注释则应加在上方且注释行与被注释的语句左对齐。
函数代码注释用"//…//"的格式。
通常,分支语句(条件分支、循环语句等)必须编写注释。其程序块结束行"}"的右方应加表明该程序块结束的标记"end of ……", 尤其在多重嵌套时。
64 变量、常量、宏的注释
同一类型的标识符应集中定义,并在定义之前一行对其共性加以统一注释。对单个标识符的注释加在定义语句的行尾。
全局变量一定要有详细的注释,包括其功能、取值范围、哪些函数或过程存取它以及存取时的注意事项等。
注释用"//…//"的格式。
7 单片机C51编程规范-函数
71 设计原则
函数的基本要求:
l 正确性:程序要实现设计要求的功能。
l 稳定性和安全性:程序运行稳定、可靠、安全。
l 可测试性:程序便于测试和评价。
l 规范/可读性:程序书写风格、命名规则等符合规范。
l 扩展性:代码为下一次升级扩展留有空间和接口。
l 全局效率:软件系统的整体效率高。
l 局部效率:某个模块/子模块/函数的本身效率高。
编制函数的基本原则:
l 单个函数的规模尽量限制在200行以内(不包括注释和空行)。一个函数只完成一个功能。
l 函数局部变量的数目一般不超过5~10个。
l 函数内部局部变量定义区和功能实现区(包含变量初始化)之间空一行。
l 函数名应准确描述函数的功能。通常使用动宾词组为执行某 *** 作的函数命名。
l 函数的返回值要清楚明了,尤其是出错返回值的意义要准确无误。
l 不要把与函数返回值类型不同的变量,以编译系统默认的转换方式或强制的转换方式作为返回值返回。
l 减少函数本身或函数间的递归调用。
l 尽量不要将函数的参数作为工作变量。
72 函数定义
l 函数若没有入口参数或者出口参数,应用void明确申明。
l 函数名称与出口参数类型定义间应该空一格且只空一格。
l 函数名称与括号()之间无空格。
l 函数形参必须给出明确的类型定义。
l 多个形参的函数,后一个形参与前一个形参的逗号分割符之间添加一个空格。
l 函数体的前后花括号"{}" 各独占一行。
73 局部变量定义
l 同一行内不要定义过多变量。
l 同一类的变量在同一行内定义,或者在相邻行定义。
l 先定义data型变量,再定义idtata型变量,再定义xdata型变量
l 数组、指针等复杂类型的定义放在定义区的最后。
l 变量定义区不做较复杂的变量赋值。
74 功能实现区规范
l 一行只写一条语句。
l 注意运算符的优先级,并用括号明确表达式的 *** 作顺序,避免使用默认优先级。
l 各程序段之间使用一个空行分隔,加以必要的注释。程序段指能完一个较具体的功能的一行或多行代码。程序段内的各行代码之间相互依赖性较强。
l 不要使用难懂的技巧性很高的语句。
l 源程序中关系较为紧密的代码应尽可能相邻。
l 完成简单功能、关系非常密切的一条或几条语句可编写为函数或定义为宏。
8 单片机C51编程规范-排版
81 缩进
代码的每一级均往右缩进4个空格的位置。
82 分行
过长的语句(超过80个字符)要分成多行书写;长表达式要在低优先级 *** 作符处划分新行, *** 作符放在新行之首,划分出的新行要进适当的缩进,使排版整齐,语句可读。避免把注释插入分行中。
83 空行
l 文件注释区、头文件引用区、函数间应该有且只有一行空行。
l 相邻函数之间应该有且只有一行空行。
l 函数体内相对独立的程序块之间可以用一行空行或注释来分隔。
l 函数注释和对应的函数体之间不应该有空行。
l 文件末尾有且只有一行空行。
84 空格
l 函数语句尾部或者注释之后不能有空格。
l 括号内侧(即左括号后面和右括号前面)不加空格,多重括号间不加空格。
l 函数形参之间应该有且只有一个空格(形参逗号后面加空格)。
l 同一行中定义的多个变量间应该有且只有一个空格(变量逗号后面加空格)。
l 表达式中,若有多个 *** 作符连写的情况,应使用空格对它们分隔:
在两个以上的关键字、变量、常量进行对等 *** 作时,它们之间的 *** 作符前后均加一个空格;在两个以上的关键字、变量、常量进行非对等 *** 作时,其前后均不应加空格;
逗号只在后面加空格;
双目 *** 作符,如比较 *** 作符, 赋值 *** 作符"="、"+=",算术 *** 作符"+"、"%",逻辑 *** 作符"&&"、"&",位 *** 作符"<<"、"^"等,前后均加一个空格;
单目 *** 作符,如"!"、"~"、"++"、"-"、"&"(地址运算符)等,前后不加空格;
"->"、""前后不加空格;
if、for、while、switch等关键字与后面的括号间加一个空格;
85 花括号
l if、else if、else、for、while语句无论其执行体是一条语句还是多条语句都必须加花括号,且左右花括号各独占一行。
l do{}while()结构中,"do"和"{"均各占一行,"}"和"while();"共同占用一行。
if ( do
{ {
} }while( ;
else
{
}
86 switch语句
l 每个case和其判据条件独占一行。
l 每个case程序块需用break结束。特殊情况下需要从一个case块顺序执行到下一个case块的时候除外,但需要在交界处明确注释如此 *** 作的原因,以防止出错。
l case程序块之间空一行,且只空一行。
l 每个case程序块的执行语句保持4个空格的缩进。
l 一般情况下都应该包含default分支。
Switch (
{
case x:
break;
case x:
break;
default:
break;
}
9 单片机C51编程规范-程序结构
91 基本要求
l 有main()函数的c文件应将main()放在最前面,并明确用void声明参数和返回值。
l 对由多个c文件组成的模块程序或完整监控程序,建立公共引用头文件,将需要引用的库头文件、标准寄存器定义头文件、自定义的头文件、全局变量等均包含在内,供每个文件引用。通常,标准函数库头文件采用尖角号< >标志文件名,自定义头文件采用双撇号〃〃标志文件名。
l 每个c文件有一个对应的h文件,c文件的注释之后首先定义一个唯一的文件标志宏,并在对应的h文件中解析该标志。
在c文件中:
#define FILE_FLAG
在h文件中:
#ifdef FILE_FLAG
#define XXX
#else
#define XXX extern
#endif
l 对于确定只被某个c文件调用的定义可以单独列在一个头文件中、单独调用。
92 可重入函数
可重入函数中若使用了全局变量,应通过关中断、信号量等 *** 作手段对其加以保护。
93 函数的形参
l 由函数调用者负责检查形参的合法性。
l 尽量避免将形参作为工作变量使用。
94 循环
l 尽量减少循环嵌套层数
l 在多重循环中,应将最忙的循环放在最内层
l 循环体内工作量最小
l 尽量避免循环体内含有判断语句
liuph 发表于 >2006-8-22 11:26:48 [全文] [评论] [引用] [推荐] [档案] [推给好友] [收藏到网摘]
2006-8-22
在C51中变量的空间分配几个方法 [原]
1、 data区空间小,所以只有频繁用到或对运算速度要求很高的变量才放到data区内,比如for循环中的计数值。
2、 data区内最好放局部变量。
因为局部变量的空间是可以覆盖的(某个函数的局部变量空间在退出该函数是就释放,由别的函数的局部变量覆盖),可以提高内存利用率。当然静态局部变量除外,其内存使用方式与全局变量相同;
3、 确保你的程序中没有未调用的函数。
在Keil C里遇到未调用函数,编译器就将其认为可能是中断函数。函数里用的局部变量的空间是不释放,也就是同全局变量一样处理。这一点Keil C做得很愚蠢,但也没办法。
4、 程序中遇到的逻辑标志变量可以定义到bdata中,可以大大降低内存占用空间。
在51系列芯片中有16个字节位寻址区bdata,其中可以定义816=128个逻辑变量。定义方法是: bdata bit LedState;但位类型不能用在数组和结构体中。
5、 其他不频繁用到和对运算速度要求不高的变量都放到xdata区。
6、 如果想节省data空间就必须用large模式,将未定义内存位置的变量全放到xdata区。当然最好对所有变量都要指定内存类型。
7、 当使用到指针时,要指定指针指向的内存类型。
在C51中未定义指向内存类型的通用指针占用3个字节;而指定指向data区的指针只占1个字节;指定指向xdata区的指针占2个字节。如指针p是指向data区,则应定义为: char data p;。还可指定指针本身的存放内存类型,如:char data xdata p;。其含义是指针p指向data区变量,而其本身存放在xdata区。
liuph 发表于 >2006-8-22 11:25:44 [全文] [评论] [引用] [推荐] [档案] [推给好友] [收藏到网摘]
2006-8-22
KEIL C51 中调用汇编 [原]
有关c51调用汇编的方法已经有很多帖子讲到,但是一般只讲要点,很少有对整个过程作详细描述,对于初学者是不够的,这里笔者通过一个简单例子对这个过程进行描述,希望能对初学者有所帮助。几年来,在这个论坛里笔者得到很多热心人指导,因此也希望
藉此尽一点绵薄之力。
在这个例子里,阐述了编写c51程序调用汇编函数的一种方法,这个外部函数的入口参数是一个字符型变量和一个位变量,返回值是一个整型变量。例中,先用c51写出这个函数的主体,然后用SRC控制指令编译产生asm文件,进一步修改这个asm文件就得到我们所要的汇编函数。该方法让编译器自动完成各种段的安排,提高了汇编程序的编写效率。
step1 按写普通c51程序方法,建立工程,在里面导入mainc文件和CFUNCc文件。
相关文件如下:
//mainc文件
#include < reg51h >
#define uchar unsigned char
#define uint unsigned int
extern uint AFUNC(uchar v_achr,bit v_bflag);
void main()
{
bit BFLAG;
uchar mav_chr;
uint mvintrslt;
mav_chr=0xd4; BFLAG=1;
mvintrslt=AFUNC(mav_chr,BFLAG);
}
//CFUNCc文件
#define uchar unsigned char
#define uint unsigned int
uint AFUNC(uchar v_achr,bit v_bflag)
{
uchar tmp_vchr;
uint tp_vint;
tmp_vchr=v_achr;
tp_vint=(uint)v_bflag;
return tmp_vchr+(tp_vint<<8);
}
step2 在 Project 窗口中包含汇编代码的 C 文件上右键,选择“Options for ”,点击右边的“Generate Assembler SRC
File”和“Assemble SRC Fil
楼主没有搞清楚 51的 结构
楼上说的虽然大多是废话,,对你的项目可以没多少帮助
但是至少有一点是对的设置成xdata可以解决你的问题
虽然不是什么好办法
51的 ram 分外三种
内部直接寻址你的128byte 内部间接的128byte
还有就是外部 ram
你的51单片机有512byte
那么肯定是 内部 直接 间接各128
外加外部256字节
你把那些大一点的数据全部改成 xdata 声明就可以了
当然如果你会控制ram大小的话用idata 声明效率更好一点
例如 unsigned char yy;
写个成 unsigned char xdata yy;
(你看你自己的编译结果显示 data=137, xdata=0, code=4856
就应该猜测一下 xdata 干吗用的了
最后 建议楼主 最好不用在keil c51里面使用printf函数(浪费啊)
回去仔细看一遍51的结构然后看看keil c51的区别于ansi c的东西
会对你有帮助
如果对您有帮助,请记得采纳为满意答案,谢谢!祝您生活愉快!
Keil
C51集成开发环境的主要功能有以下几点:
1.RTX-51实时 *** 作系统:简化了复杂的实时应用软件项目的设计。
2.C51国际际准化C交叉编译器:从C源代码产生就可以重定位的目标模块。
3.LIB51库管理器:从目标模块生成连接器可以使用的库文件。
4.BL51链接器/定位器:组合由C51和A51产生的可重定位的目标模块,生成绝对目标模块。
5.A51宏汇编器:从89C51汇编源代码产生可重定位的目标模块。
6.OH51目标文件至HEX格式的转换器,从绝对目标模块生成Intel
Hex文件。
7.µVision4
for
Windows:是一个集成开发环境,它将项目管理、程序调试、源代码编辑等组合在一个功能强大的环境中。
µVision4支持所有的Keil
89C51的工具软件,其中包括C51宏汇编器、编译器、链接器/定位器和目标文件至HEX格式转换器,µVision4可以自动地完成编译、汇编、链接程序等基本的 *** 作。还可以在编译之后进行模拟仿真调试,清楚的显示出每个变量的变化。
存储模式只是规定默认的存储区:\x0d\small :默认变量在内部RAM中,即data\x0d\compact:默认变量在外部分页的256字节RAM中,,即pdata\x0d\large:默认变量在外部64KRAM中,即xdata\x0d\ 如果,char Xdata i这样显式地规定了变量的存放区,则以定义为准。不受存储模式影响。
一般用优化等级8,其它的别用,容易出事。
编译完之后多留意data,xdata,看有没超出芯片的最大值,
特别是data,不能超过128,甚至太接近128有时也会出问题。
如果data 需要使用到256,则另外的128用idata定义
1先安装Keil C51并破解,再安装MDK5并破解。
2分别打开Keil C51和MDK5的安装目录。将Keil C51安装目录下的C51文件夹复制到MDK5的安装目录文件夹下。
3分别打开TOOLSINI文件;将Keil C51下TOOLSINI文件的内容复制,粘贴到MDK5下TOOLSINI文件内容的最低端。
4注意查看并找到粘贴到MDK5下TOOLSINI文件中如下行代码:
[C51]
PATH="D:\Keil\C51\"(Keil C51安装目录下TOOLSINI文件中的内容)
将Keil处的内容改成与MDK5下TOOLSINI文件中如下行代码:
RTEPATH="D:\Keil_v5\ARM\PACK"
Keil_v5处的内容一样。
目的是让软件在MDK5安装目录内找到C51文件。
5完成以上 *** 作,就可以将安装的Keil C51软件卸载,在MDK5软件上就可以编译C51单片机程序了。亲自测试可行。
来自:网页链接
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)