单片机C语言头文件
51单片机的串口通信程序(C语言)

51单片机的串口通信程序(C语言) 51单片机的串口通信程序(C语言)在嵌入式系统中,串口通信是一种常见的数据传输方式,也是单片机与外部设备进行通信的重要手段之一。
本文将介绍使用C语言编写51单片机的串口通信程序。
1. 硬件准备在开始编写串口通信程序之前,需要准备好相应的硬件设备。
首先,我们需要一块51单片机开发板,内置了串口通信功能。
另外,我们还需要连接一个与单片机通信的外部设备,例如计算机或其他单片机。
2. 引入头文件在C语言中,我们需要引入相应的头文件来使用串口通信相关的函数。
在51单片机中,我们需要引入reg51.h头文件,以便使用单片机的寄存器操作相关函数。
同时,我们还需要引入头文件来定义串口通信的相关寄存器。
3. 配置串口参数在使用串口通信之前,我们需要配置串口的参数,例如波特率、数据位、停止位等。
这些参数的配置需要根据实际需要进行调整。
在51单片机中,我们可以通过写入相应的寄存器来配置串口参数。
4. 初始化串口在配置完串口参数之后,我们需要初始化串口,以便开始进行数据的发送和接收。
初始化串口的过程包括打开串口、设置中断等。
5. 数据发送在串口通信中,数据的发送通常分为两种方式:阻塞发送和非阻塞发送。
阻塞发送是指程序在发送完数据之后才会继续执行下面的代码,而非阻塞发送是指程序在发送数据的同时可以继续执行其他代码。
6. 数据接收数据的接收与数据的发送类似,同样有阻塞接收和非阻塞接收两种方式。
在接收数据时,需要不断地检测是否有数据到达,并及时进行处理。
7. 中断处理在串口通信中,中断是一种常见的处理方式。
通过使用中断,可以及时地响应串口数据的到达或者发送完成等事件,提高程序的处理效率。
8. 串口通信实例下面是一个简单的串口通信实例,用于在51单片机与计算机之间进行数据的传输。
```c#include <reg51.h>#include <stdio.h>#define BAUDRATE 9600#define FOSC 11059200void UART_init(){TMOD = 0x20; // 设置定时器1为模式2SCON = 0x50; // 设置串口为模式1,允许接收TH1 = 256 - FOSC / 12 / 32 / BAUDRATE; // 计算波特率定时器重载值TR1 = 1; // 启动定时器1EA = 1; // 允许中断ES = 1; // 允许串口中断}void UART_send_byte(unsigned char byte){SBUF = byte;while (!TI); // 等待发送完成TI = 0; // 清除发送完成标志位}unsigned char UART_receive_byte(){while (!RI); // 等待接收完成RI = 0; // 清除接收完成标志位return SBUF;}void UART_send_string(char *s){while (*s){UART_send_byte(*s);s++;}}void main(){UART_init();UART_send_string("Hello, World!"); while (1){unsigned char data = UART_receive_byte();// 对接收到的数据进行处理}}```总结:通过以上步骤,我们可以编写出简单的51单片机串口通信程序。
手把手教你学单片机的C语言程序设计

手把手教你学单片机的C语言程序设计在当今科技飞速发展的时代,单片机已经成为了众多电子设备的核心控制组件。
而要让单片机按照我们的意愿工作,就离不开 C 语言程序设计。
无论你是电子爱好者,还是立志于从事相关专业的学生,掌握单片机的 C 语言编程都是一项非常实用的技能。
接下来,就让我一步步地教你如何学习单片机的 C 语言程序设计。
一、准备工作在开始学习之前,我们需要先做好一些准备工作。
首先,你需要一台电脑,安装好相应的开发软件。
常见的单片机开发软件有 Keil、IAR 等。
这些软件可以帮助我们编写、编译和调试程序。
其次,准备一块单片机开发板。
开发板的种类繁多,你可以根据自己的需求和预算进行选择。
一般来说,初学者可以选择一些简单易用、资料丰富的开发板,比如 STM32 系列、Arduino 等。
另外,还需要一本好的教材或者在线教程。
推荐《单片机 C 语言程序设计实例教程》、《手把手教你学 51 单片机 C 语言版》等书籍,网上也有很多免费的优质教程,比如哔哩哔哩上的相关教学视频。
二、C 语言基础知识学习单片机的 C 语言程序设计,需要先掌握 C 语言的基础知识。
1、数据类型C 语言中有多种数据类型,如整型(int)、浮点型(float)、字符型(char)等。
了解不同数据类型的取值范围和用途,是编写正确程序的基础。
2、变量和常量变量用于存储程序运行过程中的数据,常量则是固定不变的值。
学会正确地定义和使用变量和常量,可以让程序更加灵活和高效。
3、运算符和表达式掌握各种运算符,如算术运算符(+、、、/)、关系运算符(>、<、==)、逻辑运算符(&&、||、!)等,能够编写复杂的表达式来实现各种计算和逻辑判断。
4、控制结构C 语言中的控制结构包括顺序结构、选择结构(ifelse、switchcase)和循环结构(for、while、dowhile)。
通过合理使用这些控制结构,可以控制程序的执行流程,实现不同的功能。
单片机C语言C51的常用库函数

