资源预览内容
第1页 / 共64页
第2页 / 共64页
第3页 / 共64页
第4页 / 共64页
第5页 / 共64页
第6页 / 共64页
第7页 / 共64页
第8页 / 共64页
第9页 / 共64页
第10页 / 共64页
亲,该文档总共64页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第2章 单片机的C语言程序设计 及仿真调试本章节主要内容2.1 C51程序设计中的常用功能及应注意的问题2.2 Keil C 和 ANSI C2.3 STC15F2K60S2单片机C语言程序调试2.4 利用ISP工具将程序下载到单片机中验证程序2.1 C51程序设计中的常用功能及应注意的 问题l2.1.1 C51程序设计中的常用典型功能l2.1.2 C51程序编写中应注意的问题2.1.1 C51程序设计中的常用典型功能 C语言功能l1、逻辑运算和位运算逻辑运算符 l与运算符(char code array =“hello!”;unsigned char xdata arr1044; Keil C51扩展关键字l_at_关键字:若要实现变量的绝对定位( 称为绝对变量),可以直接在数据定义后 加上“_at_ 常数地址”即可,注意: 绝对变量不能被初始化; bit型函数及变量不能用_at_指定。例如:lunsigned char idata ADCdata _at_ 0x40; / 指定ADCdata变量在40H处lunsigned char xdata buffer20 _at_ 0x0010;/指定buffer数组从XRAM的0010H单元开始Keil C51扩展关键字l存储模式:有Small、Compact和Large三种模式;存 储模式可在Keil C51编译器选项中选择,如下图所示: 指定存储模式lSmall模式:在该模式中所有 变量都默认位于单片机内部数据存 储器,此模式访问变量的效率很高 ,缺点是空间有限,只适用于小程 序;lCompact模式:所有缺省变 量均位于外部RAM区的一页内( 256字节),这和使用pdata指定存 储器类型一样,该模式空间比 Small宽裕,速度比Small慢,比 large快,是一种中间状态;lLarge模式:所有缺省变量可 放在多达64KB的外部RAM区,这 和使用xdata 指定存储器类型一样 ,使用数据指针DPTR 进行寻址。 通过数据指针访问 外部数据存储 器的效率较低,特别是当变量为2 个字节或更多字节时。该模式的 数据访问比Small和Compact产生更 多的代码。优点是空间大,可存 变量多,缺点是速度较慢。Keil C51扩展关键字l变量或数据类型 2.2 Keil C 和 ANSI Cl2.2.1 Keil C51扩展关键字l2.2.2 扩展I/O口的使用l2.2.3 Keil C51函数l2.2.4 STC15F2K60S2单片机C51程序 框架2.2.2 扩展I/O口的使用l由于使用C语言访 问外部I/O时用到指针 的功能,因此,首先 介绍Keil C51的指针 。l1Keil C51指针Keil C51支持一般指针(Generic Pointer)和存储器指针(Memory Specific Pointer)。一般指针的声明和使 用均与标准C相同,同时还可以说明指针的 存储类型。例如,下面的语句都声明pt为指 向保存在外部RAM中unsigned char数据 的指针,但pt本身的保存位置却不同:lunsigned char xdata *pt;/pt本身依存储模式存放lunsigned char xdata * data pt; /pt被保存在内部RAM中lunsigned char xdata * xdata pt; /pt被保存在外部RAM中一般指针本身用3个字节存放,分别为存储 器类型,高位偏移,低位偏移量。基于存储器的 指针,说明时即指定了存储类型,这种指针存放 时,只需一个字节或2个字节就够了,因为只需存放偏移量。例如: lchar data * str; /str指向data区中char型数据lint xdata * pow; /pow指向外部RAM的int型整数。关于堆栈指针SP的 设定l一般情况 下,用户不需要在C 语言程序中修改堆栈 指针SP,但要关心一 下SP的位置 ;lC51是在 startup.A51中设置SP 指针的,用CODE选 项生成的汇编代码中 是找不到这段代码的 。startup.A51是C51 的初始化代码,单片 机复位后先执行这段 代码,完成初始化后 由它调用main( )函数 。特殊需要时,可以 修改这段代码,然后 连接到用户的程序中 去。扩展I/O口的使用l2外部扩展I/O口的访问方法1:使用自定义指针。由于片外I/O端口 与片外存储器统一编址,所以可以定义xdata类 型的指针访问外部I/O端口。l例如,某单片机应用系统中,使用8255扩展 I/O端口,采用线选法对8255进行地址译码,单片机 的P2.7(A15)接8255的片选引脚,则8255的命令 字地址为7FF3H,PA口地址为7FF0H,PB口地址为 7FF1H,PC口地址为7FF2H,访问8255的C程序如 下: l写端口程序:char xdata *com8255; /定义指向外部存储区 的指针com8255=0x7FF3; /使指针指向8255的控制口 口地址7FF3H*com8255=0x81; /输出81H到端口l读端口程序:char xdata *com8255;/定义指针com8255=0x7FF0; /使指针指向8255的PA口口 地址7FF0Hchar i;i=*com8255; /读PA端口到变量i扩展I/O口的使用l2外部扩展I/O口的访问方法2:使用C51预定义指针。为了方便地访问外部存储器及I/O 端口,在C51中的absacc.h头文件做了如下定义,利用这些定义可以 方便地访问外部I/O端口。l#define CBYTE (unsigned char volatile code *) 0)l#define DBYTE (unsigned char volatile data *) 0)l#define PBYTE (unsigned char volatile pdata *) 0)l#define XBYTE (unsigned char volatile xdata *) 0)l例如:#include #define PORTA XBYTE 0x7FF0 /其中,PORTA为程序定义的I/O端口名称,内的内容7FF0H为 PORTA的地址void main(void)char a;PORTA=0x81; /输出81H到端口7ff0Ha=PORTA; /读端口7ff0H到变量a2.2 Keil C 和 ANSI Cl2.2.1 Keil C51扩展关键字l2.2.2 扩展I/O口的使用l2.2.3 Keil C51函数l2.2.4 STC15F2K60S2单片机C51程序 框架2.2.3 Keil C51函数 lC51的程序结构:C51的程序也是从main()函数(主函数)开始执行的,主函 数是程序的入口; 主程序中的main()主函数可以根据不同需求来调用不同的 函数。被调用的函数可以是编译器提供的库函数,也可以是用 户自己编制设计的函数; 当函数执行完毕的时候,就会发出返回指令,主程序中语 句执行完毕,整个程序也完毕; 但在一般的设计中,主程序都是一直循环,不断的重复执 行。因此,一般在主程序中使用while(1)语句构成无限循环; 在构成C51语言程序的若干函数中,有并且只能有一个主 函数。在C51中定义主函数时,要求主函数没有参数,并且没有 返回值; 除此之外,C51的函数声明对ANSI C作了扩展。 Keil C51函数lC51的函数声明对ANSI C的扩展中断函数声明 l中断函数通过使用 interrupt关键字和中断号来声明。 中断号告诉编译器中断服务程序的 入口地址。STC15F2K60S2单片机 的中断号及中断服务程序入口地址 如下表所示。l例如,串行口1的中断函数 可以声明如下: void UART1_ISR (void) interrupt 4 using 1 /* 中断服务程序的代 码 */ Keil C51函数lC51的函数声明对ANSI C的扩展指定工作寄存器区l当需要指定函数中使用的工作寄存器区时, 使用关键字using后跟一个0到3的数,对应着工作寄 存器0到3区。例如,在下面的函数中使用了工作寄 存器1区(相当于PSW.4=0,PSW.3=1):unsigned char GetKey(void) using 1/*用户程序代码*/ Keil C51函数lC51的函数声明对ANSI C的扩展指定存储模式 l用户可以使用small,compact 及large说明 存储模式。例如:void fun1(void) small l提示:small说明的函数内部变量全部使用内 部RAM。关键的、经常性的、耗时的地方可以这样 声明,以提高运行速度。Keil C51函数lC51的函数声明对ANSI C的扩展函数的参数传递规则 l最多只能有3个参数通过寄存器传递,规律如 下表所示:Keil C51函数lC51的函数声明对ANSI C的扩展函数返回值的规定 l函数返回值一律放于寄存器中,规则如下表 所示: Keil C51函数lC51的库函数C51的本征库函数只有9个,数目虽少,但都非常有用,列如下 : _crol_,_cror_:将char型变量循环向左(右)移动指定位数后返 回 _iror_,_irol_:将int型变量循环向左(右)移动指定位数后返回 _lrol_,_lror_:将long型变量循环向左(右)移动指定位数后返回 _nop_: 相当于插入NOP _testbit_: 相当于JBC bitvar测试该位变量并跳转同时清除。 _chkfloat_: 测试并返回源点数状态。 使用时,必须包含#inclucle “intrins.h”一行。Keil C51函数lC51的库函数例如, char a,b; a = 0xA5; b = _crol_(a,3); /执行完后,b变为0x2D 再如, bit test_flag; if (_testbit_ (test_flag)printf (“Bit was setn“); elseprintf (“Bit was clearn“);Keil C51函数l几类重要库函数 1)专用寄存器include文件 2)绝对地址include文件absacc.h 该文件中实际只定义了几个宏,以确定各存储空间的绝对 地址。在程序中,用#include “absacc.h”即可使用其中定义的宏 来访问绝对地址,包括: CBYTE、XBYTE、PWORD、DBYTE、CWORD、XWORD、 PBYTE、DWORD 例如: rval=CBYTE0x0002; /指向程序存贮器的0002h地址 rval=XWORD 0x0002; /指向外RAM的0004h地址,WORD 是一个字,两个字节,故为0004h #define COM8255 XBYTE0X060FFKeil C51函数l几类重要库函数 3)动态内存分配函数,位于stdlib.h中 4)缓冲区处理函数位于“string.h”中 其中包括拷贝比较移动等函数如: memccpy memchr memcmp memcpy memmove memset 这样很方便地对缓冲区进行处理。 5)输入输出流函数,位于“stdio.h”中 流函数通过8051的串口或用户定义的I/O口读写数据,缺省为串 口。2.2
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号