51单片机intrins.h
- 格式:doc
- 大小:34.00 KB
- 文档页数:2
/**************************************//* 信号发生器(正弦波,方波,三角波)*//*************************************/#include<reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit cs=P2^0; //tlc5615片选端口sbit clk=P2^1; //tlc5615时钟线sbit din=P2^2; //tlc5615传输端口sbit key1=P1^0;sbit key2=P1^1; //按键的单片机接口uchar keydat;uchar flag; //波形发生终止信号的标志位一旦被置零立马停止发信号uchar flagsqu; //方波高低电平控制为(运用定时器1中断控制)uchar m,num;uchar dat=0xff;uchar code tosin[141]={ //正弦波的编码0x00,0x01,0x02,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0d,0x0e,0x10,0x11,0x13,0x15,0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b,0x2e,0x30,0x33,0x35,0x38,0x3a,0x3d,0x40,0x43,0x45,0x48,0x4c,0x4e,0x51,0x55,0x57,0x5a,0x5d,0x60,0x63,0x66,0x69,0x6c,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7e,0x7f,0x80,0x7f,0x7e,0x7e,0x7d,0x7c,0x7b,0x7a,0x79,0x78,0x77,0x76,0x75,0x74,0x73,0x72,0x6f,0x6c,0x69,0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,0x51,0x4e,0x4c,0x48,0x45,0x43,0x40,0x3d,0x3a,0x38,0x35,0x33,0x30,0x2e,0x2b,0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a,0x18,0x16,0x15,0x13,0x11,0x10,0x0e,0x0d,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x02,0x01,0x00};void delay(uchar z) //延时函数{uchar x,y;for(x=0;x<110;x++)for(y=z;y>0;y--);}void prepare() //tlc5615的初始化{cs=1;din=1;clk=0;cs=0; //cs的上升沿和下降沿必须在clk 为低时进?}/* 用中断来产生方波void Squtranslator(){TR1=1; //启动定时器1 控制高低电平的持续时间占空比do{do{_wave=0;}while((!flagsqu) && flag==1);//如果一旦终止信号的//产生可以立马退出循环flagsqu=0;do{_wave=1;}while((!flagsqu) && flag==1);flagsqu=0;}while(flag);flag=1;TR1=0;}*/void Squtranslator() //方波函数{uchar j;uchar dat1=0x7f;while(flag){do{prepare();dat=dat1;for(j=0;j<12;j++){din=(bit)(dat>>7); //将数据的最高位赋给dinclk=1;dat=dat<<1; //一位位的传输clk=0;}cs=1; //cs的上升沿和下降沿必须在clk 为低时进行delay(200); //使高低电平持续一段时间if(dat1==0)dat1=0x7f; //完成了0和0x7f之间的替换elsedat1=0;}while(flag);}}void Tratranslator() //锯齿波的发生函数{uchar j;uchar dat1=0x7f;while(flag){do{prepare();dat=dat1;for(j=0;j<12;j++){din=(bit)(dat>>7); //将数据的最高位赋给dinclk=1;dat=dat<<1; //一位位的传输clk=0;}cs=1; //cs的上升沿和下降沿必须在clk 为低时进行delay(2); //稍加延时dat1--;}while(flag && dat1); //一旦有终止信号就可以停止do{prepare();dat=dat1;for(j=0;j<12;j++){din=(bit)(dat>>7); //将数据的最高位赋给dinclk=1;dat=dat<<1; //一位位的传输clk=0;}cs=1; //cs的上升沿和下降沿必须在clk 为低时进行delay(2); //稍加延时dat1++;}while(flag && (!(dat1==0x7f)));}}void Sintranslator(uchar wave[],uchar num )//正弦波的转换函数{uchar i,j;uchar dat1;do{for(i=0;i<num;i++){prepare();dat1=wave[i]; //打开片选开始工作for(j=0;j<12;j++){din=(bit)(dat1>>7); //将数据的最高位赋给dinclk=1;dat1=dat1<<1; //一位位的传输clk=0;if(flag==0)break;}cs=1; //cs的上升沿和下降沿必须在clk为低时进行delay(1); //稍加延时if(flag==0)break;}}while(flag); //等待控制键的暂停}void keyscan() //切换功能按键返回键值函数{uchar i;for(i=0;i<4;i++){if(key1==0){delay(10);if(key1==0){keydat++;do{}while(!key1); //松手检测if(keydat==4)keydat=1;//加满回零处理}}}}void keycountrl() //切断输出控制函数{if(key2==0){delay(10);if(key2==0){flag=0;do{}while(!key2); //松手检测}}}void main (){uchar temp;TMOD=0x01; //确定定时器的工作方式TH0=(65536-50000)/256; //给定时器0赋予初值TL0=(65536-50000)%256;EA=1; //开总中断ET0=1; //开启定时器0中断TR0=1;while(1){do{switch(keydat){case 1:flag=1;do{Sintranslator(tosin,141);}while(flag);break;case 2: flag=1;do{Tratranslator();}while(flag);break;case 3: flag=1;do{Squtranslator();}while(flag);break;default:break;}}while(flag);temp=keydat; //装载键值while(keydat==temp); //在这里等待键值的改变}}void Time0() interrupt 1{TH0=(65536-50000)/256; //定时器0用来扫描按键不断地扫描dTL0=(65536-50000)%256;num++;if(num==4){keyscan();keycountrl();num=0;}}。
我们在单片机最小系统上接个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空转。
intrins.h编辑本段intrins.h在C51单片机编程中,头文件INTRINS.H的函数使用起来,就会让你像在用汇编时一样简便.内部函数描述_crol_ 字符循环左移_cror_ 字符循环右移_irol_ 整数循环左移_iror_ 整数循环右移_lrol_ 长整数循环左移_lror_ 长整数循环右移_nop_ 空操作8051 NOP 指令_testbit_ 测试并清零位8051 JBC 指令函数名: _crol_,_irol_,_lrol_原型: 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);举例:_crol_,_cror_:将char型变量循环向左(右)移动指定位数后返回_testbit_:相当于JBC bitvar测试该位变量并跳转同时清除。
_chkfloat_:测试并返回源点数状态。
就是汇编中的子函数。
_crol_,_cror_:如果二进制数为01010101 那么_crol_(1) 左移1位后将高位补低位。
结果10101010。
功能:_crol_,_irol_,_lrol_以位形式将val 左移n 位,该函数与8051“RLA”指令相关,上面几个函数不同于参数类型。
例:#include <intrins.h>main(){unsigned int y;C-5 1 程序设计 37y=0x00ff;y=_irol_(y,4);}函数名: _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);功能:_cror_,_iror_,_lror_以位形式将val 右移n 位,该函数与8051“RRA”指令相关,上面几个函数不同于参数类型。
MCS-51单片机的特殊功能寄存器从图中我们可以看出,在51单片机内部有一个CPU用来运算、控制,有四个并行I/O口,分别是P0、P1、P2、P3,有ROM,用来存放程序,有RAM,用来存放中间结果,此外还有定时/计数器,串行I/O口,中断系统,以及一个内部的时钟电路。
在一个51单片机的内部包含了这么多的东西。
对图进行进一步的分析,我们已知,对并行I/O口的读写只要将数据送入到相应I/O 口的锁存器就可以了,那么对于定时/计数器,串行I/O口等怎么用呢?在单片机中有一些独立的存储单元是用来控制这些器件的,被称之为特殊功能寄存器(SFR)。
事实上,我们已接触过P1这个特殊功能寄存器了,还有哪些呢?看下表下面,我们介绍一下几个常用的SFR。
1、ACC---是累加器,通常用A表示。
这是个什么东西,可不能从名字上理解,它是一个寄存器,而不是一个做加法的东西,为什么给它这么一个名字呢?或许是因为在运算器做运算时其中一个数一定是在ACC中的缘故吧。
它的名字特殊,身份也特殊,稍后在中篇中我们将学到指令,可以发现,所有的运算类指令都离不开它。
自身带有全零标志Z,若A=0则Z=1;若A≠0则z=0。
该标志常用作程序分枝转移的判断条件。
2、B--一个寄存器。
在做乘、除法时放乘数或除数,不做乘除法时,随你怎么用。
3指针寄存器(1)程序计数器PC指明即将执行的下一条指令的地址,16位,寻址64KB范围,复位时PC = 0000H(2)堆栈指针SP指明栈顶元素的地址,8位,可软件设置初值,复位时SP = 07H(3)数据指针DPTR@R0、@R1、@DPTR;指明访问的数据存储器的单元地址,16位,寻址范围64KB。
DPTR = DPH + DPL。
可以用它来访问外部数据存储器中的任一单元,如果不用,也可以作为通用寄存器来用,由我们自已决定如何使用。
分成DPL(低8位)和DPH(高8位)两个寄存器。
用来存放16位地址值,以便用间接寻址或变址寻址的方式对片外数据RAM或程序存储器作64K字节范围内的数据操作4、PSW-----程序状态字。
51单⽚机内部EEPROM读写#include <reg52.h>#include <intrins.h>//定义类型,⽅便代码移植typedef unsigned char UINT8;typedef unsigned int UINT16;typedef unsigned long UINT32;typedef char INT8;typedef int INT16;typedef long INT32;static UINT8 i=0;/*定义寄存器 ISP*/sfr ISP_DATA= 0xe2; // Flash数据寄存器sfr ISP_ADDRH= 0xe3;// Flash⾼字节地址寄存器sfr ISP_ADDRL= 0xe4;// Flash低字节地址寄存器sfr ISP_CMD= 0xe5;// Flash命令模式寄存器sfr ISP_TRIG= 0xe6;// Flash命令触发寄存器sfr ISP_CONTR= 0xe7;// ISP/IAP 控制寄存器#define NOP() _nop_()#define EEPROM_START_ADDRESS 0X2000#define LED_PORT P2//微秒级延时void DelayNus(UINT16 t){UINT16 d=0;d=t;do{NOP();}while(--d > 0);}//毫秒级延时void DelayNms(UINT16 t){do{DelayNus(1000);}while(--t > 0);}//EEPROM使能void EEPROMEnable(void){ISP_CONTR=0x81;//使能并设置好等待时间}//EEPROM禁⽤void EEPROMDisable(void){ISP_CONTR=0x00;//禁⽌EEPROMISP_CMD = 0X00;//⽆ISP操作ISP_TRIG = 0X00;//清零ISP_ADDRH = 0X00;//清零ISP_ADDRL = 0X00;//清零}//eeprom 设置读写地址(相对地址)void EEPROMSetAddress(UINT16 addr){addr+=EEPROM_START_ADDRESS;//初始化地址ISP_ADDRH=(UINT8)(addr>>8);//设置读写地址⾼字节ISP_ADDRL=(UINT8) addr; //设置读写地址低字节}//EEPROM启动void EEPROMStart(void){ISP_TRIG=0x46;ISP_TRIG=0xB9;}//EEPROM读取单个字节UINT8 EEPROMReadByte(UINT16 addr){ISP_DATA=0X00;ISP_CMD=0X01;EEPROMEnable();EEPROMSetAddress(addr);EEPROMStart();DelayNus(10);//读取⼀个字节需要10usEEPROMDisable();return (ISP_DATA);}//EEPROM写⼊单个字节UINT8 EEPROMWriteByte(UINT16 addr,UINT8 byte) {EEPROMEnable();ISP_CMD=0X02;EEPROMSetAddress(addr);ISP_DATA=byte;EEPROMStart();DelayNus(60);EEPROMDisable();}//EEPROM扇区擦除UINT8 EEPROMSectorErase(UINT16 addr){ISP_CMD=0X03;EEPROMEnable();EEPROMSetAddress(addr);EEPROMStart();DelayNus(10);//EEPROMDisable();}void main(void){EEPROMSectorErase(0);EEPROMWriteByte(0,0x0f);i=EEPROMReadByte(0);LED_PORT = i;while(1);}现象:。
新概念51单片机C语言教程----入门、提高、开发、拓展全攻略郭天祥编著电子工业出版社例2.2.1编写程序,点亮第一个发光二极管(part2_1.c P27)#include <reg52.h> //52系列单片机头文件sbit led1=P1^0; //声明单片机P1口的第一位void main() //主函数{led1=0; /*点亮第一个发光二极管*/}例2.2.2编写程序,点亮P1口的若干二极管(part2_2.c P39)#include <reg52.h> //52系列单片机头文件void main() //主函数{P1=0xaa;//while(1);}例2.5.1利用for语句延时特性,编写第一个发光二极管以间隔1S亮灭闪动的程序(part2_3.c P42)#include <reg52.h> //52系列单片机头文件#define uint unsigned int //宏定义sbit led1=P1^0; //声明单片机P1口的第一位uint i,j;void main() //主函数{while(1) //大循环{led1=0; /*点亮第一个发光二极管*/for(i=1000;i>0;i--) //延时for(j=110;j>0;j--);led1=1; /*关闭第一个发光二极管*/for(i=1000;i>0;i--) //延时for(j=110;j>0;j--);}}- 2 - 例2.6.1编写程序使第一个发光二极管以间隔500ms亮灭闪动。
(part2_4.c P48)#include <reg52.h> //52系列单片机头文件#define uint unsigned int //宏定义sbit led1=P1^0; //声明单片机P1口的第一位void delay1s(); //声明子函数void main() //主函数{while(1) //大循环{led1=0; /*点亮第一个发光二极管*/delay1s(); //调用延时子函数led1=1; /*关闭第一个发光二极管*/delay1s(); //调用延时子函数}}void delay1s() //子函数体{uint i,j;for(i=500;i>0;i--)for(j=110;j>0;j--);}例2.7.1编写程序使第一个二极管以亮200ms、灭800ms的方式闪动。
51单片机DHT11芯片,1603显示屏程序代码#include<reg52.h>#include<intrins。
h>typedefunsignedcharuchar;typedefunsignedintuint;typedefunsignedlongulong;ucharcom,flag;ucharn,m,y,x,v,u,a1,a2;//温湿度上下限的参数,其中,nm是温湿度超标与否的标准,值为0或者1.这代码的温湿度报警没有用LED或者蜂鸣器,只用了一个软件参数n、m存储报警信息。
需要添加报警功能的可以自己写额外的功能代码,然后nm两个参数就是功能传递参数。
也可以写多一个串口输出代码,用串口调试助手输出n、m的值验证温湿度是否超标判断正确。
voidDelay1000ms()//@11.0592MHz延时{unsignedchari,j,k;_nop_();i=8;j=1;k=243;do{do{while(--k);}while(--j);}while(--i);}voidDelay500us()//@11.0592MHz {ucharb;_nop_();b=227;while(--b);}voidDelay10us()//@11.0592MHz {uchara;a=2;while(--a);}voiddelay(uintz){uchari,j;for(i=z;i>0;i--)for(j=110;j>0;j--);//ÑÓʱº¯Êý}//************************引脚定义************* /*******按键控制引脚定义*********/sbity_tem_inse=P1^0;//sbity_tem_duce=P1^1;//sbitx_tem_inse=P1^2;//sbitx_tem_duce=P1^3;//sbitu_hum_inse=P1^4;//sbitu_hum_duce=P1^5;//sbitv_hum_inse=P1^6;//sbitv_hum_duce=P1^7;///***********其他功能引脚*****/sbitDQ=P2^1;//DTH11//****LCD的****sbitRS=P2^7;sbitRW=P2^6;sbitEN=P2^5;#defineDataPortP0//LCD的接线,我的是8线接发//-----------------函数声明------------- voiddelay_us(uchart);voiddelay_ms(uchart);bitLCD_Check_Busy(void);voidLCD_Write_Com(ucharcom);voidLCD_Write_Data(ucharData);voidLCD_Clear(void);voidLCD_Write_String(ucharx,uchary,uchar*s);voidLCD_Write_Char(ucharx,uchary,ucharData);voidLCD_Init(void);voidCOMdata();//*************************以下是函数定义***************************//**************液晶屏显示原函数由此开始*************************bitLCD_Check_Busy(void)//检忙{DataPort=0xFF;RS=0;RW=1;EN=0;_nop_();EN=1;return(bit)(DataPort&0x80);voidLCD_Write_Com(ucharcom)//写指令原函数{while(LCD_Check_Busy());RS=0;RW=0;EN=1;DataPort=com;_nop_();EN=0;}voidLCD_Write_Data(ucharData)//写数据原函数{while(LCD_Check_Busy());RS=1;RW=0;EN=1;DataPort=Data;_nop_();EN=0;}voidLCD_Clear(void)//清屏LCD_Write_Com(0x01);delay(1);}voidLCD_Write_String(ucharx,uchary,uchar*s)//操作-显示LCD屏的哪个位置{if(y==0)LCD_Write_Com(0x80+x);elseLCD_Write_Com(0xC0+x);while(*s){LCD_Write_Data(*s);s++;}}voidLCD_Write_Char(ucharx,uchary,ucharData)//操作-显示的数据(字符类型,显示数字需找到该数字的ASCII码){if(y==0)LCD_Write_Com(0x80+x);elseLCD_Write_Com(0xC0+x);LCD_Write_Data(Data);}voidLCD_Init(void)//LCD初始化(可以理解为唤醒){delay(15);LCD_Write_Com(0x38);delay(5);LCD_Write_Com(0x38);delay(5);LCD_Write_Com(0x38);delay(5);LCD_Write_Com(0x38);LCD_Write_Com(0x08);LCD_Write_Com(0x01);LCD_Write_Com(0x06);delay(5);LCD_Write_Com(0x0C);}//****************LCD源码结束***********//*********DHT11原函数以下开始*******//*************************************************** ucharcodeASCII[]="0123456789%c";//普通数字需用该数组转成字符ucharcodetable0[]="Hum:";ucharcodetable1[]="Tem:";uchartem;ucharhum;display0[2]={0,0};display1[2]={0,0};//*************************初始化DTH11voidCOMdata()//读数据{uchari,t;for(i=0;i<8;i++){flag=2;while((!DQ)&&flag++);Delay10us();Delay10us();Delay10us();//先看懂DHT11的工作时序图就知道我这个延时操作的含义了,读高电平多少秒可以对应数据0或1t=0;if(DQ)t=1;while((DQ)&&flag++);if(flag==1)break;com<<=1;com|=t;}}voidRH(void)//该函数包括唤醒DHT11发送数据给单片机也包括单片机把数据提取{DQ=0;delay(21);DQ=1;Delay10us();Delay10us();Delay10us();Delay10us();DQ=1;if(!DQ){flag=2;while((!DQ)&&flag++);while((DQ)&&flag++);COMdata();hum=com;COMdata();COMdata();tem=com;COMdata();COMdata();//小数位这里我不显示,所以不用读取tem或hum 第二次的COMdata()函数获取的数据DQ=1;}}//*********************************LCD显示温湿度数据voidDisplay_DTH11(){ucharxh,xl,yh,yl,vh,vl,uh,ul;xh=x/10%10;xl=x%10;yh=y/10%10;yl=y%10;uh=u/10%10;ul=u%10;vh=v/10%10;vl=v%10;LCD_Write_String(8,0,"L");LCD_Write_Char(9,0,ASCII[uh]);LCD_Write_Char(10,0,ASCII[ul]);LCD_Write_String(12,0,"H");LCD_Write_Char(13,0,ASCII[vh]);LCD_Write_Char(14,0,ASCII[vl]);LCD_Write_String(8,1,"L");LCD_Write_Char(9,1,ASCII[xh]);LCD_Write_Char(10,1,ASCII[xl]);LCD_Write_String(12,1,"H");LCD_Write_Char(13,1,ASCII[yh]);LCD_Write_Char(14,1,ASCII[yl]);display0[1]=hum/10%10;//读hum十位display0[0]=hum%10;//个位LCD_Write_String(0,0,table0);LCD_Write_Char(4,0,ASCII[display0[1]]);LCD_Write_Char(5,0,ASCII[display0[0]]);LCD_Write_Char(6,0,ASCII[10]);//显示在LCD的第几行第几位(这一行是指在第0行,第6位开始显示ASCII[10]里面的字符数据,下同),运行结果是显示了“hum:”这四个字符display1[1]=tem/10%10;display1[0]=tem%10;LCD_Write_String(0,1,table1);LCD_Write_Char(4,1,ASCII[display1[1]]);LCD_Write_Char(5,1,ASCII[display1[0]]);LCD_Write_Char(6,1,0xdf);LCD_Write_Char(7,1,ASCII[11]);}//***************原函数结束*************//voidkeyscan(){if(y_tem_inse==0){delay(10);if(y_tem_inse==0)//这里是消抖,下同{y=y+5;while(y==55)y=50;while(y_tem_inse==0);}if(y_tem_duce==0){delay(10);if(y_tem_duce==0);{y=y-5;while(y==5)y=10;while(y_tem_duce==0);}}if(x_tem_inse==0){delay(10);if(x_tem_inse==0){x=x+5;while(x==55)x=50;while(x_tem_inse==0);}}if(x_tem_duce==0)delay(10);if(x_tem_duce==0);{x=x-5;while(x==5)x=10;while(x_tem_duce==0);}}if(u_hum_inse==0){delay(10);if(u_hum_inse==0){u=u+5;while(u==85)u=80;while(u_hum_inse==0);}}if(u_hum_duce==0){delay(10);if(u_hum_duce==0);u=u-5;while(u==25)u=30;while(u_hum_duce==0);}}if(v_hum_inse==0){delay(10);if(v_hum_inse==0){v=v+5;while(v==85)v=80;while(v_hum_inse==0);}}if(v_hum_duce==0){delay(10);if(v_hum_duce==0);{v=v-5;while(v==25)v=20;while(v_hum_duce==0);}}}//*******************************上面是按键扫描,以下开始是主函数main(){LCD_Clear();x=10,y=50,u=30,v=80;//温湿度上下限初值,按键函数里可调tem=0;hum=0;//赋初值LCD_Init();Delay1000ms();//DTH11上电一秒后才工作正常while(1){EA=0;keyscan();RH();if((tem>y)||(tem<x))n=1;elsen=0;//LED或蜂鸣器亮灭判断,下同if((hum>v)||(hum<u))m=1;elsem=0;Display_DTH11();Time0_Init();Delay1000ms();Delay1000ms();Delay1000ms();}}。
intrins.h
编辑本段intrins.h
在C51单片机编程中,头文件INTRINS.H的函数使用起来,就会让你
像在用汇编时一样简便.
内部函数描述
_crol_ 字符循环左移
_cror_ 字符循环右移
_irol_ 整数循环左移
_iror_ 整数循环右移
_lrol_ 长整数循环左移
_lror_ 长整数循环右移
_nop_ 空操作8051 NOP 指令
_testbit_ 测试并清零位8051 JBC 指令函数名: _crol_,_irol_,
_lrol_
原型: 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);
举例:
_crol_,_cror_:将char型变量循环向左(右)移动指定位数后返回
_testbit_:相当于JBC bitvar测试该位变量并跳转同时清除。
_chkfloat_:测试并返回源点数状态。
就是汇编中的子函数。
_crol_,_cror_:如果二进制数为01010101 那么_crol_(1) 左移1位
后将高位补低位。
结果10101010。
功能:_crol_,_irol_,_lrol_以位形式将val 左移n 位,该函数
与8051“RLA”指令相关,上面几个函数不同于参数类型。
例:
#include <intrins.h>
main()
{
unsigned int y;
y=0x00ff;
y=_irol_(y,4);
}
函数名: _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);
功能:_cror_,_iror_,_lror_以位形式将val 右移n 位,该函数与8051“RRA”指令相关,上面几个函数不同于参数类型。
例:
#include <intrins.h>
main()
{
unsigned int y;
y=0x0ff00;
y=_iror_(y,4);
}
函数名: _nop_
原型: void _nop_(void);
功能:_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_只能用于可直接寻址的位;在表达式中使用是不允许的。