单片机实训_单片机实训台

2020-02-28 其他范文 下载本文

单片机实训由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“单片机实训台”。

#include //用AT89C51时就用这个头文件

//#include //用华邦W78E58B时必须用这个头文件 #include /*Intrins.h文件包含只是编译器产生嵌入原有代码的程序的原型*/

//注意那个LCD_Wait()函数,它是判“忙”标志的,在实际硬件要把注掉的那种打开

//Port Definitions********************************************************** sbitLcdRs = P2^0;sbit:特殊功能寄存器,位寻址,位变量名=特殊功能寄存器名^位位置

sbitLcdRw = P2^1;sbitLcdEn = P2^2;sfrDBPort = 0x80;//P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口

sfr特殊功能寄存器名=特殊功能寄存器地址常数

sfr16: 16位特殊功能寄存器,字寻址,低位在低字节,高

位在高字节

//内部等待函************************************************************************** unsigned char LCD_Wait(void){ LcdRs=0;LcdRw=1;_nop_();LcdEn=1;_nop_();

数 //while(DBPort&0x80);//在用Proteus仿真时,注意用屏蔽此语句,在调用GotoXY()时,会进入死循环,//可能在写该控制字时,该模块没有返回写入完备命令,即DBPort&0x80==0x80

//实际硬件时打开此语句

LcdEn=0;returnDBPort;} //向LCD写入命令或数据************************************************************ #define LCD_COMMAND

0

// Command #define LCD_DATA

// Data #define LCD_CLEAR_SCREEN 0x01

// 清屏 #define LCD_HOMING

0x02

// 光标返回原点 voidLCD_Write(bit style, unsigned char input){ LcdEn=0;LcdRs=style;LcdRw=0;_nop_();

} DBPort=input;_nop_();//注意顺序 LcdEn=1;_nop_();//注意顺序 LcdEn=0;_nop_();LCD_Wait();

//设置显示模式************************************************************ #define LCD_SHOW

0x04

//显示开 #define LCD_HIDE

0x00

//显示关

#define LCD_CURSOR

0x02 //显示光标 #define LCD_NO_CURSOR 0x00

//无光标

#define LCD_FLASH

0x01

//光标闪动 #define LCD_NO_FLASH 0x00

//光标不闪动

voidLCD_SetDisplay(unsigned char DisplayMode){ LCD_Write(LCD_COMMAND, 0x08|DisplayMode);}

//设置输入模式************************************************************ #define LCD_AC_UP

0x02 #define LCD_AC_DOWN 0x00

// default

#define LCD_MOVE

0x01

// 画面可平移 #define LCD_NO_MOVE 0x00

//default

voidLCD_SetInput(unsigned char InputMode){ LCD_Write(LCD_COMMAND, 0x04|InputMode);}

//初始化LCD************************************************************ voidLCD_Initial(){ LcdEn=0;LCD_Write(LCD_COMMAND,0x38);

//8位数据端口,2行显示,5*7点阵

LCD_Write(LCD_COMMAND,0x38);LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);

//开启显示, 无光标

LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);

//清屏

LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);

//AC递增, 画面不动 } //************************************************************************ voidGotoXY(unsigned char x, unsigned char y){ if(y==0)

LCD_Write(LCD_COMMAND,0x80|x);if(y==1)

LCD_Write(LCD_COMMAND,0x80|(x-0x40));}

void Print(unsigned char *str){ while(*str!=''){

LCD_Write(LCD_DATA,*str);

str++;} } voidLCD_Print(unsigned char x, unsigned char y, unsigned char *str){ GotoXY(x,y);Print(str);}

#include //用AT89C51时就用这个头文件

//#include //用华邦W78E58B时必须用这个头文件 sbit DQ = P3^4;

//定义DQ引脚为P3.4 /***********ds18b20延迟子函数(晶振12MHz)*******/ /***********DS18B20对时间要求很严,但只能长不能短 ************在11.0592M下也行,因为时间长些********/ void delay_18B20(unsigned int i){ while(i--);

/**********ds18b20初始化函数**********************/

void Init_DS18B20(void){ unsigned char x=0;

DQ = 1;

//DQ复位

delay_18B20(8);//稍做延时

DQ = 0;

//单片机将DQ拉低

delay_18B20(80);//精确延时大于 480us

DQ = 1;

//拉高总线

delay_18B20(14);

x=DQ;

//稍做延时后如果x=0则初始化成功 x=1则初始化失败

delay_18B20(20);}

/***********ds18b20读一个字节**************/

unsigned char ReadOneChar(void){ unsigned char i=0;unsigned char dat = 0;for(i=8;i>0;i--)

{

DQ = 0;// 给脉冲信号

dat>>=1;

DQ = 1;// 给脉冲信号

if(DQ)

dat|=0x80;

delay_18B20(4);

} return(dat);}

/*************ds18b20写一个字节****************/

