C51如何定义未结束的字符串常量量?其存储在哪种存储器中?

【图文】第15章
C51的存储结构_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
C51的存储结构
上传于||暂无简介
大小:144.50KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢【图文】第7章
C51的存储结构_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
C51的存储结构
上传于||文档简介
&&C1​单​片​机​变​成​介​绍
大小:161.50KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢当前位置: >>
C51语言程序设计
计算机科学与技术系第2章 认识uVision3与Keil C教学目的:熟悉80C51系列单片机的C51语言 程序设计 ,能够编写简单C51语言程序 。 教学重点: Keil C 的基本结构 数据类型、运算符 函数、中断 数组与指针 常用C51 语言程序设计方法。 教学难点: C51 语言对C语言的扩展。 计算机科学与技术
系2.1 单片机的C语言概述2.1.1 C语言的主要优点1.对单片机的指令系统不要求十分熟悉,仅要求对单片机的基本硬件结构有一 定了解; 2.C语言可直接访问单片机的物理地址,包括寄存器、不同存储器以及外部接口 器件; 3.C语言是以函数为程序设计基本模块的,这种方式可方便地进行结构化程序设 计; 4.由于具有丰富的数据结构类型及多种运算符,所以表达方式灵活,表达能力 强; 5.源代码可读性较强,容易理解和编程,并且极大地缩短了源文件长度; 6.具有丰富的库函数,其中包括许多标准子程序,具有较强的数据处理能力; 7.模块化编程技术使程序容易移植,可以把需要的功能模块方便地移植到一个 新程序中或另一种单片机上。 计算机科学与技术系 2.1.2 单片机C语言使用的工具图2-1 Keil C51 的汇编/编译器及汇编//编译过程 计算机科学与技术系1. C51编译器 2.A51宏汇编器 3.LIB51库管理器 4.BL51连接/定位器2.1.3 使用C语言的注意事项标准C语言没有提供对内存地址范围的定义,没 有处理中断的指令。 对于此问题,不同的单片机 C语言的解决方案不完全相同,从而不同型号单片 机上的程序不可互相移植 。 在用C语言编写单片机程序时,需要根据单片机 的存储器结构和内部资源定义相应的数据类型和 变量 。在编程时不要使用大量不必要的变量类型。 计算机科学与技术系2.2 Keil C51μVision 3环境简介 建立您的第一个 C 项目 计算机科学与技术系选择所要的单片机,这里我们选择常用的 Ateml 公司的 AT89C51。 计算机科学与技术系项目中创建新的程序文件或加入旧程序文件 通过菜单 File-New 或快捷键 Ctrl+N 来实现标在屏幕左边的 Source Group1 文件夹图标上右击Add File to Group ?Source Group 1?,然后将项目编译成为HEX文件,实 现仿真、下载验证的功能 计算机科学与技术系 计算机科学与技术系调 试 与 仿 真 计算机科学与技术系 外围部件的访问 计算机科学与技术系☆ 2.3Keil C语言的基本结构及变 量、常数与数据类型1、简单C程序举例 void main( ) { int b ,a=1; // a表示一个整型变量变量名a;语句结束符号 b=++a; // a的值加一变为2,然后将a的值赋给b } 说明: C程序从main开始执行程序,前一个void表示 无值返回; C程序中用到的变量一定要先定义变量的数据 类型,只有定义了变量的数据类型后,变量才会在内 存中按其数据类型长度给其分配空间。 计算机科学与技术系 复习:C语言的基本数据类型数据类型 位数 字节数 bit 1 signed char 8 1 unsigned char 8 1 enum 16 2 signed short 16 2 unsigned short 16 2 signed int 16 2 unsigned int 16 2值域 0~1 -128~+127 0~255 -3 -3 0~6~+35 计算机科学与技术系 数据类型 位数 字节数 值域 signed long 32 4 -- unsigned long 32 4 0~ float 32 4 0.~0. sbit 1 0~1 sfr 8 1 0~255 sfr16 16 2 0~65535 计算机科学与技术系C语言的缺陷无边界出错检查、运算符较多。变量用来存放数据,运算符用来处理数据。运算符 分算术运算、关系运算、逻辑运算、赋值运算、 逗号运算符、条件运算符、位运算符、指针运算 符等。 计算机科学与技术系2.4 Keil C 的基本运算符运算符 + * / % 范例 a+b a-b a*b a/b a%b 说 明 a变量值和b变量值相加 a变量值和b变量值相减 a变量值乘以b变量值 a变量值除以b变量值 取a变量值除以b变量值的余数++ --a的值加1,即a=a+1 a-a的值减1,即a=a-1 算术运算符 结果具体的值a++ 计算机科学与技术系运算符 范 例= a=6说 明将6赋值给a变量,即a变量值等于6+= a+=b 回a-= *= a /= a %= a a/=b a%=b a-=b a*=b等同于a=a+b,将a和b相加的结果又存等同于a=a-b,将a和b相减的结果又存回a 等同于a=a*b,将a和b相乘的结果又存回 等同于a=a/b,将a和b相除的结果又存回 等同于a=a%b,a值除以b值的余数又存回 计算机科学与技术系运算符 & & ==范例 a&b a&b a==b说 明 测试a是否大于b 测试a是否小于b 测试a是否等于b&=&= !=a&=ba&=b a!=b测试a是否大于或等于b测试a是否小于或等于b 测试a是否不等于b关系运算符 “0”)结果某种关系的真、假(“1”、 计算机科学与技术系运算符&&范例a&&b说 明a和b AND,两个变量都是“真”, 结果才为 “真”否则结果为“0” a和b作逻辑OR,只要有任何 一个变量为“真”,结果就为“真”‖a‖b!!a将a变量的值取反,即原来为“真”则 变 “假”,为“假”则变为真逻辑运算符 运算结果真、假 (“1”、“0”) 计算机科学与技术系运算符 范 例&&说 明将a按位右移b个位,左侧补“0”, 出舍去 将a按位左移b个位,右侧补“0”, 溢出舍去 a和b的按位作OR运算 a和b的按位作AND运算 a和b的按位作XOR运算 将a的每一位取反 指针运算 将b变量的地址存入a寄存器 用来取寄存器所指地址内的值&& & ^ ~a&&b 溢 a&&b ab a&b a^b ~a& *a=&b *a 计算机科学与技术系条件运算符:表达式1?表达式2:表达式3条件运算符表达式的运算规则:如果表达式1的值为真, 那么整个表达式的值就是表达式2的值,否则是表达式3 的值。 各种运算符时,要考虑运算符的优先级及结合性。 运算符的优先级如下:初等 单目 算术关系逻辑条件赋值逗号 计算机科学与技术系2.5Keil C的流程控制★ #define 宏名 字符串 以一个宏名称来代表一个字符串,即当程序任何地方 使用到宏名称时,则将以代表的字符串来替换。宏的定义可 以是一个常数,表达式,或含有参数的表达式都可,在程序 中如果多次使用宏,则会占用较多的内存,但执行速度较 快。范例:#define uchar unsigned char #define unit unsigned int #define LED P2 //用uchar代替unsigned char //用unit 代替unsigned char //用功能来命名注意:宏定义不是C程序的语句,所以后面不能有分号,若 有分号会发生连同分号一起置换,则会出错。 如 #define PI 3.141596 ; area=PI*r*r; 置换后 area=3.141596;*r*r ;出错。 计算机科学与技术系 ★ if 语句( Keil软件的使用)1. if (条件表达式) { 动作 } 如果条件表达式的值为真(非零数), 则执行{ }内的动作,如果条件表达式为假, 则略过该动作而继续往下执行。 计算机科学与技术系2、 if (条件表达式) { 动作1 } else { 动作2 }如果条件表达式为真,则执行动作1,略过else 的部分,接着往下执行,如果条件表达式为假, 则略过if的部分而执行else的动作2,然后再往下 执行。 计算机科学与技术系 3、if (条件表达式1) if (条件表达式2) if (条件表达式3) { 动作A } else { 动作B } else { 动作C } else { 动作D } 动作 A:条件表达式1,2,3都成立时才会执行。 动作 B:条件表达式1,2成立,但条件表达式3不成立时才会 执行。 动作 C:条件表达式1成立,条件表达式2不成立时才会执行。 动作 D:条件表达式1不成立时才会执行。 计算机科学与技术系 4、if (条件表达式1) { 动作A } else if (条件表达式2) { 动作B } else if (条件表达式3) { 动作C } else { 动作D } 动作 A:条件表达式1成立时立即执行。 动作 B:条件表达式1不成立,但条件表达式 2成立时才会 执行。 动作 C:条件表达式1,2不成立,条件3成立时才会执行。 动作 D:是条件表达式1,2,3都不成立时才会执行。 计算机科学与技术系★ switch-case语句 switch (条件表达式) { case条件值1: 动作1 case条件值2: 动作2 case条件值3: 动作3default:动作4 } 计算机科学与技术系 switch内的条件表达式的结果必须为整数或字符。 Switch用条件表达式的值来与各case的条件值对比,如 果与某个条件值相符合,则执行该case的动作,之后一定 要写break退出循环。 如果所有的条件值都不符合,则执行default的动作,每 一个动作之后一定要写break,否则会继续执行。 另外case之后的条件值必须是数据常数,不能是变量, 而且不可以重复,即条件值必须各不同,如果有数种case 所做的动作一样时,也可以写在一起,即上下并列。 一般当程序必须作多选1时,可以采用switch语句。 计算机科学与技术系 break:是跳出循环的命令,任何由switch、 for、while、do-while构成的循环,都可以用break来跳 出。 必须注意的是break一次只能跳出一层循环,通常都和if 连用,当某些条件成立后就跳出循环。default:当所有case的条件值都不成立时,就执行 default所指定的动作,作完后也要使用break指令跳出 switch循环。 计算机科学与技术系★while循环语句 while (条件表达式) { 动作 } 先测试条件表达式是否成立,当条件表达式为真 时,则执行循环内动作,做完后又继续跳回条件 表达式作测试,如此反复直到条件表达式为假为 止,使用时要避免条件永远为真,造成死循环。 计算机科学与技术系★do-while 循环语句 do { 动作 } while(条件表达式); 先执行动作后,再测试条件表达式是否成 立。当条件表达式为真,则继续回到前 面动作,如此反复直到条件表达式为假 为止,不论条件表达式的结果为何,至 少会做一次动作,使用时要避免条件永 远为真,造成死循环。 计算机科学与技术系★ for循环语句 for (表达式1;表达式2;表达式3) { 动作 } 表达式1:通常是设定起始值。 表达式2:通常是条件判断式,如果条件为真时, 则执行动作,否则终止循环。 表达式3:通常是步长表达式,执行动作完毕后, 必须再回到这里做运算,然后再到表达式2做 判断。 计算机科学与技术系 ★goto语句:使用方法 goto 标号 编写程序,尽量不要使用goto语句,以避免程序阅 读困难。 但是,break一次只能跳离一个循环,如果需要跳离很多 循环,则可使用goto语句,但goto的目的位置必须 在同一个程序文件内,不能跳到其他程序文件,标签的 写法和变量是一样的,标签后面必须加一个冒号。 goto经常和if连用,如果程序中检查到异常时,即使 用goto语句去处理。 计算机科学与技术系★2.6 函数与中断子程序 (FUNCTION)数据类型 函数名称 ( 数据类型 参数1, 数据类型 参数 2,......) 所谓函数,即子程序,也就是“语句的集合”。就是说把 经常使用的语句群定义为函数,在程序用到时调用,这 样就可以减少重复编写程序的麻烦,也可以减少程序的 长度。当一个程序太大时,建议将其中的一部分改用函 数的方式比较好,因为大程序过于繁杂容易出错,而小 程序容易调试,也易于阅读和修改。 计算机科学与技术系C语言程序是由函数构成的,函数是C语言程序中的基本模块 C51函数分为2类,一类是库函数,一类是用户定义函数。C51中函 数的定义、参数和函数值及函数调用等内容与标准C语言基本 相同,下面仅说明几个不同点。 1.中断服务程序(interrupt修饰符的应用) 为实现在C51源程序中直接编写中断程序,C51编译器允许用 C语言创建中断服务程序。在C51编译器中增加了一个扩展关键 字interrupt,在函数声明时包括interrupt m,将把所声明 的函数定义为一个中断服务程序。 其格式为: void 函数标识符(void) interrupt m 其中, m=0~31,0对应于外部中断0; 在C语言中调用中断服务程序,用户只需关心中断号和寄存器组的 选择。 0――4 计算机科学与技术系2.寄存器组的切换(using修饰符的应用) 在51系列单片机中有4个寄存器组,每组包含8个通用寄存器,在采用中断 程序时,经常需要保护某些寄存器组,此时采用交换寄存器组的方法很 方便快捷, C51编译器定义了一个函数using可方便地用于寄存器组的 交换。 函数使用指定寄存器组的定义性说明如下: void 函数标识符(形参表) using n n=0~3为寄存器组号,对应80C51中的4个寄存器组。 3.函数使用指定的存储模式 修饰存储空间的修饰符,用以指明所定义的变量应分配在什么样的存储空 间,其定义 格式为: 类型说明符 函数标识符(形参表)存储模式修饰符{small,compact, large} 例如:extern int func (int i, int j) /* 修饰为 大模式 */ 计算机科学与技术系 ★使用函数的注意事项1、函数定义时要同时声明其类型; 2、调用函数前要先声明该函数; 3、传给函数的参数值,其类型要与函数原定义一致; 4、接受函数返回值的变量,其类型也要与函数一致。★ 函数的声明 void functionl(void) 此函数无返回值,也不传参数。 void function2(unsign char i , int j) 此函数无返回值,但需要unsign char类型的i参数和int类型 的j参数。 unsign char function3(unsign char i) 此函数有unsign char类型的返回值给原调用程序。 计算机科学与技术系★函数的返回值 return是用来使函数立即结束以返回原 调用程序的指令,而且可以把函数内的最 后结果数据传回给原调用程序。 计算机科学与技术系 2、中断函数 51单片机的中断系统十分重要,可以用C51语言来声明 中断和编写中断服务程序,当然也可以用汇编语言来写。 中断过程通过使用interrupt关键字和中断编号0~4来实现。中断函数的完整语法及示例如下: 返回值 函数名([参数][模式][重入]interrupt n [using n] interrupt n 中的n对应中断源的编号:中断编号告诉编译器 中断程序的入口地址,它对应着IE寄存器中的使能位,既IE 寄存器中的0位对应着外部中断0,相应的外部中断0的编号 是0。 using n中的n对应四组通用寄存器中的一组。 计算机科学与技术系在51系列单片机中,有的单片机多达32个中断源, 所以中断编号是0~31。当正在执行一个特定任务时,可能有更紧急的事情需 要CPU处理,这就涉及到了中断优先级。 高优先级中断可以中断正在处理的低优先级中断程 序,因而最好给每种优先程序分配不同的寄存器组。 在C51中可使用using指定寄存器组,using后的变量为 0~3的常整数,分别表示51单片机内的4个寄存器组。 计算机科学与技术系8051单片机的中断源以及中断编号如表2-2所示。表2-2 中断编 号 0 1 2 3 4 中断源以及中断编号 中断源 外部中断0 定时器/计数器0溢出 外部中断 1 定时器/计数器1溢出 串行口中断 入口地址 BH BH 0023H 计算机科学与技术系例如编写定时器中断服务程序 unsig
void timer (void) interrupt 1 using 2 { if(++interruptcnt==4000) { /*计数到4000*/ second++; /*另一个计数器*/ interruptcnt=0; /*计数器清零*/ }} 计算机科学与技术系2.7 Keil C对单片机端口的定义/*-----------------------------------------------------------------REG51.H Header file for generic 80C51 and 80C31 microcontroller. Copyright (c)
Keil Elektronik GmbH and Keil Software, Inc. All rights reserved. ------------------------------------------------------------------*/ /* BYTE Register */ sfr P0 = 0x80; sfr P1 = 0x90; sfr P2 = 0xA0; sfr P3 = 0xB0; sfr PSW = 0xD0; sfr ACC = 0xE0; sfr B = 0xF0; sfr SP = 0x81; 计算机科学与技术系 sfr DPL = 0x82; sfr DPH = 0x83; sfr PCON = 0x87; sfr TCON = 0x88; sfr TMOD = 0x89; sfr TL0 = 0x8A; sfr TL1 = 0x8B; sfr TH0 = 0x8C; sfr TH1 = 0x8D; sfr IE = 0xA8; sfr IP = 0xB8; sfr SCON = 0x98; sfr SBUF = 0x99; /* IE */ sbit EA = 0xAF; sbit ES = 0xAC; sbit ET1 = 0xAB; sbit EX1 = 0xAA; sbit ET0 = 0xA9; sbit EX0 = 0xA8; /* IP */ sbit PS = 0xBC; sbit PT1 = 0xBB; sbit PX1 = 0xBA; sbit PT0 = 0xB9; sbit PX0 = 0xB8; 计算机科学与技术系/* BIT Register */ /* PSW */ sbit CY = 0xD7; sbit AC = 0xD6; sbit F0 = 0xD5; sbit RS1 = 0xD4; sbit RS0 = 0xD3; sbit OV = 0xD2; sbit P = 0xD0;/* TCON */ sbit TF1 = 0x8F; sbit TR1 = 0x8E; sbit TF0 = 0x8D; sbit TR0 = 0x8C; sbit IE1 = 0x8B; sbit IT1 = 0x8A; sbit IE0 = 0x89; sbit IT0 = 0x88; 计算机科学与技术系/* P3 */ sbit RD = 0xB7; sbit WR = 0xB6; sbit T1 = 0xB5; sbit T0 = 0xB4; sbit INT1 = 0xB3; sbit INT0 = 0xB2; sbit TXD = 0xB1; sbit RXD = 0xB0;/* SCON */ sbit SM0 = 0x9F; sbit SM1 = 0x9E; sbit SM2 = 0x9D; sbit REN = 0x9C; sbit TB8 = 0x9B; sbit RB8 = 0x9A; sbit TI = 0x99; sbit RI = 0x98; 计算机科学与技术系C51对标准C语言的扩展☆ 数据类型C51具有标准C语言的所有标准数据类型,除 此之外,为了更加有效的利用8051结构,还加入 了以下特殊的数据类型。 bit 位变量值为0或1。 sbit 从字节中声明的位变量0或1。 sfr 特殊功能寄存器,sfr字节地址为0~255 sfr 16 同sfr ,只是 sfr字地址为0~65535 计算机科学与技术系bit、sbit、sfrs和sfr16数据类型专门用于 8051硬件和C51编译器,并不是标准C语言的一 部分,不能通过指针进行访问。 bit、sbit、sfrs 和sfr16数据类型用于访问8051的特殊功能寄存 器,例如sfr P0=0x80,表示声明变量P0,并为 其分配特殊功能寄存器地址0x80。 当结果为不同的数据类型时,C51编译器自 动转换数据类型,例如位变量在整数分配中就被 转换成一个整数。除了数据类型的转换之外,带 符号变量的符号扩展也是自动完成的。 计算机科学与技术系☆2.8存储器形式与模式1、存储类型及存储区描述 C51编译器支持8051及其扩展系列,并提供 对8051所有存储区的访问。 存储区可分为内部数据存储区,外部数据存储区以 及程序存储区。8051CPU内部的数据存储区是可读写 的,8051派生系列最多可有256字节的内部存储区, 其中: 低128字节可直接寻址,高128字节(从0x80到0xFF) 只能间接寻址,从20H开始的16字节可位寻址。内部数据区又可分为3个不同的存储类型: data、idata、bdata。 计算机科学与技术系外部数据也是可读写的,访问外部数据区比 访问内部数据区慢,因为外部数据区是通过数据 指针加载地址来间接访问的。 C51编译器提供两种不同的存储类型xdata 和pdata访问外部数据。 程序CODE存储区是只读不写的。程序存储 区可能在8051CPU内或者在外部或者内外都有, 具体要看设计时选择的CPU的型号来决定程序 存储区在CPU内、外分布的情况;及根据程序 容量决定是否需要程序存储器扩展。 计算机科学与技术系C51程序设计时,每个变量可以明确地分配到指定的存储空间,定义变量 时参考表2-4。对内部存储器的访问比对外部存储器的访问快许多,因此 应当将频繁使用的变量放在内部数据存储器中,而把较少使用的变量放在 外部数据存储器中。各存储区的描述如表所示。表2-4存储区描述 述存储区 data bdata idata xdata pdata code描RAM的低128字节,可在一个周期内直接寻址 data区可字节、位混合寻址的16字节区 RAM区的高128字节,必须采用间接寻址 外部存储区,使用DPTR间接寻址 外部存储区的256字节,通过P0口的地址对其寻 址。使用指令MOVX @Rn,需要两个指令周期 程序存储区使用DPTR寻址 计算机科学与技术系 2、存储类型及存储区使用举例 1)DATA区:DATA区声明中的存储类型标识符为data。 DATA指低128字节的内部数据区。DATA区可直接寻 址,所以对其存取是最快的,应该把经常使用的变量放在 DATA区;但是DATA区的空间是有限的,DATA区除了包含 程序变量外,还包括了堆栈和存储器组。 举例: unsigned char data system_status=0;//定义无符号字符型 变量system_status,初值为0使其存储在内部低128字节 unsigned int data unit_id[2];//定义无符号整型数组 data unit_id,存储在内部RAM char data inp_string[16];//定义字符型变量 inp_string,使其存储在内部低128字节 计算机科学与技术系标准变量和用户自声明变量都可存储在DATA 区中,只要不超过DATA区范围即可。 2)bDATA区:bDATA区声明中的存储类型 标识符为bdata,指内部可位寻址的16字节储区 (20H到2FH)可位寻址变量的数据类型。 bDATA区实际就是DATA区中的位寻址 区,在这个区声明变量就可进行位寻址。位变量 的声明对状态寄存器来说是十分有用的,因为它 可能仅仅需要使用某一位,而不是整字节。 计算机科学与技术系在bDATA区中声明的位变量和使用位变量的例子: unsigned char bdata status_byte;//定义无符号字符型 变量 status_byte,使其存储20H到2FH区,可进行位寻址。 unsigned int bdata status_word;// 定义无符号整型变量 status_word,使其存储20H到2FH区 unsigned long bdata status_dword;//定义无符号长整型变量 status_dword,使其存储20H到2FH区 sbit start_flag=status_byte^4;//将status_byte的第4位赋值 给位变量sbit start_flag 计算机科学与技术系 ☆ 特殊功能寄存器(SFR) 51系列单片机提供128字节的SFR寻址区,地址为 80H-FFH。除了程序计数器PC和4组通用寄存器之外,其他 所 有的寄存器均为SFR,并位于片内特殊寄存器区。这个区域部 分可位寻址,字节寻址或字寻址,用以控制定时器,计数器, 串口,I/O及其他部件。特殊功能寄存器可由以下几种关键字 说明。 sfr: 声明字节寻址的特殊功能寄存器。比如sfrP0=0x80;表 示P0口地址为80H。注意:“sfr”后面必须跟一个特殊寄存器名;“=”后面 的地址必须是常数,不允许带有运算符的表达式,这个常数值 的范围必须在特殊功能寄存器地址范围内,位于0X80H到 0XFFH之间。 计算机科学与技术系sfr16:许多新的8051派生系列单片机用两个连 续地址的SFR来指定16位值,例如8052用地址 0XCC和0XCD表示定时器/计数器2的低和高字节。 如sfr16T2=0XCC;表示T2口地址的低字节地址 T2L=0XCC,高地址T2H=0XCD。 sfr16声明和sfr声明遵循相同的原则,任何符号 名都可用在sfr16的声明中。声明中名字后面不是 赋 值语句,而是一个sfr地址,其高字节必须位于低字 节之后,这种声明适用于所有新的SFR,但不能用 于定时/计数器0和计数器1。 计算机科学与技术系sbit:声明可位寻址的特殊功能寄存器和别的可位寻址的目标。 “=” 号后将绝对地址赋给变量名。sbit声明变量位寻址的声明形式如下: ① sbit 变量名=sfr_name^int_constant 如: sbit OV=PSW^2; //声明溢出位变量OV,是PSW的第2位 sbit P10=P1^0; //声明位变量P10,是P1口的第0位 该变量用一个已声明的sfr_name作为sbit地基地址,“^”后面 的表达式指定了位的位置,必须是0~7之间的一个数字。 计算机科学与技术系②sbit 变量名=int_constant^int_constant例如: sfr CY=0XD0^7; sbit OV=0XD0^2; sbit P10=0X90^0;该变量用一个整常数作为sbit的基地址,“^” 后 面的表达式指定位的位置,必须在0~7之间 。 计算机科学与技术系③sbit 变量名=int_constant例如: sbit OV=0XD2; sbit P11=0X91; 计算机科学与技术系若编程时已将8051微处理器头文件包含#include&reg51.h.& 则sfr PSW=0xD0; sfr IE=0xA8; sbit OV=PSW^2; 可以不用声明PSW为特殊功能寄存器, 因头文件中已定义。可直接在程序中使用PSW、IE、OV 等。但P1_0、P1_1是一个头文件中没有的变量,要求它指 向P1的第0位、第1位。所以使用时应定义 sbit P1_0=P1^0; sbit P1_1=P1^1; 注意:&reg51.h.&文件中的寄存器、特殊功能寄存器均是大 写。所以P1^0、P1^1中的P1一定要大写。但P1_0 、P1_1由 于是用户自定义变量,所以大小写随意,也可是其它标识符。 计算机科学与技术系☆ 存储器模式存储器模式是函数自变量、自动变量和没有明确规定存 储类型的变量的默认存储器类型,指定存储器需要在命令行 中使用SMALL,COMPACT和LARGE 3个控制命令中的1个。 例如:void fun(void)small{ }; ● SMALL : 在该模式中,所有变量都默认地位于51内部数 据存储器,这和使用data指定存储类型的方式一样。在此模 式下,变量访问的效率很高,但所有的数据对象和堆栈必须 适合内部RAM。确定堆栈的大小是很关键的,因为使用的 堆栈空间是由不同函数嵌套的深度决定的。通常,如果 BL51连接器/定位器将变量都配置在内部数据存储器内,则 SMALL模型是最佳选择。 计算机科学与技术系● COMPACT: 当使用COMPACT模式时,所有变量 都被默认为在外部数据存储的一页内,这和使用pdata指 定 存储器类型是一样的。该存储器类型适用于变量不超过 256 字节的情况,此限制是由寻址方式所决定的。和SMALL模 式相比,该存储器模型的效率比较低,对变量访问的速度 也慢一些,但比LARGE模式快。 ● LARGE : 在LARGE模式中,所有变量都默认为位于 外部存储器(这和使用xdata指定存储器类型是一样的), 并使用数据指针DPTR进行寻址。通过数据指针访问外部 数据存储器的效率较低,特别是当变量为2字节或更多字 节 时,该模式要比SMALL和COMPACT产生更多的代码。 计算机科学与技术系 ☆Keil C51的代码效率 C51程序编译生成汇编代码的效率,是由许多因素共 同决定的,对于Keil C51,主要受以下两种因素影响: 存 储模式的影响、程序结构的影响。1、存储模式的影响 存储模式决定了缺省变量的存储空间,而访问各空 间变量的汇编代码的繁简程度决定了代码率的高低。就 汇编之后的语句而言,对外部存储器的操作较内部存储 器操作代码率要低得多,生成的语句为内存的两倍以 上,而程序中有大量的这种操作,可见存储模式对代码 率的影响了。 计算机科学与技术系因此程序设计的原则是: 1)存储模式从small-Compact-large依次选择, 实在是变量太多,才选large模式。 2)即使选择了large模式,对一些常用的局部的 或者可放于内存中的变量,最好放于内存中, 以尽量提高程序的代码效率。 计算机科学与技术系2、程序结构的影响程序的结构单元包括模块、函数等等。同样的功能, 如果结构越复杂,其所涉及的操作、变量、功能模块函 数等就越多,较之结构性好,代码简单的程序其代码率 自然就低得多。此外程序的运行控制语句,也是影响代 码率的关键因素。 例如:switch -case语句,许多编译器都把它们译得非 常 复杂,Keil C51也不例外,相对较为简易的Switch-case 语句,编译成跳转指令形式,代码率较高,但对较为复 杂的Switch-Case,则要调用一个系统库函 数?C?ICASE 进行处理,非常复杂。 计算机科学与技术系再如if( )、while( ),等语句也是代码相对较低 的语句,但编译以后比switch-case要高得多。 因 此建议设计者尽量少用switch-case之类语句来 控 制程序结构,以提高代码率。除以上两点外,其 它因素也会对代码率产生影响。 计算机科学与技术系C51编译器能从C程序源代码中产生高度优化的代码, 而通过一些编程上的技巧又可以帮助编译器产生更好的 代码。下面总结了一些使用技巧: 1)使用短型变量 一个提高代码效率的最基本的方式就是减小变量的长度。 使用C语言编程时若对循环控制变量使用int类型,int型 数据为16位,这对8位单片机来说是一种极大的浪费。 如果使用unsigned char型的变量,它只使用一字节(8 位)。 计算机科学与技术系☆使用C51的技巧 C51编译器能从C程序源代码中产生高度优化的 代码,而通过一些编程上的技巧又可以帮助编译 器产生更好的代码。下面总结了一些使用技巧:1)使用短型变量 一个提高代码效率的最基本的方式就是减小变 量的长度。使用C语言编程时若对循环控制变量 使用int类型,int型数据为16位,这对8位单片机 来说是一种极大的浪费。如果使用unsigned char 型的变量,它只使用一字节(8位)。 计算机科学与技术系2)使用无符号类型 由于51单片机不支持符号运算,所以程序中也不要 使用带符号型变量的外部代码。除了根据变量长度来选 择变量类型外,还要考虑变量是否会出现负数,如果程 序中不需要负数,就可以把变量都声明成无符号类的。 3)使用位变量 对于某些标志位,应使用位变量而不是unsingned char 型变量,这将节省7位存储区,节省内存,而且在 RAM中访问位变量只需要一个处理周期。 计算机科学与技术系4)用局部变量代替全局变量 把变量声明成局部变量比声明成全局变量更 有效,因为编译器在内部存储区中为局部变量分 配存储空间,而在外部存储区中为全局变量分配 存储空间,这会降低访问全局变量的速度。用局部变量代替全局变量的原因是在中断系 统和多任务系统中,会有多个函数使用全局变 量,这需要在系统的处理中调节使用全局变量, 增加了编程的难度。 计算机科学与技术系 5)为变量分配内部存储区 经常使用的变量防在内部RAM中时,可使程序执行 的速度得到提高。除此之外,这样做还缩短了代码,因 为写外部存储区寻址的指令相对要麻烦一些,考虑到存 储速度,一般按下面的顺序使用存储器,既DATA, IDATA,PDATA,XDATA,同时要留出足够的堆栈空 间。 6)使用特定指针 在程序中使用指针时,应指定指针的类型,确定他 们指向哪个区域,如XDATA或CODE区,这样编译器就 不必去确定指针所指向的存储区,所以代码也会更加紧 凑。 计算机科学与技术系 7)使用宏替代函数 对小段代码,像使用某些电路或从锁存器中读取数据, 可通过宏来替代函数,以使程序有更好的可读性。也可以把 代码声明在宏中,这样看上去更像函数。编译器在碰到宏 时,按照事先声明好的代码去替代宏。宏的名字应能够描述 宏的操作。当需要改变宏时,只要在宏的声明处修改即可。 例如 #define led_on() { led_state=LED_ON; XBYTE[LED_CNTRL]=0x01; } 宏使得访问多层结构和数组更加容易,可以用宏来替 代 程序中经常使用的复杂语句,以减少工作量,并使程序具有 更好的可读性和可维护性。 计算机科学与技术系☆C51使用规范 为了增加程序的可读性,便于源程序的交 流,减少合作开发中的障碍,应当在编写C51程 序时遵循一定的规范。1、注释1)开始的注释文件(模块)注释内容:公司名称,版权, 作者名称,修改时间,模块功能,背景介绍等, 复杂的算法需要加上流程说明。 计算机科学与技术系例如: /**************************************************/ /*公司名称*/ /*模 块 名:LCD模块LCD型号:HD44780*/ /*创 始 人:zhaolang 日期:* /*修 改 人: 日期:*/ /*功能描述:*/ /*其他说明:*/ /*版本: /**************************************************/ 计算机科学与技术系2)函数开头的注释内容 函数名称,功能,说明,输入,返回,函数描述,流 程处理,全局变量,调用样例等,复杂的函数需要加上变 量用途说明。 /**************************************************/ * 函数名:v_LcdInit * 功能描述:LCD初始化 * 函数说明:初始化命令:0x3c,0x08,0x01,0x06,0x10,0x0c * 调用函数:v_Delaymsec(),v_LcdCmd() * 全局变量: * 输入 :无 * 返回 :无 * 设计者:zhao 日期: * 修改者:zhao 日期: * 版本: /**************************************************/ 计算机科学与技术系3)程序中的注释内容 修改时间和作者,方便理解的注释等。注释内容应简 练,清楚,明了,对一目了然的语句不加注释。 2、命名:命名必须具有一定的实际意义。 1)宏和常量的命名。宏和常量的命名规则:单词的字母全部大写,各单词之间用 下划线隔开。命名举例:#define MAX_SLOT_NUM #define EI_ENCR_INFO const int MAX_ARRAY 8 0x07 计算机科学与技术系2)标识符缩写缩写的几种技术:①去掉所有的不在词头的元音字母。screen写成scrn, primtive写成prmv。 ②使用每个单词的头一个或几个字母。如 Channel Activation 写成 ChanActiv, Release Indication写成RelInd。 计算机科学与技术系③使用变量名中每个有典型意义的单词。如 Count of Failure写成FailCnt。 ④去掉无用的单词后缀 ing, ed等。如Paging Request写成PagReq。 ⑤ 使用标准的或惯用的缩写形式(包括协议 文件中出现的缩写形式)。 如BSIC(Base Station Identification Code)、 MAP(Mobile Application Part)。 计算机科学与技术系缩写的准则: ①缩写应该保持一致性。如Channel不要有 时缩写成Chan,有时缩写成Ch,Length有 时 缩写成Len,有时缩写成len。 ②在源代码头部加入注解来说明协议相关 的、非通用缩写。 ③标识符的长度不超过32个字符。 计算机科学与技术系2)变量的命名:变量名加前缀,前缀反映变量的数据类 型,用小写。反映变量意义的第一个字母大写,其他小写。 例如:ucReceivData //无符号字符型接收数据 计算机科学与技术系3)函数的命名:函数名首字母大写,函数名若包含有两 个单词,则每个单词首字母大写。例如:PowerOnInitial( );InitialCpu( ); DelayX10ms( ) Timer40msDelay( )//打开电源的初始动作//初始微处理器内部缓存器 //10ms延时 //利用定时器产生40ms延时函数原形说明包括:引用外来函数及内部函数,外部 引用内必须在右侧著名函数来源(模块名及文件名),内 部函数只要注释其声明文件名。 计算机科学与技术系 3)函数的命名:函数名首字母大写,函数名若包含有两个 单词,则每个单词首字母大写。 例如:PowerOnInitial( ); //打开电源的初始动作 InitialCpu( ); DelayX10ms( ) //初始微处理器内部缓存器 //10ms延时Timer40msDelay( )//利用定时器产生40ms延时函数原形说明包括:引用外来函数及内部函数,外部 引用内必须在右侧著名函数来源(模块名及文件名),内 部函数只要注释其声明文件名。 计算机科学与技术系3.编辑风格 1)缩进:缩进以TAB为单位,一个TAB为4个空格大小。预处理语句, 全局数据,函数原形,标题,附加说明,函数说明,标号等均顶 格书写。语句块的“{”“}”配对对齐,并与其前一行对齐。 2)空格:数据和函数在其类型、修饰名称之前适当空格并据情况对 齐。关键字原则上空一格,如:if(…)等。运算符的空格规定: “-&”、“[”、“]”、“++”、“―”、“~”、“!”、“+”、“-” (指正负号)、“―”(取址或引用)、“*”(指使用指针时) 等几个运算符两边不空格(其中单目运算符系指与操作数相连的 一边),其他运算符(包括大多数二目运算符和三目运算符 “?:”两边均空一格。“(”,“)”运算符在其内侧空一格, 在作函数声明时还可根据情况多空或不空格来对齐,但在函数实 现时可以不用。“,”运算符在其后空一格,对语句行后加的注 释应用适当空格与语句隔开并尽可能对齐。 计算机科学与技术系3)对齐:原则上关系密切的行应对齐,对齐包括类型、修饰、 名称、参数等各部分对齐。另一个行的长度不应超过屏幕太 多,必要时适当换行。换行时进可能在“,”处或运算符处。 换行后最好以运算符打头,并且以下各行均以该语句首行缩 进,但该语句仍以首行的缩进为准,即如其下一行为“{”应 与首行对齐。4)空行:程序文件结构各部分之间空两行,若不必要也可只空 一行,各函数实现之间一般空两行。 5)修改:版本风存以后的修改一定要将旧语句用:“/**/”封闭, 不能自行删除或修改,并要在文件及函数的修改记录中加以 记录。 6)形参:在声明函数时,在函数名后面括号中直接进行形式参 数说明,不再另行说明。 计算机科学与技术系2.9 指针1.指针的概念 ?变量的指针-----在C语言中变量的指针 是该变量的地址。?指针变量-------用于存放变量的指针的变量称为指针变量。?2.指针变量的定义?C语言规定所有的变量在使用前必须定义,以确定其类型。 ?指针定义的一般形式为: ?类别识别符 [存储器类型] *指针变量名 (*表示该变量为指针变量)? 例如:char *s;?int */* string ptr */ /* int ptr */ 计算机科学与技术系 3.存储器指针 存储器的指针在定义时要包含一个存储器类型说明 。 例如:char data * /* 在data 区域的指向字符串的指针 */ 4.指针变量的引用 在对变量、指针变量定义之后,就可以用指针进行间接访问了。 下面举例说明。 int a; /*定义整型变量a */ a=10; /*给整型变量a 赋值为10*/ int * /* 定义指针变量sp */ sp=& /*通过取地址运算符&使sp指向变量a的 地址 */ x=* /*整型变量a的值10通过间接寻址的方法 赋给x */ 计算机科学与技术系一、 数据类型1. bit 类型 bit 数据类型可以定义一个位变量。 例如: bit flag1; /*定义flag1为位变量 */ 2. sbit、sfr和sfr16数据类型 编译器提供 sbit、sfrs和fr16数据类型访问SFR。 1) sfr 类型 定义1个8位的SFR 。 例如:sfr P0=0x80;/*定义 80C51P0口,地址为80h*/ 2)sfr16 类型 定义2个8位的SFR,将低字节的地址用作 sfr16声明的地 址。 例如:sfr16 T0=0x8A ; /* 定时器0(见第7章),TL0的 地址 为08Ah,TH0的地址为 08Bh */ 计算机科学与技术系3) sbit 类型 编译器用sbit数据类型访问可位寻址的SFR中的位。例如:sbit EA=0xAF; /* EA位的地址为0AFh */二、 数据的存储区类型 1.程序存储区 用code标识符访问片内、片外统一编址的程序存储区。 例如:char code text[ ]=“end”;/*在代码段定义了一个字符型数 组*/ 2.内部数据存储区 内部数据区可以分成三个不同的存储类型 data、idata 和bdata。 data 存储类型标识符通常是指低128字节的内部数据区 计算机科学与技术系? Idata 存储类型标识符是指全部256个字节的内部存储区,为片内间接寻址的RAM空间, ? Bdata 存储类型标识符是指可位寻址的16字节内部存储区(20H~ 2FH) ? 定义举例: ? Char data vr ;/*字符变量vr被定义为data存储类型*/ ? Flout idata x,y;/*浮点变量x,y被定义为idata存储类型*/ ? Bit bdata flags ;/*位变量flags被定义为bdata存储类型*/。 ? 3.外部数据存储区 ? 外部数据存储区是可读、可写的 ,外部数据存储区最多可有64KB。 两种不同的存储类型xdata 和 pdata用于访问外部数据。 ? xdata 存储类型标识符是指外部数据存储区(64KB)内的任何地 址 。 ? pdata 存储类型标识符仅指一页或256 字节的外部数据存储区 。 计算机科学与技术系在变量的声明中,可以包括存储器类型和有 符号signed或无符号unsigned属性。 例如: char data var1; char code text[ ] = &ENTER PARAMETER&; unsigned long xdata array[100]; float idata x,y,z; unsigned unsigned char xdata vector[10][4][4]; 计算机科学与技术系三、 存储模式1.小(SMALL)模式存储速度 有区别在这种模式下,所有变量都默认定义在内部数据存 储器中。 2.紧凑(COMPACT)模式 在这种模式下,所有变量都默认存放在外部数据存 储器的一页中 。 3.大(LARGE)模式 在大模式下,所有的变量都默认在外部数据存储器 (xdata)中 计算机科学与技术系四、 C51语言对单片机硬件的访问1.访问特殊功能寄存器 例如: #include&reg51.h& /*包含寄存器头文件 */ P0=0; /*将端口P0全部设为低电平,就可不 写sfr P0=0x80了*/ int in1; /*定义一个整型变量in1 */ int in2; /*定义一个整型变量in2 */ in1=P0; /*读取端口0中的数据到变量in1中*/ in2=TL0; /*读取定时器0 TL0中的数据到变量 in2中*/ 计算机科学与技术系2.访问存储器 对绝对地址的访问主要有3种形式。 1)采用C51中的预定义宏 C51编译器提供了8个宏定义用于对存储器进行绝对寻址,其函数原型为: #define CBYTE ((unsigned char volatile code *) 0) #define DBYTE ((unsigned char volatile data *) 0)…….等 例如:#include&reg51.h& /*包含寄存器头文件 */ #include&absacc.h& /*包含绝对地址头文件 */ #define uchar unsigned char /*定义符号uchar为数据类型符unsigned char */ #define uint unsigned int /*定义符号uint为数据类型符unsigned int */ void main (void) { uchar var1; uint var2; var1= DBYTE[0x30];/*把data区中30h地址单元中的数赋给var1 */ var2= XBYTE[0x1000];/*把xdata区中1000h地址单元中的数赋给 var2 */ ……. } 计算机科学与技术系2)通过指针访问例如: uchar data var1; uchar data *dp1;/*定义一个data区中指针dp1 */ uint xdata *dp2;/*定义一个xdata区中指针dp2 */ uchar pdata *dp3;/*定义一个pdata区中指针dp3 */ dp1=&var1; /*取data区中变量var1的指针 */ *dp1=0xa0; /*给变量var1赋值a0h */ dp2=0x2000; /* dp2指针赋值,指向xdata区的2000h */ *dp2=0x16; /*将数据16h送到片外RAM区的2000h单元 */ dp3=0x20; /* dp3指针赋值,指向pdata区的20 h */ *dp3=0x80; /*将数据80h送到pdata区的20h单元*/ 计算机科学与技术系3)采用扩展关键字_at_ 采用扩展关键字_at_访问存储器绝对地址 的一般格式如下: [存储器类型] 数据类说明符 变量名 _at_ 地址常数 例如: data uchar x1 _at_ 0x20;/* 在data区 中定义字符变量的地址为20 h */ xdata uint x2_at_ 0x2000;/*在xdata区 中定义整数变量的地址为2000 h */ 计算机科学与技术系3.访问外围接口器件地址 例如:假设一块8255A芯片的命令口地址确定为ffadh,A口 地址确定为ffaah,那么在程序中可以如下编制: #define PD8255 XBYTE [0xffad] /* 命令口地址在片 外RAM的ffadh */ #define PA8255 XBYTE [0xffaa] /* A口地址在片外 RAM的ffaah */ ……… PD; /* 给命令口赋值 */ PA8255=0XFF; /* 给A口赋值*/ 计算机科学与技术系2.10 C语言与汇编语言的混合编程2.10.1 C语言与汇编语言混合编程注意事项为了创建有正确接口的汇编语言子程序,必须注 意以下几个问题: 1. 函数名的命名规则 2. 函数段名的命名规则2.10.2 带参数传递的函数调用1. 参数传递规则 2. 函数返回值2.10.3无参数传递的函数调用 计算机科学与技术系 2.10.4 混合编程举例例1:设主函数的作用就是调用一个加法子程序CAL,此加法子 程序用汇编语言编写,其加法参数在主程序中。main.c和 cal.asm为项目中的两个文件,c文件 main.c 如下: #define uint unsigned int #include &REG51.H& extern unsigned int cal(unsigned int m,n); /*声明外部函 数cal为有参数调用*/ /*定义myint为无符号整型变量 */ void main(void) { myint= 0; /*变量清零 */ myint = cal(); /*调用外部函数计算;结果为3052 */ while(1); /*延时等待 */ } 计算机科学与技术系汇编子程序cal.asm如下: ?PR?_cal?CAL SEGMENT CODE ; 在程序存储区中定义段, CAL为段名,?PR?表示段位于程序存储区内 PUBLIC _cal ;声明函数为公共函数 RSEG ?PR?_cal?CAL;函数可被连接器放置在任何地方 _cal: ; R6,R7 为m值(2000),R4,R5为n值(1052) MOV A,R7; ADD A,R5; MOV R7,A; MOV A,R6; ADDC A,R4; MOV R6,A; 计算结果放在R6,R7中(3052) RET END
2、 掌握 C51 语言的数据类型、常量和变量、运算符和表达式 第4章 Cx51 流程控制语句 一& 教学内容: 1、 C51 程序的基本结构及流程图 2、 程序设计的步骤。...单片机原理与 C51 语言程序设计与基础教程 课后习题答案 习题 填空题 1 .一般...2.首先,大概了解单片机的机构,例如本书的第 2 章则是主要讲了单片机的内部...第三章 第三章 Keil C 语言及其程序设计 C51 是在标准 C 的基础上,根据单片机存储器硬件结构及内部资源,扩展了 扩展了 相应的数据类型和变量,而 C51 在语法...6 ***单片机 C 语言复习总结***【机电】 第2章 C51 语言程序设计基础 1.哪些变量类型是51单片机直接支持的? C51编译器支持的数据类型有:位型(bit)、无符号...第2章 MCS-51单片机的结... 第3章 KeilC语言及其程序... 第4章 Keil开发...扩展了 相应的数据类型和变量,而 C51 在语法规定、程序结构与设计方法上,都与...4 第2章 C51 语言程序设计基础 1.哪些变量类型是51单片机直接支持的? .哪些变量类型是 单片机直接支持的 单片机直接支持的?答:C51编译器支持的数据类型有:位型(....2 CPU 取指令、执行指令周期时序 第3章 C51 程序设计 3.1 C51 程序设计基础...语言程序设计中容易出错的地方 9.2.2 有关 C5l 的若干实际应用技巧 9.3 MCS-...Keil C51软件使用详解(第二章)_信息与通信_工程科技...* 高级语言显示模式 * 集成硬件环境模拟 * 单步或...(2) 带 5K 外部程序存储器(从 O 地址开始),...单片机原理与应用及C51程序设计第4章习题答案_工学_高等教育_教育专区。第 4 章习题答案 4-2 有哪里些数据类型是 MCS-51 系列单片机直接支持的? 答:见 P89,...第2章 C51的数据类型_教学案例/设计_教学研究_教育专区。第2章 C51 的数据类型 C 语言是一种编译型程序设计语言,兼顾了许多高级语言的特点和一定的汇编语言功 ...
All rights reserved Powered by
copyright &copyright 。文档资料库内容来自网络,如有侵犯请联系客服。

我要回帖

更多关于 未结束的字符串常量 的文章

 

随机推荐