C51的常用库函数详解C51语言的编译器中包含有丰富的库函数,使用库函数可以大大简化用户程序设计的工作量,提高编程效率。
每个库函数都在相应的头文件中给出了函数原型声明,在使用时,必须在源程序的开场处使用预处理命令#include将有关的头文件包含进来。
C51库函数中类型的选择考虑到了8051单片机的构造特性,用户在自己的应用程序中应尽可能地使用最小的数据类型,以最大限度地发挥8051单片机的性能,同时可减少应用程序的代码长度。
下面将C51的库函数分类列出并详细介绍其用法。
1 字符函数字符函数的原型声明包含在头文件CTYPE.H中。
常用的一些字符函数介绍如下。
1.1 检查英文字母函数检查英文字母函数用于检查形参字符是否为英文字母,其函数原型如下:bit isalpha(char c);其中,c为待判断的字符,如果是英文字母则返回1,否则返回0。
程序例如如下:1.2 检查字母数字函数检查字母数字函数用于检查形参字符是否为英文字母或数字字符,其函数原型如下:bit isalnum(char c);1.3 检查控制字符函数检查控制字符函数用于检查形参字符是否为控制字符,其函数原型:bit istrl (char c);其中,c为待判断的字符。
控制字符其取值围为0*00~0*lF之间或等于0*7F,如果是,则返回1,否则返回0。
1.4 十进制数字检查函数十进制数字检查函数用于检查形参字符是否为十进制数字,其函数原型如下:bit isdigit (char c);其中,c为待判断的字符,如果是十进制数字则返回1,否则返回0。
1.5 可打印字符检查函数可打印字符检查函数用于检查形参字符是否为可打印字符,其函数原型如下:bit isgraph (char c);其中,c为待判断的字符。
可打印字符的取值围为0*21~0*7C,不包含空格,如果是可打印字符则返回1,否则返回0。
1.6 包含空格的可打印字符检查函数包含空格的可打印字符检查函数用于检查形参字符是否为可打印字符以及空格,其函数原型如下:bit isprint (char c);其中,c为待判断字符。
(1小时学会C语言51单片机)C语言入门教程1

我们在单片机最小系统上接个LED,看我们能否点亮它!对了,上面也有好几次提到过单片机最小系统了,所谓单片机最小系统就是在单片机上接上最少的外围电路元件让单片机工作。
一般只须连接晶体、VCC、GND、RST即可,一般情况下,A T89C51的31脚须接高电平。
#include<reg51.h> //头文件定义。
或用#include<at89x51.h>其具体的区别在于:后者定义了更多的地址空间。
//在Keil安装文件夹中,找到相应的文件,比较一下便知!sbit P1_0 = P1 ^ 0; //定义管脚void main (void){while(1){P1_0 = 0;//低电平有效,如果把LED反过来接那么就是高电平有效}}就那么简单,我们就把接在单片机P1_0上的LED点亮了,当然LED是低电平,才能点亮。
因为我们把LED的正通过电阻接至VCC。
P1_0 = 0; 类似与C语言中的赋值语句,即把0 赋给单片机的P1_0引脚,让它输出相应的电平。
那么这样就能达到了我们预先的要求了。
while(1)语句只是让单片机工作在死循环状态,即一直输出低电平。
如果我们要试着点亮其他的LED,也类似上述语句。
这里就不再讲了。
点亮了几个LED后,是不是让我们联想到了繁华的街区上流动的彩灯。
我们是不是也可以让几个LED依次按顺序亮呢?答案是肯定的!其实显示的原理很简单,就是让一个LED灭后,另一个立即亮,依次轮流下去。
假设我们有8个LED分别接在P1口的8个引脚上。
硬件连接,在P1_1--P1_7上再接7个LED即可。
例程如下:#include<reg51.h>sbit P1_0 = P1 ^ 0;sbit P1_1 = P1 ^ 1;sbit P1_2 = P1 ^ 2;sbit P1_3 = P1 ^ 3;sbit P1_4 = P1 ^ 4;sbit P1_5 = P1 ^ 5;sbit P1_6 = P1 ^ 6;sbit P1_7 = P1 ^ 7;void Delay(unsigned char a){unsigned char i;while( --a != 0){for(i = 0; i < 125; i++); //一个; 表示空语句,CPU空转。
单片机C语言_电子时钟程序

