DS18B20测温显示,proteus仿真。
Written by jinsongliang具体程序如下:#include<>#include""#include""#include""void main (void){unsigned char disp[5]={10,0,0,14,2};signed char temp=0;while(1){/*1、读取温度值*/temp=Get_Temputer();//2、显示前处理*/if(temp<0){disp[0]=13;temp=-temp;disp[1]=temp/10;disp[2]=temp%10;}else{disp[0]=temp/100;disp[1]=temp/10-disp[0]*10;disp[2]=temp%10;if(!disp[0]) //百位数不为0则显示,若要显示0,可将其注释掉disp[0]=10;}//3、显示*/Seg_Display(disp);}}void Delay_Nus (unsigned char n) {while(n--);//for (;n>0;n--);}:/******************************************************************时序很重要,移植时注意延时函数******************************************************************/#define B20_PORT P1 //此处可以设置I/O口#define B20_CHANNEL 0#define R_B20_CHANNEL() B20_PORT&(1<<B20_CHANNEL)#define W_B20_CHANNEL_1() B20_PORT|=(1<<B20_CHANNEL)#define W_B20_CHANNEL_0() B20_PORT&=~(1<<B20_CHANNEL)#define SKIP_ROM 0xCC#define TEMPUTER_CONVERT 0x44#define READ_ROM 0xBE//one/*初始化函数,失败会返回1,初始化过程见注释若单片机读到了数据线上的低电平“0”后,还要做延时,其延时的时间从单片机发出的高电平算起最少要480微秒。
之后单片机将数据线再次拉高到高电平“1”后结束。
*/static unsigned char Init_18b20 (void){unsigned char x=0;W_B20_CHANNEL_1(); //1、从单片机拉高数据线开始Delay_Nus(8); //6*n usecondsW_B20_CHANNEL_0();Delay_Nus(81);W_B20_CHANNEL_1(); //2、单片机拉低数据线480us以上,拉高数据线,释放 Delay_Nus(14); //3、之后ds18b20,15~60us以后反应,拉高数据线x=R_B20_CHANNEL(); //4、单片机读取数据线if(x)return x;Delay_Nus(20);return x; //x=0代表复位成功}//twostatic void Write_18b20(unsigned char w_data){unsigned char i;unsigned char temp;for(i=0;i<8;i++){W_B20_CHANNEL_1();temp=w_data&(1<<0);W_B20_CHANNEL_0(); //单片机从高到低,拉低1us以上,并在15us内产生写间隙B20_PORT=temp<<B20_CHANNEL; //写数据,(先写低位)Delay_Nus(7); //15~60us内18B20采样w_data>>=1;}W_B20_CHANNEL_1();Delay_Nus(4);}//threestatic unsigned char Read_18b20(void){unsigned char i;unsigned char temp;unsigned char r_data=0x00;for(i=0;i<8;i++){r_data>>=1;W_B20_CHANNEL_1();W_B20_CHANNEL_0(); //从高到低15us内,再到高,产生读间隙Delay_Nus(1);W_B20_CHANNEL_1();temp=B20_PORT<<(7-B20_CHANNEL); //读数据,从低位开始temp&=(1<<7);r_data+=temp;Delay_Nus(8); //整个读一位过程在60~120us }W_B20_CHANNEL_1();return r_data;}//four/*若要读出当前的温度数据我们需要执行两次工作周期,第一个周期为复位、跳过ROM指令、执行温度转换存储器操作指令、等待500uS温度转换时间。
紧接着执行第二个周期为复位、跳过ROM指令、执行读RAM的存储器操作指令、读数据(最多为9个字节,中途可停止,只读简单温度值则读前2个字节即可)*/signed char Get_Temputer (void)//读取温度值,返回的带符号字符型-55到+127;128无法显示,初始化失败会显示{unsigned char tem_h,tem_l;signed char temp;if(Init_18b20()==0) //复位18b20{Write_18b20(SKIP_ROM); //跳过ROMWrite_18b20(TEMPUTER_CONVERT); //温度变换}elsereturn temp=0;//Delay_Nus(100);if(Init_18b20()==0) //复位18b20{Write_18b20(SKIP_ROM); //跳过ROMWrite_18b20(READ_ROM); //读暂存存储器}elsereturn temp=0;tem_l=Read_18b20(); //读数据tem_h=Read_18b20();/*只要高字符的低四位和低字符的高四位,温度范围0~99,temp为补码,直接由unsigned char 赋值给 signed char 内容不变,代表的值改变*/temp=(tem_h<<4)+(tem_l>>4);return temp;}:#define COMMON_ANODIC 0 //共阳数码管#define COMMON_CATHODAL 1 //共阴数码管#define SEG_CATEGORY 0 //选择共阳数码管#define SEG8_A ~(1<<0) //段A亮时为0,属共阳数码管#define SEG8_B ~(1<<1)#define SEG8_C ~(1<<2)#define SEG8_D ~(1<<3)#define SEG8_E ~(1<<4)#define SEG8_F ~(1<<5)#define SEG8_G ~(1<<6)#define SEG8_DP ~(1<<7)#define SEG8_CHAR_0 ~(SEG8_G&SEG8_DP)#define SEG8_CHAR_1 ~(SEG8_A&SEG8_D&SEG8_E&SEG8_F&SEG8_G&SEG8_DP)#define SEG8_CHAR_2 ~(SEG8_C&SEG8_F&SEG8_DP)#define SEG8_CHAR_3 ~(SEG8_E&SEG8_F&SEG8_DP)#define SEG8_CHAR_4 ~(SEG8_A&SEG8_D&SEG8_E&SEG8_DP)#define SEG8_CHAR_5 ~(SEG8_B&SEG8_E&SEG8_DP)#define SEG8_CHAR_6 ~(SEG8_B&SEG8_DP)#define SEG8_CHAR_7 ~(SEG8_D&SEG8_E&SEG8_F&SEG8_G&SEG8_DP)#define SEG8_CHAR_8 ~SEG8_DP#define SEG8_CHAR_9 ~(SEG8_E&SEG8_DP)#define SEG8_CHAR_ ~0#define SEG8_CHAR_E ~(SEG8_B&SEG8_C&SEG8_DP)#define SEG8_CHAR_R ~(SEG8_A&SEG8_B&SEG8_C&SEG8_D&SEG8_F&SEG8_DP)#define SEG8_CHAR_SUB ~(SEG8_A&SEG8_B&SEG8_C&SEG8_D&SEG8_E&SEG8_F&SEG8_DP) //#define SEG8_CHAR_A//#define SEG8_CHAR_B#define SEG8_CHAR_C ~(SEG8_B&SEG8_C&SEG8_G&SEG8_DP)//#define SEG8_CHAR_D//#define SEG8_CHAR_F//#define SEG8_CHAR_H#if SEG_CATEGORY==COMMON_ANODICstatic const unsigned char SEG8_CODE[]={SEG8_CHAR_0,SEG8_CHAR_1,SEG8_CHAR_2,SEG8_CHAR_3,SEG8_CHAR_4,SEG8_CHAR_5,SEG8_CHAR_6,SEG8_CHAR_7,SEG8_CHAR_8,SEG8_CHAR_9,SEG8_CHAR_, //SEG8_CODE[10]SEG8_CHAR_E, //SEG8_CODE[11]SEG8_CHAR_R, //SEG8_CODE[12]SEG8_CHAR_SUB, //SEG8_CODE[13]SEG8_CHAR_C //SEG8_CODE[14]};#elsestatic const unsigned char SEG8_CODE[]={~SEG8_CHAR_0,~SEG8_CHAR_1,~SEG8_CHAR_2,~SEG8_CHAR_3,~SEG8_CHAR_4,~SEG8_CHAR_5,~SEG8_CHAR_6,~SEG8_CHAR_7,~SEG8_CHAR_8,~SEG8_CHAR_9,~SEG8_CHAR_, //SEG8_CODE[10]~SEG8_CHAR_E, //SEG8_CODE[11]~SEG8_CHAR_R, //SEG8_CODE[12]~SEG8_CHAR_SUB, //SEG8_CODE[13]~SEG8_CHAR_C //SEG8_CODE[14]};#endif#define SEG8_SLECT_PORT P3 //此处可以设置I/O口#define BIT0 0#define BIT1 1#define BIT2 2#define BIT3 3#define SEG8_BIT0_ON() SEG8_SLECT_PORT|=(1<<BIT0)#define SEG8_BIT0_OFF() SEG8_SLECT_PORT&=~(1<<BIT0)#define SEG8_BIT1_ON() SEG8_SLECT_PORT|=(1<<BIT1)#define SEG8_BIT1_OFF() SEG8_SLECT_PORT&=~(1<<BIT1)#define SEG8_BIT2_ON() SEG8_SLECT_PORT|=(1<<BIT2)#define SEG8_BIT2_OFF() SEG8_SLECT_PORT&=~(1<<BIT2)#define SEG8_BIT3_ON() SEG8_SLECT_PORT|=(1<<BIT3)#define SEG8_BIT3_OFF() SEG8_SLECT_PORT&=~(1<<BIT3)#define SEG8_CODE_PORT P2 //此处可以设置I/O口void Seg_Display (char *p){unsigned char temp[4];temp[0]=SEG8_CODE[*p++];temp[1]=SEG8_CODE[*p++];temp[2]=SEG8_CODE[*p++];temp[3]=SEG8_CODE[*p++];if(*p<4)#if SEG_CATEGORY==COMMON_ANODICtemp[*p]&=SEG8_DP;#elsetemp[*p]|=~SEG8_DP;#endif{unsigned char i;for(i=0;i<150;i++){SEG8_CODE_PORT = temp[0];SEG8_BIT0_ON();Delay_Nus(6); //SEG8_BIT0_OFF();SEG8_CODE_PORT = temp[1];SEG8_BIT1_ON();Delay_Nus(6);SEG8_BIT1_OFF();SEG8_CODE_PORT = temp[2];SEG8_BIT2_ON();Delay_Nus(6);SEG8_BIT2_OFF();SEG8_CODE_PORT = temp[3];SEG8_BIT3_ON();Delay_Nus(6);SEG8_BIT3_OFF();}}}。