voidWriteOneChar(unsigned char dat){ unsigned char i=0;for(i=8;i>0;i--)

} } { DQ = 0;DQ = dat&0x01;delay_18B20(5);DQ = 1;dat>>=1;/**************读取ds18b20当前温度************/ unsigned char *ReadTemperature(char TH,charTL,unsigned char RS){ unsigned char tt[2];Init_DS18B20();

} WriteOneChar(0xCC);

// 跳过读序号列号的操作

WriteOneChar(0x4E);// //写入“写暂存器”命令,修改TH和TL和分辩率配置寄存器

//先写TH,再写TL,最后写配置寄存器 WriteOneChar(TH);//写入想设定的温度报警上限 WriteOneChar(TL);//写入想设定的温度报警下限 WriteOneChar(RS);//写配置寄存器,格式为0 R1 R0 1,1 1 1 1

//R1R0=00分辨率娄9位,R1R0=11分辨率为12位 delay_18B20(80);

// this meage is wery important Init_DS18B20();WriteOneChar(0xCC);

// 跳过读序号列号的操作 WriteOneChar(0x44);// 启动温度转换

delay_18B20(80);

// this meage is wery important Init_DS18B20();WriteOneChar(0xCC);//跳过读序号列号的操作

WriteOneChar(0xBE);//读取温度寄存器等(共可读9个寄存器)前两个就是温度 delay_18B20(80);tt[0]=ReadOneChar();

tt[1]=ReadOneChar();

return(tt);

//读取温度值低位

//读取温度值高位

#include //用AT89C51时就用这个头文件

//#include //用华邦W78E58B时必须用这个头文件 #include #include #include #include #include

//sbit DQ = P3^4;

//定义DQ引脚为P3.4 unsigned char t[2],*pt;

//用来存放温度值,测温程序就是通过这个数组与主函数通信的unsigned char TempBuffer1[9]={0x2b,0x31,0x32,0x32,0x2e,0x30,0x30,0x43,''};

//显示实时温度,上电时显示+125.00C unsigned char TempBuffer0[17]={0x54,0x48,0x3a,0x2b,0x31,0x32,0x35,0x20,0x54,0x4c,0x3a,0x2b,0x31,0x32,0x34,0x43,''};

//显示温度上下限,上电时显示TH:+125 TL:+124C

unsigned char code dotcode[4]={0,25,50,75};/***因显示分辨率为0.25,但小数运算比较麻烦,故采用查表的方法******* 再将表值分离出十位和个位后送到十分位和百分位********************/

void covert0(unsigned char TH, unsigned char TL)//将温度上下限转换为LCD显示的数据 {

if(TH>0x7F)

//判断正负,如果为负温,将其转化为其绝对值

{

TempBuffer0[3]=0x2d;

//0x2d为“-”的ASCII码

TH=~TH;TH++;

}

else TempBuffer0[3]=0x2b;//0x2B为“+”的ASCII码

if(TL>0x7f)

{

TempBuffer0[11]=0x2d;

//0x2d为“-”的ASCII码

TL=~TL+1;

}

else TempBuffer0[11]=0x2b;//0x2B为“+”的ASCII码

TempBuffer0[4]=TH/100+0x30;

//分离出TH的百十个位

if(TempBuffer0[4]==0x30)TempBuffer0[4]=0xfe;//百位数消隐

TempBuffer0[5]=(TH%100)/10+0x30;

//分离出十位

TempBuffer0[6]=(TH%100)%10+0x30;

//分离出个位

TempBuffer0[12]=TL/100+0x30;

//分离出TL的百十个位

if(TempBuffer0[12]==0x30)TempBuffer0[12]=0xfe;//百位数消隐

TempBuffer0[13]=(TL%100)/10+0x30;

//分离出十位

TempBuffer0[14]=(TL%100)%10+0x30;

//分离出个位 }

void covert1(void)//将温度转换为LCD显示的数据 { unsigned char x=0x00,y=0x00;t[0]=*pt;pt++;t[1]=*pt;

if(t[1]>0x07)

//判断正负温度

{

TempBuffer1[0]=0x2d;

//0x2d为“-”的ASCII码

t[1]=~t[1];

/*下面几句把负数的补码*/ t[0]=~t[0];

/* 换算成绝对值*********/ x=t[0]+1;

/***********************/ t[0]=x;

/***********************/ if(x>255)

/**********************/ t[1]++;

/*********************/

}

else TempBuffer1[0]=0x2b;//0xfe为变“+”的ASCII码

t[1]

t[1]=t[1]&0x70;//取出高字节的3个有效数字位

x=t[0];

//将t[0]暂存到X,因为取小数部分还要用到它

x>>=4;

//右移4位

x=x&0x0f;

//和前面两句就是取出t[0]的高四位

t[1]=t[1]|x;

//将高低字节的有效值的整数部分拼成一个字节

TempBuffer1[1]=t[1]/100+0x30;

//+0x30 为变 0~9 ASCII码

if(TempBuffer1[1]==0x30)TempBuffer1[1]=0xfe;//百位数消隐

TempBuffer1[2]=(t[1]%100)/10+0x30;

//分离出十位

TempBuffer1[3]=(t[1]%100)%10+0x30;

//分离出个位

t[0]=t[0]&0x0c;

//取有效的两位小数

t[0]>>=2;

//左移两位,以便查表

x=t[0];

y=dotcode[x];

//查表换算成实际的小数

TempBuffer1[5]=y/10+0x30;

//分离出十分位

TempBuffer1[6]=y%10+0x30;

//分离出百分位 }

void delay(unsigned char i){ while(i--);}

main(){ unsigned char TH=110,TL=-20;

//下一步扩展时可能通过这两个变量,调节上下限

//测温函数返回这个数组的头地址 while(1){

pt=ReadTemperature(TH,TL,0x3f);//上限温度-22,下限-24,分辨率10位,也就是0.25C

} }

delay(100);covert1();covert0(TH,TL);

//读取温度,温度值存放在一个两个字节的数组中, LCD_Initial();

//第一个参数列号,第二个为行号,为0表示第一行

//为1表示第二行,第三个参数为显示数据的首地址 LCD_Print(0,0,TempBuffer0);LCD_Print(0,1,TempBuffer1);

《单片机实训.docx》
将本文的Word文档下载,方便收藏和打印
推荐度:
单片机实训
点击下载文档
相关专题 单片机实训台 单片机 实训 单片机实训台 单片机 实训
[其他范文]相关推荐
    [其他范文]热门文章
      下载全文