#include<AT89X52.H>#define uint unsigned int#define uchar unsigned charunsigned char key2;bit ding=1;unsigned char Getkey(void);uchar a,n=0,shi,fen,miao;void delay01s(void);uchar LED[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};uchar LED1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//有小数点的void init(); //函数声明void Delay(unsigned char z);//函数声明void display(); //函数声明//函数声明void main() //函数声明{P1=0xfe;//对P1口赋初值init(); //函数调用while(1){//函数调用key2=Getkey();switch(key2){case 1:shi++;if(shi==24){shi=0;}break;case 2:fen++;if(fen==60){fen=0;}break;case 3:if(fen!=0)fen--;if(fen==24){fen=0;}break;case 4:ding=~ding;default:break;}display(); //函数调用}}void init(){TMOD=0x01; //定时器工作方式选择和赋初值TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1; //开总中断ET0=1; //开定时器中断TR0=1; //启动定时器}void timer0() interrupt 1 //中断服务程序{if(ding==1){TH0=(65536-50000)/256;//中断时间50msTL0=(65536-50000)%256; //定时器重新赋初值a++;if(a==10){n=~n;}if(a==20){n=~n;a=0;P1=P1<<1|P1>>7;miao++;if(miao==60){miao=0;fen++;if(fen==60){fen=0;shi++;if(shi==24){shi=0;}}}}}}void display()//显示程序{P0=LED[shi/10];P2=((P2&0x0f)|0x70); Delay(4);if(n==0){P0=LED[shi%10];}else{P0=LED1[shi%10];}P2=((P2&0x0f)|0xb0);Delay(4);P0=LED[fen/10];P2=((P2&0x0f)|0xd0);Delay(4);P0=LED[fen%10];P2=((P2&0x0f)|0xe0);Delay(4);}/**********获得键值子程序**********************/ unsigned char bool;//bool 是否松键的标志unsigned char Getkey(void){unsigned char temp,key=0;P2=(P2&0xff)|0x0f;if((P2&0xff)!=((P2&0xff)|0x0f)) // 有键按下{//delay01s();if(((P2&0xff)!=((P2&0xff)|0x0f)) &&(bool==0)) // 有键按下{temp=~(P2|0xf0);if(temp==1) key=1;else if(temp==2) key=2;else if(temp==4) key=3;else if(temp==8) key=4;bool=1;}}if(((P2&0xff)==((P2&0xff)|0x0f)) &&(bool==1)){bool=0;}return key; //返回1~16键值}/********延时程序******/void delay01s(void){unsigned char j,k;for(j=5;j>0;j--) //198{for(k=15;k>0;k--)//248{;}}}void Delay(unsigned char z){unsigned char i,j,k; //定义变量for(i=z;i>0;i--)for(j=25;j>0;j--)for(k=20;k>0;k--);}#include<reg52.h>//头文件#define uchar unsigned char//宏定义#define uint unsigned intsbit P31=P3^1;//位声明sbit P32=P3^2;sbit P33=P3^3;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴段码表uint hou1,hou2,min1,min2,sec1,sec2,numhou,nummin,numsec,yue1,yue2,ri1,ri2,numyue,numri; uint num,m,n;void delayms(uint xms)//延时函数{uint i,j;for(i=xms;i>0;i--)for(j=110;j>0;j--);}void p31xd()//按键P31消抖{ delayms(2);while(P31!=1);delayms(2);}void p32xd()//按键P32消抖{ delayms(1);while(P32!=1);delayms(1);}void p33xd()//按键P33消抖{ delayms(1);while(P33!=1);delayms(1);}void displaysj()//显示时间{P2=0x00;P0=table[hou1];//显示时的第一位P2=0X20;delayms(1);P2=0xff;P0=table[hou2]&0x7f;//显示时的第二位与小数点P2=0X10;delayms(1);P2=0xff;P0=table[min1];//显示分的第一位P2=0X08;delayms(1);P2=0xff;P0=table[min2]&0x7f;//显示时的第二位与小数点P2=0X04;delayms(1);P2=0xff;P0=table[sec1];//显示秒的第一位P2=0X02;delayms(1);P2=0xff;P0=table[sec2];//显示秒的第二位P2=0X01;delayms(1);}void displayrq()//显示日期{ P2=0x00;P0=table[yue1];//显示月的第一位P2=0X20;delayms(1);P2=0x00;P0=table[yue2]&0x7f;//显示月的第二位P2=0X10;delayms(1);P2=0x00;P0=table[ri1];//显示日的第一位P2=0X08;delayms(1);P2=0x00;P0=table[ri2];//显示日的第二位P2=0X04;delayms(1);}void houqh()//时针切换函数{hou1=numhou/10;hou2=numhou%10;}void minqh()//分针切换函数{min1=nummin/10;min2=nummin%10;}void secqh()//秒针切换函数{sec1=numsec/10;sec2=numsec%10;}void yueqh()//月切换函数{yue1=numyue/10;yue2=numyue%10;}void riqh()//日切换函数{ri1=numri/10;ri2=numri%10;}void start()//初始化函数{num=0;TMOD=0x01;TH0=(65532-45872)/256;TL0=(65532-45872)%256;EA=1;IT0=0;//电平触发(低电平有效)EX0=1;ET0=1;TR0=1;yueqh(),riqh();//初始化日月切换}void ritiao()//日期的调节函数{ if(P32==0)//日期加一调节键{p32xd();if((numyue==1)||(numyue==3)||(numyue==5)||(numyue==7)||(numyue==8)||(numyue==10)||( numyue==12)){numri+=1;if(numri>=31)//如果是大月,日期有31号,等于符号是防止日期大于31号而乱码{numri=1;}}if((numyue==4)||(numyue==6)||(numyue==9)||(numyue==11)){numri+=1;if(numri>=30)//如果是小月,日期有30号{numri=1;}}if(numyue==2){numri+=1;if(numri>=28)//如果是小月,日期有28号{numri=1;}}riqh();//日期调节后切换一下}if(P33==0)//日期减一调节键{p33xd();if((numyue==1)||(numyue==3)||(numyue==5)||(numyue==7)||(numyue==8)||(numyue==10)||( numyue==12)){numri-=1;if(numri==0){numri=31;}}if((numyue==4)||(numyue==6)||(numyue==9)||(numyue==11)){numri-=1;if(numri==0){numri=30;}}if(numyue==2){numri-=1;if(numri==0){numri=28;}}riqh();}}void yuetiao()//月份的调节函数{if(P32==0){p32xd();numyue+=1;if(numyue==13)//月份为12时再加一马上为一月{numyue=1;}yueqh();}if(P33==0){p33xd();numyue-=1;if(numyue==0){numyue=12;}yueqh();}}void int0() interrupt 0{p31xd();while(P31!=0)//第一次按下p31时,进行秒调时{for(m=0;m<40;m++)//此for循环不显示秒,为的是使秒闪烁{P2=0x00;P0=table[hou1];P2=0X20;delayms(1);P2=0x00;P0=table[hou2]&0x7f;P2=0X10;delayms(1);P2=0x00;P0=table[min1];P2=0X08;delayms(1);P2=0x00;P0=table[min2]&0x7f;P2=0X04;delayms(1);if(P32==0)//如果按一下P32,则秒加一{p32xd();numsec+=1;if(numsec==60){numsec=0;}secqh();}if(P33==0)//如果按一下P33,则秒减一{p33xd();numsec-=1;if(numsec==-1){numsec=59;}secqh();}};for(n=0;n<40;n++)//此循环时分秒全显示,也为的是使秒闪烁{ displaysj();if(P32==0){p32xd();numsec+=1;if(numsec==60){numsec=0;}secqh();}if(P33==0){p33xd();numsec-=1;if(numsec==-1){numsec=59;}secqh();}}};p31xd();while(P31!=0)//第二次按下p31时,进行分调时{for(m=0;m<40;m++){P2=0x00;P0=table[hou1];P2=0X20;delayms(1);P2=0x00;P0=table[hou2]&0x7f;P2=0X10;delayms(1);P2=0x00;P0=table[sec1];P2=0X02;delayms(1);P2=0x00;P0=table[sec2];P2=0X01;delayms(1);if(P32==0){p32xd();nummin+=1;if(nummin==60){nummin=0;}minqh();}if(P33==0){p33xd();nummin-=1;if(nummin==-1){nummin=59;}minqh();}}for(n=0;n<40;n++){ displaysj();if(P32==0){p32xd();nummin+=1;if(nummin==60){nummin=0;}minqh();}if(P33==0){nummin-=1;if(nummin==-1){nummin=59;}minqh();}}};p31xd();while(P31!=0)//第三次按下p31时,进行时调时{for(m=0;m<40;m++){P2=0x00;P0=table[min1];P2=0X08;delayms(1);P2=0x00;P0=table[min2]&0x7f;P2=0X04;delayms(1);P2=0x00;P0=table[sec1];P2=0X02;delayms(1);P2=0x00;P0=table[sec2];P2=0X01;delayms(1);if(P32==0){p32xd();numhou+=1;if(numhou==24){numhou=0;}}if(P33==0){p33xd();numhou-=1;if(numhou==-1){numhou=23;}houqh();}}for(n=0;n<40;n++){ displaysj();if(P32==0){p32xd();numhou+=1;if(numhou==24){numhou=0;}houqh();}if(P33==0){p33xd();numhou-=1;if(numhou==-1){numhou=23;}houqh();}}}p31xd();while(P31!=0)//第四次按下p31时,进行日期调节{for(m=0;m<50;m++){ P2=0x00;P0=table[yue1];P2=0x20;delayms(1);P2=0x00;P0=table[yue2]&0x7f;P2=0x10;delayms(1);ritiao();}for(n=0;n<50;n++){ displayrq();ritiao();}}p31xd();while(P31!=0)//第五次按下p31时,进行月调节{for(m=0;m<50;m++){P2=0xff;P0=table[ri1];P2=0xf7;delayms(1);P2=0xff;P0=table[ri2];P2=0xfb;delayms(1);yuetiao();}for(n=0;n<50;n++){ displayrq();yuetiao();}}p31xd();}void yuejia(){ numri=1;numyue+=1;if(numyue==13){numyue=1;}}void timer0() interrupt 1{TH0=(65532-46100)/256;TL0=(65532-46100)%256;num++;if(num==20){num=0;TH0=(65532-46100)/256;TL0=(65532-46100)%256;numsec=numsec+1;if(numsec==60){numsec=0;nummin=nummin+1;if(nummin==60){nummin=0;numhou=numhou+1;if(numhou==24){numhou=0;numri+=1;if((numyue==1)||(numyue==3)||(numyue==5)||(numyue==7)||(numyue==8)||(numyue==10)||( numyue==12)){numri+=1;if(numri>=31){numri=1;numyue+=1;if(numyue==13){numyue=1;}}}if((numyue==4)||(numyue==6)||(numyue==9)||(numyue==11)){numri+=1;if(numri>=31){numri=1;numyue+=1;if(numyue==13){numyue=1;}}}if(numyue==2){numri+=1;if(numri>=29){numri=1;numyue+=1;if(numyue==13){numyue=1;}}}}}}}}void main(){numhou=12;//初始化时间设为12点,日期设为1月1日nummin=0;numsec=0;numyue=1;numri=1;start();while(1){if(P32==1)//默认(没有按下p32时)显示时间{houqh(),minqh(),secqh();displaysj();}if(P32==0)//当按下p32键时显示日期{yueqh(),riqh();displayrq();}}}。
关于51单片机启动程序和头文件的深入学习

