版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
任课教师:刘忠国山东大学课程中心网站:
/G2S/stcmcu.cc宏晶官方网站:STC单片机编译(汇编)/编程(烧录)/仿真工具说明书;stc15系列单片机器件手册等keilμvision软件下载及指导手册(Help→μvisionHelp)/KeilSoftware–Cx51编译器用户手册:Cx51编译器--对传统和扩展的8051微处理器的优化的C编译器和库参考1第五章单片机的C语言程序设计及仿真调试本章学习目标掌握单片机C语言程序中的常用功能掌握KeilC的程序设计掌握STC15F2K60S2单片机C语言程序调试过程2第五章单片机的C语言程序设计及仿真调试目录§5.1单片机C语言程序中的常用功能5.1.1逻辑运算和位运算5.1.2
预处理§5.2KeilC和ANSIC5.2.1KeilC51扩展关键字5.2.2扩展I/O口的使用5.2.3KeilC51函数5.2.4
STC15F2K60S2单片机C51程序框架§5.3单片机C语言程序调试3汇编语言和C语言的选择问题设计规模较小的嵌入式应用系统时,可以使用汇编语言。因为代码一般不长,且较简单。当程序比较复杂,且没有很好的注释时,使用汇编语言编写的程序,可读性和可维护性会很差,代码的可重用性也比较低。使用C语言编程,编写简单、直观易读、便于维护、通用性好。在控制任务比较复杂或者具有大量运算的系统中,C语言优势明显。由于模块化,用C语言编写的程序具有很好的可移植性。4§5.1单片机C语言程序中的常用功能5.1.1逻辑运算和位运算1、逻辑运算符逻辑运算符包括与(&&),或(||),非(!)3种,用于逻辑运算。逻辑运算符的表达式,返回0表示“假”,
返回1表示“真”。5与运算符(&&)功能:两个条件同时满足时(即两个条件都为真时),结果才为真。如一个程序在同时满足条件a<10和b==7时,则执行某些操作,应使用关系运算符和逻辑与运算符(&&)来写这个条件的代码:(a<10)&&(b==7)。按布尔逻辑值(真假)运算1、逻辑运算符或运算符(||)功能:检查两个条件中是否有一个为真,只要有一个条件为真,运算结果就为真。对条件a<10和b==7,若任一条件为真,程序执行某操作,则条件代码为:
(a<10)||(b==7);6逻辑非运算符(!)功能:表示对表达式的真值取反。例如,如果变量s小于10,程序需执行某些操作,则条件代码如下:(s<10)
也可以写成:(!(s>=10))//s不大于等于102、位运算符很多系统程序常要求进行位(bit)运算或处理。C语言提供了六种位运算符:按位与(&)、按位或(|)、按位异或(^)、取反(~)、左移(<<)和右移(>>)
。7(1)按位“与”运算:
按位与运算符“&”是双目运算符。功能:参与运算的两数各对应二进制位相与。只有对应的两位均为1时,结果位才为1,否则为0。例如,9&5的算式:00001001&00000101=00000001按位与运算通常用来对某些位清0或保留某些位。例把16位数a的高8位清0,保留低8位,可作运算:a&255(255的二进制数为0000000011111111)。(2)按位“或”运算按位或运算符“|”是双目运算符。功能是参与运算的两数各对应的二进制位相或。只要对应的两个位有一个为1时,结果位就为1。例如,9|5的算式:00001001(十进制为9)
|00000101(十进制为5)00001101(十进制13)或运算通常用来对某些位置1。8(3)按位“异或”运算按位异或运算符“^”是双目运算符。功能是参与运算的两数各对应的二进制位相异或。当两个对应的位相异时,结果为1。例如,9^5的算式:00001001(十进制为9)
^00000101(十进制为5)00001100(十进制12)异或运算通常用来对某些位取反。9(4)求反运算求反运算符“~”为单目运算符,具有右结合性。功能是对参与运算的数的各二进制位按位求反。例如,~9的运算为:~(0000000000001001)结果为:111111111111011010(5)左移运算左移运算符“<<”是双目运算符。功能:把“<<”符左边运算数的各二进制位都左移若干位,
“<<”符右边的数指定移动位数,高位丢弃,低位补0。例如:a<<4
指把a的各二进位向左移动4位。如a=00000011(十进制3),
左移4位后为00110000(十进制48)。(6)右移运算右移运算符“>>”是双目运算符。功能是把“>>”左边的运算数的各二进制位全部右移若干位,“>>”右边的数指定移动的位数。例如,设a=15,a>>2000001111右移2位为00000011(十进制3)。对于有符号数,在右移时,符号位将随同移动。当为正数时,最高位补0,而为负数时,符号位为1,最高位是补0或是补1取决于编译系统的规定。115.1.2预处理以“#”号开头的命令是预处理命令。C语言的预处理功能包括宏定义#define,文件包含#include,条件编译等。合理地使用预处理功能,可以使得编写的程序便于阅读、修改、移植和调试,也利于模块化程序设计。121、宏定义(#define)在C语言源程序中允许用一个标识符来表示一个字符串,称为宏。被定义为宏的标识符称为宏名。在编译预处理时,对程序中所有出现的宏名,都用宏定义中的字符串去代换,这称为宏代换或宏展开。宏代换是由预处理程序自动完成的。在C语言中,宏分为有参数和无参数两种。(1)无参宏定义无参宏的宏名后不带参数。其定义的一般形式为:#define标识符字符串其中,标识符为所定义的宏名。字符串可以是常数,表达式,格式串等。若要终止宏定义,可用#undef命令:#undef标识符符号常量的定义就是一种无参宏定义。此外,常对程序中反复使用的表达式进行宏定义。13例如:#definePI3.14159#define
M(y*y+3*y)程序中的语句:L=2*PI;s=3*M+M/2;经宏代换后为:L=2*3.14159;s=3*(y*y+3*y)+(y*y+3*y)/2(2)带参宏定义在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。带参宏定义的一般形式为:#define
宏名(形参表)
字符串14在字符串中含有各个形参。例如:#defineMAX(a,b)(a>b)?a:b
//取a和b的最大数例如,程序中的语句:max=MAX(x,y);
经宏代换后为:max=(x>y)?x:y;带参宏调用的一般形式为:宏名(实参表);2、文件包含(#include)文件包含的一般形式为:
#include"文件名"功能是把指定文件插入该命令行位置取代该命令行,从而把指定的文件和当前的源程序文件连成一个源文件。15说明:(头)文件名可用双引号括起来(用户头文件),也可用尖括号括起来(系统头文件)。如:#include“stdio.h”,#include<math.h>。二者区别:用尖括号表示在包含文件目录中去查找(包含目录可由用户在开发环境中设置,一般在\INC\),而不在源文件目录去查找;用双引号则表示首先在当前源文件目录中查找,若未找到才到包含目录中去查找。3、条件编译条件编译就是按不同的条件去编译不同的程序部分,从而产生不同的目标代码文件。条件编译对于程序的移植和调试(可以分段调试)非常有用。特别在操作系统的裁减中,经常使用条件编译。16(1)第一种形式:#ifdef标识符程序段1#else
程序段2#endif功能是:如果标识符已被#define命令定义过,则对程序段1进行编译;否则对程序段2进行编译。如果没有程序段2(它为空),本格式中的#else可以没有。3、条件编译(2)第二种形式:
#ifndef标识符程序段1#else
程序段2#endif功能是:如果标识符未被#define命令定义过则对程序段1进行编译,否则对程序段2进行编译。这与第一种形式的功能正相反。173、条件编译(3)第三种形式:
#if常量表达式程序段1#else
程序段2#endif功能是,如果常量表达式的值为真(非0),则对程序段1进行编译,否则对程序段2进行编译。因此可以使程序在不同条件下,完成不同的功能。18§5.2KeilC和ANSICKeilC51基本语法与ANSIC相同,针对8051内核单片机硬件等进行了扩展。5.2.1KeilC51扩展关键字(共19个)
_at_,sbit,sfr,bit,sfr16,code,idata,bdata,data,
xdata,pdata,small,compact,large,using,reentrant,interrupt,alien,_task_,
19(或参考keil官网/support/man/docs/c51/)(参考keil软件帮助文件bookswindow→Cx51CompilerUser'sGuide)(或参考“keilsoftwareCx51编译器用户手册09.2001-对传统和扩展的8051微处理器的优化的C编译器和库参考”)(keil帮助文件介绍21个)_priority_,far下面分类介绍常用关键字:alien(声明与Intel编译器PL/M51兼容的函数)。far声明3字节扩展地址。_task_,_priority_分别定义实时多任务操作系统的实时任务及其优先级。1、存储区域(MemoryAreas)
(1)程序存储器8051结构支持几个物理分开的程序和数据存储空间,这些存储空间可能:可读不可写;可读写;读写比别的存储空间快。(1)程序存储器:程序(CODE)存储区只读不能写,可在8051CPU片内或片外或都有,根据8051派生硬件决定,STC15F2K60S只在片内。最多可有64K字节的程序存储区。存储程序代码,包括所有函数和库,常数变量。8051可执行程序只保存在程序存储区。C51编译器中,通过存储类型标识符code可访问程序存储器。20关键字1、存储区域(MemoryAreas)(1)程序存储器(1)程序存储器:通过存储类型标识符code可访问程序存储器。code用来限定常量或函数的存储类型,而程序的函数默认为code存储类型,并不需code限定符(也可写上)。code一般只用来定义常量,例:staticcodeunsignedcharDPY_TAB[16]={0X3f,0X06,0X5b,0X4f,0X66,0X6d,0X7d,0X07,0X7f,0X6f,0X77,0X7c,0X39,0X5e,0X79,0X71};
//
用code定义共阴极数码管显示0~9,A~F时对应的字模21关键字1、存储区域(MemoryAreas)
(2)内部RAMdata:直接寻址区,内部RAM的低128字节,地址范围是:00H~7FH。idata:间接寻址区,包括整个内部RAM区,256字节,地址范围为00H~0FFH。bdata:可位寻址区,地址范围为20H~2FH。22(2)内部RAM数据存储器。位于51片内,可读写。根据51种类不同,最多256字节。低128字节可直接寻址,而高128字节只能间接寻址。可用以下关键字分为3种存储类型:特殊功能寄存器(0x80~0xFF)单独一类,见后。1、存储区域(MemoryAreas)(3)外部数据存储器(3)外部数据存储器:可读写。采用数据指针访问,比访问内部数存要慢,最多可达64K字节。外部RAM可由以下关键字标识分为2种存储类型::xdata:可指定多达64KB的外部直间接寻址区,地址范围0000H~0FFFFH。23xdata可访问外部数存64K字节的任意位置,只能通过数据指针(MOVX@DPTR)来访问。pdata:可访问外部数存的一页即256字节,通过R0和R1(MOVX@Ri)来访问(有时可能需P2指出高8位地址)。51对外设采取统一编址,外设也占用此空间,可通过访问外部数存来控制外设----存储器映射I/O,所以可用空间可能不足64K字节。(对物理上(且逻辑上)在外部的数存)。(片内XRAM只能访问00-0FFh)。在Xtal(MHz)右侧框输入6,其余按默认设置。4-10-2KeilμVision集成开发环境调试汇编语言程序方法Project窗口,选中Target1,并单击右键,出现浮动菜单。浮动菜单中选中OptionsforTarget‘Target1’...选项。24*出现OptionsforTarget‘Target1’对话框界面。在该界面中,点击Target标签。在该标签界面中,按下面设置参数:在此设置使用晶振的频率3.针对目标硬件设置工具选项MemoryModel右侧下拉选择:Small,Compact,large。1、存储区域(MemoryAreas)
存储模式(Small,large,Compact)数据存储类型的指定:变量或函数参数存储类型可由存储模式
(Small,large,Compact)(OptionsforTarget‘Target1’...选项)指定缺省存储类型;在small模式下,函数参数和局部变量位于由data定义的单片机片内数据RAM(00~7FH)中;在compact模式下,函数参数和局部变量位于pdata定义的扩展数据RAM中(访问用MOVX@Ri)。在large模式下,函数参数和局部变量位于xdata定义的扩展数据RAM中(访问用MOVX@DPTR)25数据1、存储区域(MemoryAreas)
存储模式(Small,large,Compact)数据存储类型的指定:变量或函数参数存储类型可由存储模式(Small,large,Compact)(OptionsforTarget‘Target1’...选项)指定缺省存储类型;也可由关键字code、data、idata、bdata、xdata、pdata直接声明指定。例如:unsignedchardatabuffer;
charcodearray[]=“hello!”;
unsignedcharxdataarr[10][4][4];26数据1、存储区域(MemoryAreas)
(4)特殊功能寄存器(4)特殊功能寄存器(SFR)(128字节:0x80~0xFF)单片机特殊功能寄存器(SFR)可位寻址,字节寻址或字寻址,用来控制定时器,计数器,串口,I/O及其他部件。通过关键字sfr,sfr16和sbit声明数据类型,访问SFR。27sfr:字节寻址。语法如下:
sfr
sfr_name=int_constant;如sfr
P0=0x80;
0x80为P0口寄存器的地址,
“=”
后为常数用来指定地址,且其范围必须位于80H到~FFH。sfr16:字寻址。
如sfr16DPTR=0x82;指定DPTR地址DPL=0x82,DPH=0x83。(4)特殊功能寄存器(SFR)(128字节:0x80~0xFF)sbit:位寻址用于声明可位寻址的特殊功能寄存器位变量,三种方法:28方法1:sbitbitname=sfr_name^bit_number;
sfr_name必须是已定义SFR的名字,bit_number是位号(0~7)。如:sbitCY=PSW^7;//定义CY为PSW的第7位。方法2:sbitbitname=sfr_address^bit_number;
sfr_address是SFR所在地址(0x80~0xff),bit_number是位号(0~7)。如:sbitOV=0xD0^2;//定义PSW中的OV位方法3:sbitbitname=bit_address;其中,bit_address是位地址。如:sbitEA=0xAF;//第0xAF位为IE寄存器的EA位
(见46页特殊功能寄存器SFR中位地址)IE位地址AFHAEHADHACHABHAAHA9HA8H寄存器IE位名称EAELVDEADCESET1EX1ET0EX0IE字节地址A8H*位寻址区--图3-11特殊功能寄存器SFR中位地址特殊功能寄存器中位地址范围:80H~0FFH。图3-11特殊功能寄存器中的位地址291、存储区域(MemoryAreas)(4)特殊功能寄存器KeilCx51没有预先定义SFR的名字,而是提供了一个包含所有特殊功能寄存器和它们的位定义的头文件reg51.h(在安装文件夹...\Keil\C51\INC)。通过包含头文件可很容易的进行新的扩展。附录C提供了STC15F2K60S2单片机的头文件stc15.h的内容,其中包含了标准8051单片机寄存器的定义,编程时只需包含这一个文件即可。该文件可从www.mcu001stcmcu.com中下载。在STC新ISP软件V6.85I中选择菜单选项“头文件”即可找到STC各系列的头文件(包括stc15.h)。301、存储区域(MemoryAreas)(4)特殊功能寄存器STC15F2K60S2单片机的头文件stc15.h的内容,31/*---------8051内核特殊功能寄存器-------------*/sfr
ACC=0xE0;//累加器sfr
B=0xF0; //B寄存器sfr
PSW=0xD0;//程序状态字寄存器sbit
CY=PSW^7; //进位标志位sbit
AC=PSW^6;//辅助进位标志位sbit
F0=PSW^5; //用户标志位0sbit
RS1=PSW^4;//工作寄存器组选择控制位sbit
RS0=PSW^3;//工作寄存器组选择控制位sbit
OV=PSW^2;//溢出标志位sbitF1=PSW^1; //用户标志位1sbit
P=PSW^0; //奇偶标志位sfr
SP=0x81; //堆栈指针寄存器sfr
DPL=0x82; //数据指针0低字节sfr
DPH=0x83; //数据指针0高字节/*------------系统管理特殊功能寄存器-------------*/sfrPCON=0x87; //电源控制寄存器sfrAUXR=0x8E;//辅助寄存器sfrINT_CLKO=0x8F;//外部中断和时钟输出控制寄存器sfrAUXR1=0xA2;//辅助寄存器1sfrCLK_DIV=0x97;//时钟分频控制寄存器sfrBUS_SPEED=0xA1;//总线速度控制寄存器sfrWKTCL=0xAA;//掉电唤醒专用定时器低字节sfrWKTCH=0xAB;//掉电唤醒专用定时器高字节/*-----------中断控制特殊功能寄存器--------------*/sfrIE=0xA8; //中断允许寄存器sbitEA=IE^7; //总中断允许位sbitELVD=IE^6; //低电压检测中断控制位sbitEADC=IE^5; //ADC中断允许控制位sbitES=IE^4; //串口1中断允许位sbitET1=IE^3; //定时器1溢出中断允许位sbitEX1=IE^2; //外部中断1允许位sbitET0=IE^1; //定时器0溢出中断允许位sbitEX0=IE^0; //外部中断0允许位sfrIE2=0xAF;//中断允许寄存器2sfrIP=0xB8; //中断优先级寄存器sbitPPCA=IP^7; //PCA中断优先级控制位sbitPLVD=IP^6;//低电压检测中断优先级控制位sbitPADC=IP^5;//ADC中断优先级控制位sbitPS=IP^4;//串口1中断优先级控制位sbitPT1=IP^3;//定时器1中断优先级控制位sbitPX1=IP^2;//外部中断1优先级控制位sbitPT0=IP^1;//定时器0中断优先级控制位sbitPX0=IP^0;//外部中断0优先级控制位sfrIP2=0xB5;//第二中断优先级寄存器低字节/*---------------I/O口特殊功能寄存器-------------------*/sfrP0=0x80; //P0口寄存器sfrP0M1=0x93;//P0口工作模式寄存器1sfrP0M0=0x94;//P0口工作模式寄存器0sfrP1=0x90;//P1口寄存器sfrP1M1=0x91;//P1口工作模式寄存器1sfrP1M0=0x92;//P1口工作模式寄存器0sfrP1ASF=0x9D;//P1口模拟量功能设置寄存器sfrP2=0xA0;//P2口寄存器sfrP2M1=0x95;//P2口工作模式寄存器1sfrP2M0=0x96;//P2口工作模式寄存器0sfrP3=0xB0; //P3口寄存器sbitT1=P3^5;//定时器1外部输入sbitT0=P3^4;//定时器0外部输入sbitINT1=P3^3;//外部中断1sbitINT0=P3^2;//外部中断0sbitTXD=P3^1; //串行输入通道sbitRXD=P3^0; //串行输出通道sfrP3M1=0xB1;//P3口工作模式寄存器1sfrP3M0=0xB2;//P3口工作模式寄存器0sfrP4=0xC0;//P4口寄存器sfrP4M1=0xB3;//P4口工作模式寄存器1sfrP4M0=0xB4;//P4口工作模式寄存器0sfrP5=0xC8;//P5口(只有P5.3P5.2P5.1P5.0)sfrP5M1=0xC9;//P5口工作模式寄存器1sfrP5M0=0xCA;//P5口工作模式寄存器0sfrP_SW2=0xBA; //外设功能切换控制寄存器/*-----------------定时器特殊功能寄存器-----------------*/sfrTCON=0x88; //定时/计数控制寄存器sbitTF1=TCON^7; //定时器1溢出中断标志sbitTR1=TCON^6; //定时器1运行控制位sbitTF0=TCON^5; //定时器0溢出中断标志sbitTR0=TCON^4; //定时器0运行控制位sbitIE1=TCON^3; //外部中断1请求标志sbitIT1=TCON^2;//选择外部中断请求1为边沿触发方式的控制位sbitIE0=TCON^1; //外部中断0请求标志sbitIT0=TCON^0;
//选择外部中断请求0为边沿触发方式的控制位sfrTMOD=0x89;//定时/计数模式控制寄存器sfrTL0=0x8A; //定时/计数器0低字节sfrTH0=0x8C; //定时/计数器0高字节sfrTL1=0x8B; //定时/计数器1低字节sfrTH1=0x8D; //定时/计数器1高字节sfrT2H=0xD6;//定时器2重新装载时间常数高字节sfrT2L=0xD7;//定时器2重新装载时间常数低字节/*--------------串行口特殊功能寄存器------------------*/sfrSCON=0x98; //串行口控制寄存器sbitSM0=SCON^7;
//串行口工作方式设定控制位0(与FE功能复用)sbitFE=SCON^7;sbitSM1=SCON^6; //串行口工作方式设定控制位1sbitSM2=SCON^5; //UART的SM2设定sbitREN=SCON^4; //接收允许位sbitTB8=SCON^3; //发送数据的第九位sbitRB8=SCON^2; //接收数据的第九位sbitTI=SCON^1; //发送中断标志sbitRI=SCON^0; //接收中断标志sfrSBUF=0x99; //串口数据缓冲器sfrSADEN=0xB9;//从机地址掩码寄存器sfrSADDR=0xA9;//从机地址寄存器sfrS2CON=0x9A;//串行口2控制寄存器sfrS2BUF=0x9B;//串行口2数据缓冲器/*----------------看门狗定时器寄存器------------------*/sfrWDT_CONTR=0xC1;//看门狗定时器控制寄存器/*----------------PCA寄存器-----------------*/sfrCCON=0xD8;//PCA控制寄存器sbitCF=CCON^7;
//PCA计数器溢出(CH,CL由FFFFH变为0000H)标志sbitCR=CCON^6;//PCA计数器计数允许控制位sbitCCF2=CCON^2;//PCA模块2中断标志sbitCCF1=CCON^1;//PCA模块1中断标志sbitCCF0=CCON^0;//PCA模块0中断标志sfrCMOD=0xD9;//PCA工作模式寄存器sfrCL=0xE9;//PCA计数器低8位sfrCH=0xF9;//PCA计数器高8位sfrCCAPM0=0xDA;//PAC模块0的工作模式寄存器sfrCCAPM1=0xDB;//PAC模块1的工作模式寄存器sfrCCAPM2=0xDC;//PAC模块2的工作模式寄存器sfrCCAP0L=0xEA;//PAC模块0捕捉/比较寄存器低8位sfrCCAP0H=0xFA;//PAC模块0捕捉/比较寄存器高8位sfrCCAP1L=0xEB;//PAC模块1捕捉/比较寄存器低8位sfrCCAP1H=0xFB;//PAC模块1捕捉/比较寄存器高8位sfrCCAP2L=0xEC;//PAC模块2捕捉/比较寄存器低8位sfrCCAP2H=0xFC;//PAC模块2捕捉/比较寄存器高8位sfrPCA_PWM0=0xF2;//PCA模块0PWM寄存器sfrPCA_PWM1=0xF3;//PCA模块1PWM寄存器sfrPCA_PWM2=0xF4;//PCA模块2PWM寄存器/*-----------------ADC寄存器-----------------*/sfrADC_CONTR=0xBC;//ADC控制寄存器,本寄存器不支持位操作sfrADC_RES=0xBD;//ADC转换结果高8位寄存器sfrADC_RESL=0xBE;//ADC转换结果低2位寄存器/*----------------SPI寄存器--------------------*/sfrSPSTAT=0xCD;
//SPI状态寄存器,本寄存器不支持位操作sfrSPCTL=0xCE;//SPI控制寄存器sfrSPDAT=0xCF;//SPI数据寄存器/*-----------------ISP_IAP_EEPROM寄存器------------------*/sfrIAP_DATA=0xC2;//ISP/IAPFlash数据寄存器sfrIAP_ADDRH=0xC3;//ISP/IAPFlash地址高字节sfrIAP_ADDRL=0xC4;//ISP/IAPFlash地址低字节sfrIAP_CMD=0xC5;//ISP/IAPFlash命令寄存器sfrIAP_TRIG=0xC6;//ISP/IAPFlash命令触发器sfrIAP_CONTR=0xC7;//ISP/IAP控制寄存器1、存储区域(MemoryAreas)(4)特殊功能寄存器STC15F2K60S2单片机的头文件stc15.h的内容,32/*---------8051内核特殊功能寄存器-------------*/sfr
ACC=0xE0;//累加器sfr
B=0xF0; //B寄存器sfr
PSW=0xD0;//程序状态字寄存器sbit
CY=PSW^7; //进位标志位sbit
AC=PSW^6;//辅助进位标志位sbit
F0=PSW^5; //用户标志位0sbit
RS1=PSW^4;//工作寄存器组选择控制位sbit
RS0=PSW^3;//工作寄存器组选择控制位sbit
OV=PSW^2;//溢出标志位sbitF1=PSW^1; //用户标志位1sbit
P=PSW^0; //奇偶标志位sfr
SP=0x81; //堆栈指针寄存器sfr
DPL=0x82; //数据指针0低字节sfr
DPH=0x83; //数据指针0高字节/*------------系统管理特殊功能寄存器-------------*/sfrPCON=0x87; //电源控制寄存器sfrAUXR=0x8E;//辅助寄存器sfrINT_CLKO=0x8F;//外部中断和时钟输出控制寄存器sfrAUXR1=0xA2;//辅助寄存器1sfrCLK_DIV=0x97;//时钟分频控制寄存器sfrBUS_SPEED=0xA1;//总线速度控制寄存器sfrWKTCL=0xAA;//掉电唤醒专用定时器低字节sfrWKTCH=0xAB;//掉电唤醒专用定时器高字节/*-----------中断控制特殊功能寄存器--------------*/sfrIE=0xA8; //中断允许寄存器sbitEA=IE^7; //总中断允许位sbitELVD=IE^6; //低电压检测中断控制位sbitEADC=IE^5; //ADC中断允许控制位sbitES=IE^4; //串口1中断允许位sbitET1=IE^3; //定时器1溢出中断允许位sbitEX1=IE^2; //外部中断1允许位sbitET0=IE^1; //定时器0溢出中断允许位sbitEX0=IE^0; //外部中断0允许位sfrIE2=0xAF;//中断允许寄存器2sfrIP=0xB8; //中断优先级寄存器sbitPPCA=IP^7; //PCA中断优先级控制位sbitPLVD=IP^6;//低电压检测中断优先级控制位sbitPADC=IP^5;//ADC中断优先级控制位sbitPS=IP^4;//串口1中断优先级控制位sbitPT1=IP^3;//定时器1中断优先级控制位sbitPX1=IP^2;//外部中断1优先级控制位sbitPT0=IP^1;//定时器0中断优先级控制位sbitPX0=IP^0;//外部中断0优先级控制位sfrIP2=0xB5;//第二中断优先级寄存器低字节/*---------------I/O口特殊功能寄存器-------------------*/sfrP0=0x80; //P0口寄存器sfrP0M1=0x93;//P0口工作模式寄存器1sfrP0M0=0x94;//P0口工作模式寄存器0sfrP1=0x90;//P1口寄存器sfrP1M1=0x91;//P1口工作模式寄存器1sfrP1M0=0x92;//P1口工作模式寄存器0sfrP1ASF=0x9D;//P1口模拟量功能设置寄存器sfrP2=0xA0;//P2口寄存器sfrP2M1=0x95;//P2口工作模式寄存器1sfrP2M0=0x96;//P2口工作模式寄存器0sfrP3=0xB0; //P3口寄存器sbitT1=P3^5;//定时器1外部输入sbitT0=P3^4;//定时器0外部输入sbitINT1=P3^3;//外部中断1sbitINT0=P3^2;//外部中断0sbitTXD=P3^1; //串行输入通道sbitRXD=P3^0; //串行输出通道sfrP3M1=0xB1;//P3口工作模式寄存器1sfrP3M0=0xB2;//P3口工作模式寄存器0sfrP4=0xC0;//P4口寄存器sfrP4M1=0xB3;//P4口工作模式寄存器1sfrP4M0=0xB4;//P4口工作模式寄存器0sfrP5=0xC8;//P5口(只有P5.3P5.2P5.1P5.0)sfrP5M1=0xC9;//P5口工作模式寄存器1sfrP5M0=0xCA;//P5口工作模式寄存器0sfrP_SW2=0xBA; //外设功能切换控制寄存器/*-----------------定时器特殊功能寄存器-----------------*/sfrTCON=0x88; //定时/计数控制寄存器sbitTF1=TCON^7; //定时器1溢出中断标志sbitTR1=TCON^6; //定时器1运行控制位sbitTF0=TCON^5; //定时器0溢出中断标志sbitTR0=TCON^4; //定时器0运行控制位sbitIE1=TCON^3; //外部中断1请求标志sbitIT1=TCON^2;//选择外部中断请求1为边沿触发方式的控制位sbitIE0=TCON^1; //外部中断0请求标志sbitIT0=TCON^0;
//选择外部中断请求0为边沿触发方式的控制位sfrTMOD=0x89;//定时/计数模式控制寄存器sfrTL0=0x8A; //定时/计数器0低字节sfrTH0=0x8C; //定时/计数器0高字节sfrTL1=0x8B; //定时/计数器1低字节sfrTH1=0x8D; //定时/计数器1高字节sfrT2H=0xD6;//定时器2重新装载时间常数高字节sfrT2L=0xD7;//定时器2重新装载时间常数低字节/*--------------串行口特殊功能寄存器------------------*/sfrSCON=0x98; //串行口控制寄存器sbitSM0=SCON^7;
//串行口工作方式设定控制位0(与FE功能复用)sbitFE=SCON^7;sbitSM1=SCON^6; //串行口工作方式设定控制位1sbitSM2=SCON^5; //UART的SM2设定sbitREN=SCON^4; //接收允许位sbitTB8=SCON^3; //发送数据的第九位sbitRB8=SCON^2; //接收数据的第九位sbitTI=SCON^1; //发送中断标志sbitRI=SCON^0; //接收中断标志sfrSBUF=0x99; //串口数据缓冲器sfrSADEN=0xB9;//从机地址掩码寄存器sfrSADDR=0xA9;//从机地址寄存器sfrS2CON=0x9A;//串行口2控制寄存器sfrS2BUF=0x9B;//串行口2数据缓冲器/*----------------看门狗定时器寄存器------------------*/sfrWDT_CONTR=0xC1;//看门狗定时器控制寄存器/*----------------PCA寄存器-----------------*/sfrCCON=0xD8;//PCA控制寄存器sbitCF=CCON^7;
//PCA计数器溢出(CH,CL由FFFFH变为0000H)标志sbitCR=CCON^6;//PCA计数器计数允许控制位sbitCCF2=CCON^2;//PCA模块2中断标志sbitCCF1=CCON^1;//PCA模块1中断标志sbitCCF0=CCON^0;//PCA模块0中断标志sfrCMOD=0xD9;//PCA工作模式寄存器sfrCL=0xE9;//PCA计数器低8位sfrCH=0xF9;//PCA计数器高8位sfrCCAPM0=0xDA;//PAC模块0的工作模式寄存器sfrCCAPM1=0xDB;//PAC模块1的工作模式寄存器sfrCCAPM2=0xDC;//PAC模块2的工作模式寄存器sfrCCAP0L=0xEA;//PAC模块0捕捉/比较寄存器低8位sfrCCAP0H=0xFA;//PAC模块0捕捉/比较寄存器高8位sfrCCAP1L=0xEB;//PAC模块1捕捉/比较寄存器低8位sfrCCAP1H=0xFB;//PAC模块1捕捉/比较寄存器高8位sfrCCAP2L=0xEC;//PAC模块2捕捉/比较寄存器低8位sfrCCAP2H=0xFC;//PAC模块2捕捉/比较寄存器高8位sfrPCA_PWM0=0xF2;//PCA模块0PWM寄存器sfrPCA_PWM1=0xF3;//PCA模块1PWM寄存器sfrPCA_PWM2=0xF4;//PCA模块2PWM寄存器/*-----------------ADC寄存器-----------------*/sfrADC_CONTR=0xBC;//ADC控制寄存器,本寄存器不支持位操作sfrADC_RES=0xBD;//ADC转换结果高8位寄存器sfrADC_RESL=0xBE;//ADC转换结果低2位寄存器/*----------------SPI寄存器--------------------*/sfrSPSTAT=0xCD;
//SPI状态寄存器,本寄存器不支持位操作sfrSPCTL=0xCE;//SPI控制寄存器sfrSPDAT=0xCF;//SPI数据寄存器/*-----------------ISP_IAP_EEPROM寄存器------------------*/sfrIAP_DATA=0xC2;//ISP/IAPFlash数据寄存器sfrIAP_ADDRH=0xC3;//ISP/IAPFlash地址高字节sfrIAP_ADDRL=0xC4;//ISP/IAPFlash地址低字节sfrIAP_CMD=0xC5;//ISP/IAPFlash命令寄存器sfrIAP_TRIG=0xC6;//ISP/IAPFlash命令触发器sfrIAP_CONTR=0xC7;//ISP/IAP控制寄存器2、_at_关键字若要实现变量的绝对定位(称为绝对变量),可以直接在数据定义后加上“_at_常数地址”即可。注意:(1)绝对变量不能被初始化(不能赋初值);(2)bit型函数及变量不能用_at_指定。33例如:unsignedcharidataADCdata_at_0x40;//指定ADCdata变量在40H处unsignedcharxdatabuffer[20]_at_0x0010;//指定buffer数组从XRAM的0010H单元开始3、存储模式存储模式决定了没有明确指定存储类型的变量时、函数参数等的缺省存储区域,有Small、Compact和Large三种模式。34指定存储模式图5-1指定存储模式
3、存储模式(1)Small模式在该模式中所有变量都默认位于单片机内部数据存储器(00~7FH),这和使用data指定存储器类型的方式一样。此模式访问变量的效率很高,但所有的数据对象和堆栈必须适合内部RAM堆栈的大小。如果将变量都能配置在内部数据存储器内,Small模式是最佳选择。该模式的优点是访问速度快,缺点是空间有限,只适用于小程序。35(2)Compact模式所有缺省变量均位于外部RAM区的一页内(256字节),这和使用pdata指定存储器类型一样。该模式通过寄存器R0和R1(@R0,@R1)间接寻址。R0和R1只提供地址低字节,如果COMPACT模式使用多于256字节的外部存储区,高字节地址或页由8051的P2(口地址0A0H)提供;初始化PORT2及指定PDATA起始地址的工作可在起始代码中STARTUP.A51文件中说明。该模式空间比Small宽裕,速度比Small慢,比Large快,是一种中间状态。363、存储模式(3)Large模式所有缺省变量可放在多达64KB的外部RAM区,这和使用xdata指定存储器类型一样,使用数据指针DPTR进行寻址。通过数据指针访问外部数据存储器的效率较低,特别是当变量为2个字节或更多字节(用一般指针)时。Large模式的数据访问比Small和Compact产生更多的代码。优点是空间大,可存变量多,缺点是速度较慢。374、变量或数据类型表5-1C51数据类型数据类型含义位数(bit)字节数(byte)取值范围bit*位型11/80或1signedchar带符号字符型81-128~+127unsignedchar无符号字符型810~255enum8/161or2-128~+127or-32768~+32767signedshort带符号短型162-32768~+32767unsignedshort无符号短型1620~65535signedint带符号整型162-32768~+32767unsignedint无符号整型1620~65535signedlong带符号长整型324-2147483648~+2147483647unsignedlong无符号长整型3240~4294967295float浮点型324+1.175494E38~+3.402823E+38sbit*11/80-1sfr*810x80-0xffsfr16*1620x0000~0xffff38C51特有特殊功能寄存器类型4、变量或数据类型C51提供以下几种扩展数据类型:
bit:位变量值为0或1。格式:bit位名[=value];
例:staticbit
done_flag=0;/*bitvariable*/
sbit:从可位寻址的字节中定义的位变量(0或1)。
sfr:sfr字节地址(0x80~0xff)。
sfr16:sfr字地址(0x80~0xff,其实占用两个连续地址)。
例:sfr16DPTR=0x82h;其余数据类型如:char、enum、short、int、long、float等与ANSIC相同。下面着重介绍位变量及其声明。390或1*图3-10内部RAM中的位地址20H~2FH之间单元既可按字节存取,也可按位存取,共128位,位地址范围:00H~7FH。位寻址区404、变量或数据类型
(1)bit型变量(1)bit型变量bit型变量可用于变量类型声明、函数参数列表和函数返回值等,存储于内部RAM的20H~2FH单元中。
例:bitflag1注意:
1)使用禁止中断
(#pragmadisable)或用一个明确的寄存器组声明
(usingn)的函数不能返回位值,否则,编译器会识别出来并产生一个错误信息。
2)位不能声明为一个指针。如bit*bit_poiter;是错误的。
3)不能有bit数组如:bitarr[5];是错误的。4)bit型函数及变量不能用'_at_'定位到一个绝对地址。41(#pragma的作用是设定编译器的状态或者指示编译器完成一些特定的动作)此指令是给位变量Fg3赋值1(0x20非0是真,值=1)(2)可位寻址区的说明使用sbit声明可独立访问可位寻址对象的位。sbit声明要求基址对象的存贮器类型为“bdata”(特殊功能寄存器除外),否则只有绝对的位声明方法是合法的。例:sbitFg1=0x20;//错误使用sbit,位地址须在80H~FFH之间sbitEA=0xAF;//位地址可大于80HsbitFg2=0x20^2;//错误使用sbit,
bitFg3=0x20;//既不能用bit定义Fg3的位地址是0x20,//也不能用sbit定义,除非用bdata声明:intbdata
bitram
_at_0x20;//用“bdata”声明后可用sbitsbitFg4=bitram^2;//相当于定义了Fg4=0x20^2bitFg4=bitram^2;//bit不能这样使用,虽然sbit可以.4、变量或数据类型(2)可位寻址区的说明42sbit可绝对定位位变量,但bit不可总结(^1)4、变量或数据类型(2)可位寻址区的说明(2)可位寻址区的说明使用sbit声明可独立访问可位寻址对象的位。sbit声明要求基址对象的存贮器类型为“bdata”(特殊功能寄存器除外):int
bdata
bitram
_at_0x20;
//用“bdata”声明后可用sbit位寻址sbitFg15=bitram^15;//相当于定义了Fg15=0x20^15位的位置(
‘^’操作符号后的数字)的最大值依赖于指定的基址变量类型:对于char/uchar而言是0~7,对于int/uint/short/ushort而言是0~15,对于long/ulong而言是0~31。434、变量或数据类型下面举例说明位寻址的声明方法。例,intbdata
bittest_at_
0x20;//也可省略“_at_0x20”
sbitbit0=bittest^0;//0x20单元的第0位(bittest的第8位)sbit
bit15=bittest^15;//0x21单元的第7位(bittest的第7位)参见“Cx51CompilerUser‘sGuide”--“Bit-AddressableObjects”
最后一段“Physicalbitposition0referstobitposition0ofthefirstbyte.Physicalbitposition8referstobitposition0ofthesecondbyte.Becauseintvariablesarestoredhigh-bytefirst,bit0oftheintegerislocatedinbitposition0ofthesecondbyte.Thisisphysicalbitposition8whenaccessedusingansbitdatatype.”注意:可位寻址对象的位的声明只能放到main函数的外部,
作为全局变量使用,否则,编译会出错。bit无限制。44先存高字节,再存低字节0x20单元的0~7位是bittest的第8~15位0x21单元的0~7位是bittest的第0~7位实际位的位置与位号bit0~7不相符定义为char就不存在此不对应问题5.2.2扩展I/O口的使用STC15F2K60S2单片机除了芯片上的I/O口外,还可在片外扩展I/O端口。由于使用C语言访问外部I/O时用到指针的功能,因此,首先介绍K
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024至2030年中国胶片观察灯行业投资前景及策略咨询研究报告
- 2024年小儿肺热咳喘冲剂项目可行性研究报告
- 小学生运动安全班会课
- 2024至2030年中国微波炉发热片行业投资前景及策略咨询研究报告
- 2024至2030年中国幕墙材行业投资前景及策略咨询研究报告
- 2024年中国驴鞭市场调查研究报告
- 2024年汽车空调用风机项目可行性研究报告
- 青海大学《中国房地产博观》2023-2024学年第一学期期末试卷
- 青岛远洋船员职业学院《蔬菜作物究法》2023-2024学年第一学期期末试卷
- 青岛幼儿师范高等专科学校《环境科学进展》2023-2024学年第一学期期末试卷
- 布加综合征护理
- 燃气高空作业专项施工方案
- 第六单元多边形的面积 (单元测试)-2024-2025学年五年级上册数学人教版
- 青岛市卫生健康委员会直属事业单位招聘人员笔试真题2023
- 2022年内蒙古自治区高等职业院校对口招收中等职业学校毕业生单独考试英语试卷
- 公路养护培训知识
- 国家安全教育高教-第六章坚持以经济安全为基础
- 2024版BIM模型可视化与仿真技术培训
- 锂电储能产品设计及案例详解-笔记
- 2025届云南省昭通市物理高二第一学期期末教学质量检测试题含解析
- 《浙江省历史文化名城名镇名村街区保护规划编制导则》(试行)
评论
0/150
提交评论