总的作用:STARTUP.A51//启动文件. 清理RAM.设置堆栈等.即执行完start.a51后跳转到.c文件的main 函数<reg51.h> //特殊寄存器的字节地址和位地址,sfr定义字节变量、sbit定义位变量,用通俗名作为变量名,并赋地址值,从而用名称来使用这些特殊寄存器。
<intrins.h> //定义了一些外部函数,在C51单片机编程中,头文件INTRINS.H的函数使用起来,就会让你像在用汇编时一样简便.特别需要注意的概念:地址与地址值:“地址是存放值的内存空间对应的门牌号码。
地址值是门牌号对应内存空间里存放内容。
通俗讲,一栋楼房, 101号房间什么都没只有1个人。
这个人是值。
101是地址。
房间是内存空间。
”启动程序详细解释;STARTUP.A51:用户上电初始化程序;------------------------------------------------------------------------------;; 用户定义需上电初始化的内存空间;; 使用以下EQU命令可定义在CPU复位时需用0进行初始化的内存空间;; ;IDATA 存储器的空间的绝对起始地址总是0.IDATALENEQU 80H ; 需用0进行初始化的IDATA存储器空间的字节数;XDATASTARTEQU 0H ; XDATA存储器空间的绝对起始地址XDATALENEQU 0H ; 需用0进行初始化的XDATA存储器的空间字节数.;PDATASTARTEQU 0H ; PDATA存储器的空间的绝对起始地址PDATALENEQU 0H ; 需用0进行初始化的PDATA存储器的空间字节数.;; 注意: IDATA 存储器的空间在物理上包括了8051单片机的DATA和BIT存储器空间.; 听说至少要保证与C51编译器运行库有关的存储器的空间进行0初始化不知是否;------------------------------------------------------------------------------;; 再入函数模拟初始化;; 以下用EQU指令定义了再入函数模拟堆栈指针的初始化;; 使用SMALL存储器模式时再入函数的堆栈空间.IBPSTACKEQU 0 ; 使用SMALL存储器模式再入函数时将其设置成1. IBPSTACKTOPEQU 0FFH+1 ; 将堆栈顶设置为最高地址+1.;; 使用LARGE存储器模式时再入函数的堆栈空间.XBPSTACKEQU 0 ; 使用LARGE存储器模式再入函数时将其设置成1. XBPSTACKTOPEQU 0FFFFH+1; 将堆栈顶设置为最高地址+1.;; 使用COMPACT存储器模式时再入函数的堆栈空间.PBPSTACKEQU 0 ; 使用COMPACT存储器模式再入函数时将其设置成1. PBPSTACKTOPEQU 0FFFFH+1; 将堆栈顶设置为最高地址+1.;;------------------------------------------------------------------------------;; 使用COMPACT存储器模式时64K字节XDATA存储器空间的分页定义;; 以下用EQU指令定义PDATA类型变量在XDATA存储器空间的页地址; 使用EQU指令定义PFAGE时必须与L51连接定位器PDATA指令的控制参数一致;PPAGEENABLEEQU 0 ; 使用PDATA类型变量时将其设置成1.PPAGEEQU 0 ; 定义页号.;;------------------------------------------------------------------------------NAME?C_STARTUP ; 模块名为?C_STAUTUP?C_C51STARTUPSEGMENT CODE ; 代码?STACKSEGMENT IDATA ; 堆栈RSEG?STACK ; 堆栈DS 1EXTRNCODE (?C_START) ; 程序开始地址PUBLIC?C_STARTUPCSEGAT 0x8000 ; 定义用户程序的起始地址,用MON51仿真器时可能有用?C_STARTUP:LJMP STARTUP1RSEG?C_C51STARTUPSTARTUP1:;; 初始化串口MOVSCON,#40HMOVTMOD,#20HMOVTH1,#0fdHSETBTR1CLRTI; 单片机上电IDATA内存清零如果不需要上电清零IDATA可以注销IF到IFEDN之间的话句; 或者修改IDTALEN的长度为了具有掉电保护功能不知IDTALEN多长为好IFIDATALEN <> 0MOVR0,#IDATALEN - 1CLR AIDATALOOP:MOV @R0,ADJNZR0,IDATALOOPENDIF;; 单片机上电XDATA内存清零如果不需要上电清零XDATA可以注销IF到IFEDN之间的话句; 或者修改XDATALEN的长度IFXDATALEN <> 0MOVDPTR,#XDATASTARTMOVR7,#LOW (XDATALEN)IF(LOW (XDATALEN)) <> 0MOVR6,#(HIGH (XDATALEN)) +1ELSEMOVR6,#HIGH (XDATALEN)ENDIFCLR AXDATALOOP:MOVX @DPTR,AINCDPTRDJNZR7,XDATALOOPDJNZR6,XDATALOOPENDIF;; 送PDATA存储器页面高位地址IFPPAGEENABLE <> 0MOVP2,#PPAGEENDIF;; 单片机上电PDATA内存清零如果不需要上电清零XDATA可以注销IF到IFEDN之间的话句; 或者修改PDATALEN的长度IFPDATALEN <> 0MOVR0,#PDATASTARTMOVR7,#LOW (PDATALEN)CLR APDATALOOP:MOVX @R0,AINCR0DJNZR7,PDATALOOPENDIF;; 设置使用SMALL存储器模式时再入函数的堆栈空间.IFIBPSTACK <> 0EXTRNDATA (?C_IBP)MOV?C_IBP,#LOW IBPSTACKTOPENDIF;; 设置使用LARGE存储器模式时再入函数的堆栈空间.IFXBPSTACK <> 0EXTRNDATA (?C_XBP)MOV?C_XBP,#HIGH XBPSTACKTOPMOV?C_XBP+1,#LOW XBPSTACKTOPENDIF;; 设置使用COMPACT存储器模式时再入函数的堆栈空间.IFPBPSTACK <> 0EXTRNDATA (?C_PBP)MOV?C_PBP,#LOW PBPSTACKTOPENDIF;; 设置堆栈的起始地址MOVSP,#?STACK-1 ; 例如MOV SP,#4FH;;This code is required if you use L51_BANK.A51 with Banking Mode 4; 如果你的程序使用了Mode 4 程序分组技术请启动下面的程序,不会吧你的程序超过64K 利害;EXTRN CODE (?B_SWITCH0);CALL ?B_SWITCH0 ; init bank mechanism to code bank 0; 程序从第一组bank 0 块开始执行; 跳转到用户程序MAIN函数LJMP?C_STARTEND总之,在KEIL中,汇编是从ORG 000H开始启动,那么它在C51中是如何启动MAIN()函数的呢?实际上是C51中有一个启启动程序STARTUP.A51,它总是和C程序一起编译和链接的.启动文件STARTUP.A51中包含目标板启动代码,可在每个project中加入这个文件,只要复位,则该文件立即执行,其功能包括:z 定义内部RAM大小、外部RAM大小、可重入堆栈位置z 清除内部、外部或者以此页为单元的外部存储器z 按存储模式初使化重入堆栈及堆栈指针z 初始化8051硬件堆栈指针z 向main( )函数交权头文件详解/*--------------------------------------------------------------------------REG51.HHeader file for generic 80C51 and 80C31 microcontroller.Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.All rights reserved.--------------------------------------------------------------------------*/#ifndef __REG51_H__#define __REG51_H__/* 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;/* 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;/* 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;/* 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;#endif/*-------------------------------------------------------------------------- INTRINS.HIntrinsic functions for C51.Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc. All rights reserved.--------------------------------------------------------------------------*/#ifndef __INTRINS_H__#define __INTRINS_H__extern void _nop_ (void);extern bit _testbit_ (bit);extern unsigned char _cror_ (unsigned char, unsigned char);extern unsigned int _iror_ (unsigned int, unsigned char);extern unsigned long _lror_ (unsigned long, unsigned char);extern unsigned char _crol_ (unsigned char, unsigned char);extern unsigned int _irol_ (unsigned int, unsigned char);extern unsigned long _lrol_ (unsigned long, unsigned char);extern unsigned char _chkfloat_(float);#endif关于sfr、sbit://如同int、char...sfr 似乎不是标准C 语言的关键字,而是Keil 为能直接访问80C51 中的SFR 而提供了一个新的关键词,其用法是:sfrt 变量名=地址值。
单片机C语言项目式教程
单片机C语言项目式教程单片机是一种集成电路芯片,具有微型计算机的功能,通常用于嵌入式系统中。
C语言是一种高级编程语言,结构清晰、语法简洁,非常适用于单片机编程。
本文将介绍一些单片机C语言项目实践,帮助初学者掌握单片机的编程技巧。
首先,我们来看一个简单的单片机C语言项目:LED闪烁。
在这个项目中,我们将使用单片机控制一个LED灯反复闪烁。
首先,我们需要了解单片机的IO口。
IO口是用来连接外部设备的引脚,我们可以通过控制IO口的高低电平来控制外部设备的状态。
接下来,我们利用C语言编写程序来控制LED闪烁。
首先,我们需要引入头文件,定义IO口的引脚号,以及定义延时函数。
然后,我们在主函数中设置IO口的状态为输出模式,并且定义一个死循环,循环中通过设置IO口的高低电平来闪烁LED灯。
下面是一个简单的LED闪烁程序示例:```#include <reg51.h>#define LED_PIN P1_0void delay(unsigned int count)unsigned int i, j;for (i = 0; i < count; i++)for (j = 0; j < 1000; j++);int mainwhile (1)LED_PIN=1;//点亮LED灯delay(1000); // 延时LED_PIN=0;//熄灭LED灯delay(1000); // 延时}return 0;```在上述程序中,我们使用`reg51.h`头文件来引入单片机的寄存器定义,这个头文件包含了一些常用的寄存器定义和函数。
然后,我们定义了LED的引脚号为`P1_0`,这意味着我们使用P1端口的0号引脚来控制LED灯。
接下来,我们定义了一个延时函数`delay`,用于实现简单的延时功能。
在这个函数中,我们通过两个循环来实现延时,具体的延时时间取决于循环的次数。
在主函数中,我们通过设置LED引脚的电平来控制LED灯的状态。
补充-单片机的C语言-11通信
4.1 一个简单小实例
仿真电路演示
对简单程序分析
#include "reg51.h“ #define uint unsigned int #define uchar unsigned char void msec (unsigned int) sbit p1_0 = P1^0; void main() { p1_0 = 0; mesc(1000) p1_0=1; } void msec (uint x) {uchar j; while((x--)!=0) {for(j=0;j<125;j++) {; ;} } }
C51的数据类型扩充定义
几点说明 1)用sbit定义的位变量,必须能够按位操作; 2)用sbit定义位变量,必须放在函数外面作为全 局位变量,而不能在函数内部定义。 3)用sbit每次只能定义一个位变量。
C51的数据类型扩充定义
二、位寻址区变量的位定义
sbit 位变量名 = bdata型变量名^位号常数
C51的数据类型扩充定义
几点说明: 1)定义特殊功能寄存器中的地址必须在 0x80~0xff范围内。 2)定义特殊功能寄存器,属于宏定义范畴, 必须放在函数外面作为全局变量。 3)用sfr或sfr16每次只能定义一个特殊功 能寄存器。 4)像sbit一样,用sfr或sfr16定义的是绝 对定位的变量(因为名字是与确定地址对应的), 具有特定的意义,在应用时不能像一般变量那样 随便使用。
4.2 C语言的基本语法
4.2.1 C-51的包含的头文件
通常有: reg51.h reg52.h math.h ctype.h stdio.h stdlib.h absacc.h 常用有: reg51.h reg52.h(定义特殊功能寄存器和位寄存器) 访问SFR和SFR_bit地址REGxxx.H math.h (定义常用数学运算); STDIO.H一般I/0函数 CTYPE.H字符函数 STRING .H字符串函数
C51单片机的头文件REG51 和REG52
/*--------------------------------------------------------------------------REG51.HHeader file for generic 80C51 and 80C31 microcontroller.Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.All rights reserved.--------------------------------------------------------------------------*/#ifndef __REG51_H__#define __REG51_H__/* 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;/* BIT Register *//* PSW */sbit CY = 0xD7;sbit AC = 0xD6;sbit F0 = 0xD5;sbit RS1 = 0xD4;sbit RS0 = 0xD3;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;/* 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; /* 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 TI = 0x99;sbit RI = 0x98;#endif--------------------------------------------------------------/*--------------------------------------------------------------------------REG52.HHeader file for generic 80C52 and 80C32 microcontroller.Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.All rights reserved.--------------------------------------------------------------------------*/#ifndef __REG52_H__#define __REG52_H__/* BYTE Registers */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 IP = 0xB8;sfr SCON = 0x98;sfr SBUF = 0x99;/* 8052 Extensions */sfr T2CON = 0xC8;sfr RCAP2L = 0xCA;sfr RCAP2H = 0xCB;sfr TL2 = 0xCC;sfr TH2 = 0xCD;/* BIT Registers *//* PSW */sbit CY = PSW^7;sbit AC = PSW^6;sbit F0 = PSW^5;sbit RS1 = PSW^4;sbit RS0 = PSW^3;sbit OV = PSW^2;sbit P = PSW^0; //8052 only /* TCON */sbit TF1 = TCON^7;sbit TR1 = TCON^6;sbit TF0 = TCON^5;sbit TR0 = TCON^4;sbit IE1 = TCON^3;sbit IT1 = TCON^2;sbit IE0 = TCON^1;sbit IT0 = TCON^0;/* IE */sbit EA = IE^7;sbit ET2 = IE^5; //8052 onlysbit ES = IE^4;sbit ET1 = IE^3;sbit EX1 = IE^2;sbit ET0 = IE^1;sbit EX0 = IE^0;/* IP */sbit PT2 = IP^5;sbit PT1 = IP^3;sbit PX1 = IP^2;sbit PT0 = IP^1;sbit PX0 = IP^0;/* P3 */sbit RD = P3^7;sbit WR = P3^6;sbit T1 = P3^5;sbit T0 = P3^4;sbit INT1 = P3^3;sbit INT0 = P3^2;sbit TXD = P3^1;sbit RXD = P3^0;/* SCON */sbit SM0 = SCON^7;sbit SM1 = SCON^6;sbit SM2 = SCON^5;sbit REN = SCON^4;sbit TB8 = SCON^3;sbit RB8 = SCON^2;sbit TI = SCON^1;sbit RI = SCON^0;/* P1 */sbit T2EX = P1^1; // 8052 only sbit T2 = P1^0; // 8052 only /* T2CON */sbit TF2 = T2CON^7;sbit EXF2 = T2CON^6;sbit RCLK = T2CON^5;sbit TCLK = T2CON^4;sbit EXEN2 = T2CON^3;sbit TR2 = T2CON^2;sbit C_T2 = T2CON^1;sbit CP_RL2 = T2CON^0;#endif。
C51单片机头文件INTRINS.H的作用
原型:unsigned char _crol_(unsigned char val,unsigned char n);
unsigned int _irol_(unsigned int val,unsigned char n);
unsigned int _lrol_(unsigned int val,unsigned char n);
功能:_nop_产生一个NOP指令,该函数可用作C程序的时间比较。C51编译器在_nop_函数工作期间不产生函数调用,即在程序中直接执行了NOP指令。
例:
P()=1;
_nop_();
P()=0;
函数名:_testbit_
原型:bit _testbit_(bit x);
功能:_testbit_产生一个JBC指令,该函数测试一个位,当置位时返回1,否则返回0。如果该位置为1,则将该位复位为0。8051的JBC指令即用作此目的。_testbit_只能用于可直接寻址的位;在表达式中使用是不允许的。
}
函数名:_cror_,_iror_,_lror_
原型:unsigned char _cror_(unsigned char val,unsigned char n);
unsigned int _iror_(unsigned int val,unsigned char n);
unsigned int _lror_(unsigned int val,unsigned char n);
结果10101010。
功能:_crol_,_irol_,_lrol_以位形式将val左移n位,该函数与8051“RLA”指令相关,上面几个函数不同于参数类型。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
单片机C语言编程头文件解析一,C51内存结构深度剖析二,reg51.头文件剖析三,浅淡变量类型及其作用域四,C51常用头文件五,浅谈中断六,C51编译器的限制七,小淡C51指针*************************************我们平时写单片机应用程序的时候,所使用的头文件大多都是用的的reg51.h或是用reg52.h。
会写C51的人都会用,但对其头文件内部的定义有所了解的人确并不多。
下面对其内部做详细解释,方便读者作进一步的了解,并能运用各类型号的单片机。
因为增强型号的单片机的增强功能都是通过特殊功能寄存器(SFR)控制。
打开reg52.h 头文件,会发现是由大量的sfr ,sbit的声明组成,甚至于还有sfr16.其实这样的声明都是与单片机内部功能寄存器(特殊功能寄存器)联系起来的,下面对其做出详细解释SFR 声明一个变量,它的声明与其它的C变量声明基本相同,唯一的区别,SFR在声明的同时为其指定特殊功能寄存器作为存储地址,而不同于C变量声明的整型,字符型等等由编译器自动分配存储空间。
(sfr只用于特殊功能寄存器的声明)如reg52.h头文件,第一条声明就是sfr P0 = 0x80;此处声明一个变量P0,并指定其存储地址为特殊功能寄存器0x80;,在加入reg52.h 头文件后。
编写应用程序时P0就可以直接使用而无需定义,对P0的操作就是,对内部特殊功能寄存器(0x80对应用MCU的P0口)的操作,可进行读写操作。
如果将第一条声明改为sfr K0 = 0x80; 那么,如果要把单片机的P0口全部拉低,则不能写P0=0x00;而应保存后再在应用程序中写成K0=0x00;否则编译器会提示“P0为未定义标识符”使用方法:sfr [variable] = [address] //为变量分配一个特殊功能寄存器。
1、等号右边,只能是十进制,十六进制整型的数据常量,不允许带操作符的表达式。
经典的8051内核支持的SFR地址从0x80H~0xFF 飞利浦80C51MX系列0x180H~0x1FF2、SFR不能声明于任何函数内部,包括main函数。
只能声明于函数外。
3、用SFR声明一个变量后,不能用取地址运算符&获取其地址,编译无法通过,编译器会提示非法操作。
4、有一点须特别注意,51内核0x80~0xff,为特殊功能寄存器地址区间,但并不是所有的地址都有定义,如果说你所用的MCU芯片上对于某个地址没有定义,那么用sfr 在定义变量的时候,不要把变量的地址分配到未定义的特殊功能寄存器上,虽然编译时能通过,用KEIL仿真时貌似是没有问题,但下载到芯片里运行时,是会出问题的。
比如说,向一个未定义的特殊功能寄存器执行读操作,读出来的就是一个未知的数。
(读者可自行测试,先把串口通信调通,然后做一个简单的人机交互。
读出一个数后,再发给计算机,用串口调试助手或是串口监控查看。
这用方法在仿真的时候很有用。
)所以具体那些特殊功能寄存器能够用,就要查看你使用的芯片手册。
5、若遇到增强性的单片机,只要知道其扩展的特殊功能寄存器的地址,用SFR定就可以很方便进行编程。
*************************************sbit同样是声明一个变量,和SFR 使用方法类似,但是SBIT是用来声明一个位变量,因为,在51系列的应用中,非常有必要对SFR的单个位进行存取,而通过bit 数据类型,使其具备位寻址功能。
如,在reg52.h中有如下声明sfr IE = 0xA8;sbit EA = IE^7;sbit ET2 = IE^5; //8052 onlysbit ES = IE^4;sbit ET1 = IE^3;sbit EX1 = IE^2;sbit ET0 = IE^1;sbit EX0 = IE^0;所以,对EA的操作即是对IE最高位的操作。
但如果想让SP DPL DPH PCON TMOC TL0 TL1 TH0 TH1 SBUF这些特殊功能寄存器具备位寻址,采用上述如IE类似的定义,是不行的,虽然修改后,在编译的时候不会出现错误,但只要用到你定义的位变量名时就会出错。
原因是,只有特殊功能寄存器的地址是8的倍数(十六进制以0或8结尾)才能进行位寻址。
打开reg52.h头文件可以看到,所有用sbit声明了的特殊功能寄存器的地址均是以0或8结尾如硬要达到上述要求,可用带参的宏定义来完成。
此处不做详细说明(意义并不大)。
下面对sbit的使用做详细介绍:随着8051的应用,非常有必要对特殊功能寄存器的单个bit位进行存取,C51编译器通过sbit数据类型,提供了对特殊功能寄存器的位操作。
以下是sbit的三种应用形式:一,sbit name = sfr-name^bit-position;sfr PSW =0xD0;sfr IE =0xA8;sbit OV= PSW^2;sbit CY=PSW^7;sbit EA= IE^7;二,sbit name= sft-address^bit-position;sbit OV =0xD0^2;sbit CY =0xD0^7;sbit EA =0xA8^7;三,sbit name= sbit-address;sbit OV =0xD2;sbit CY =0xD7;sbit EA =0xAF;现对上述三种形式的声明做必要的说明第一种形式sbit name = sfr-name^bit-position;如sbit OV= PSW^2; 当中的这个特殊功能寄存器必须在此之前已经用sfr定义,否则编译会出错。
bit-position范围从0~7;第二种形式sbit name= sft-address^bit-position如sbit OV =0xD0^2; 与第一种形式不同之外在于,此处直接使用PSW的地址.第一种形式须先定义PSW第三种形式. sbit name= sbit-address 如sbit OV =0xD2 是直接用的OV的地址OV的地址计算方式,是OV所在的寄存器地址加上OV的bit-position注意:不是所有的SFR都可位寻址。
只有特殊功能寄存器的地址是8的倍数(十六进制以0或8结尾)才能进行位寻址,并且sbit声明的变量名,虽可以是任意取,但是最好不要以下划线开头,因为以下划线开头的都保留给了C51的头文件做保留字。
sfr16: 声明变量许多8051的派生型单片机,用两个连续地址的特殊功能寄存器,来存储一个16bit的值。
例如,8052就用了0xCC和0xCD来保存定时/计数寄存器2的高字节和低字节。
编译器提供sfr16这种数据类型,来保存两个字节的数据。
虚拟出一个16bit的寄存器。
如下:sfr16 T2 = 0xCC存储方面为小端存储方式,低字节在前,高字节在后。
定义时,只写低字节地址,如上,则定义T2为一个16位的特殊功能寄存器。
T2L= 0CCh, T2H= 0CDh使用方法:sfr [variable] = [low_address]1 等号右边,只写两个特殊功能寄存器的低地址,且只能是十进制,十六进制的整型数据常量,不允许带操作符的表达式2 SFR不能声明于任何函数内部,包括main函数。
只能声明于函数外。
3 用SFR声明一个变量后,不能用取地址运算符&获取其地址,编译无法通过,编译器会提示非法操作。
4 当你向一个sfr16写入数据的时候,KEIL CX51 编译器生成的代码,是先写高字节,后写低字节,(可通过返汇编窗口查看)在有些情况下,这并非我们所想要的操作顺序。
使用时,须注意。
5 当你所要写入sfr16的数据,当是高字节先写还是低字节先写非常重要的时候,就只能用sfr这个关键字来定义,并且任意时刻只保存一个字节,这样操作才能保证写入正确。
//////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////C51常用头文件在KEIL 中,对于单片机所使用的头文件,除了reg51 reg52以外,还有一些从各芯片制商的官网下载与reg51,reg52功能类似的头文件,需了解透外,还要对各类型单片机均可通用且相当有用的的头文件,做相应的了解。
因为,内部所包含的函数与宏定义,可以及大的方便我们编写应用程序。
1字符函数ctype.h1 extern bit isalpha(char);功能:检查参数字符是否为英文字母,是则返回12 extern bit isalnum(char)功能:检查字符是否为英文字母或数字字符,是则返回13 extern bit iscntrl(char)功能:检查参数值是否在0x00~0x1f 之间或等于0x7f,是则返回14 extern bit isdigit(char)功能:检查参数是否为数字字符,是则返回15 extern bit isgraph(char)功能:检查参数值是否为可打印字符,是则返回1,可打印字符为0x21~0x7e6 extern bit isprint(char)功能:除了与isgraph相同之外,还接受空格符0x207 extern bit ispunct(char)功能:不做介绍。
8 extern bit islower(char)功能:检查参数字符的值是否为小写英文字母,是则返回19 extern bit isupper(char)功能:检查参数字符的值是否为大写英文字母,是则返回110 extern bit isspace(char)功能:检查字符是否为下列之一,空格,制表符,回车,换行,垂直制表符和送纸。
如果为真则返回111 extern bit isxdigit(char)功能:检查参数字符是否为16进制数字字符,是则返回112 extern char toint(char)功能:将ASCII字符0~9 a~f(大小写无关)转换成对应的16进制数字,返回值00H~0FH13 extern char tolower(char)功能:将大写字符转换成小写形式,如字符变量不在A~Z之间,则不作转换而直接返回该字符14 extern char toupper(char)功能:将小写字符转换成大写形式,如字符变量不在a~z之间,则不作转换而直接返回该字符15 define toascii(c) ((c)&0x7f)功能:该宏将任何整形数值缩小到有效的ASCII范围之内,它将变量和0x7f相与从而去掉第7位以上的所有数位16 #define tolower(c) (c-‘A’+’a’)功能:该宏将字符与常数0x20 逐位相或17 #define toupper(c) ((c)-‘a’+’A’)功能:该宏将字符与常数0xdf 逐位相与2数学函数math.hexternint abs (intval);extern char cabs (char val);extern long labs (long val);extern float fabs (float val);功能:返回绝对值。