⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 温度在串口和数码管同时显示
💻 C
字号:
/*
 * DS18B20 
*/

#include <reg52.h>
#include <intrins.h> 

typedef unsigned char uint8;
typedef unsigned int uint16;
typedef char int8;
typedef int int16;
#define nops();  {_nop_(); _nop_(); _nop_(); _nop_();} //定义空指令

uint8 word4[1] ;
uint8 k;

code uint8 number[] = {0xc0,0xf9,0xa4,0xb0,
				   	   0x99,0x92,0x82,0xf8,
				 	   0x80,0x90,0xff};


sbit DQ  = P3^2;		    //温度输入口

sbit ENLED = P1^4;
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;

uint8 i= 0;

void delay(uint16 n)
{
	while (n--);
}

void delay_ms(uint16 n)
{
	uint8 m=120;

	while (n--)
		while (m--);
}

/*
 * 18B20复位函数
*/
void DS18b20_reset(void)
{
	bit flag=1;

	while (flag)
	{
		while (flag)
	 	{
 			DQ = 1;
			delay(1);
 			DQ = 0;
 			delay(50); // 550us
 			DQ = 1; 
 			delay(6);  // 66us
 			flag = DQ;
   		}
		delay(45);    //延时500us
		flag = ~DQ;
	}
	DQ=1;
}


/*
 * 18B20写1个字节函数
 * 向1-WIRE总线上写一个字节
*/
void write_byte(uint8 val)
{
	uint8 i;

	for (i=0; i<8; i++)
	{
		DQ = 1;
		_nop_();
		DQ = 0;
		nops(); //4us
		DQ = val & 0x01;      //最低位移出
		delay(6);           //66us
		val >>= 1;          //右移一位
	}
	DQ = 1;
	delay(1);  
}

/*
 * 18B20读1个字节函数
 * 从1-WIRE总线上读取一个字节
*/
uint8 read_byte(void)
{
	uint8 i, value=0;

	for (i=0; i<8; i++)
	{
		DQ=1;
		_nop_();
		value >>= 1;
		DQ = 0;
		nops();   //4us
		DQ = 1;
		nops();   //4us 
		if (DQ)
			value|=0x80;
		delay(6);           //66us
	}
	DQ=1;

	return(value);
}

/*
 * 启动温度转换
*/
void start_temp_sensor(void)
{
	DS18b20_reset();
	write_byte(0xCC); // 发Skip ROM命令
	write_byte(0x44); // 发转换命令
}

/*
 * 读出温度
*/
int16 read_temp(void)
{
   
	uint8 temp_data[2]; // 读出温度暂放
	uint16 temp;

	DS18b20_reset();  // 复位
	write_byte(0xCC); // 发Skip ROM命令
	write_byte(0xBE); // 发读命令
	temp_data[0]=read_byte();  //温度低8位
	temp_data[1]=read_byte();  //温度高8位

	temp = temp_data[1];
	temp <<= 8;
	temp |= temp_data[0];
	 temp >>= 4;
	 
	 
	return temp;
}


/**
 * UART初始化
 * 波特率:9600
*/
void uart_init(void)
{
    TMOD |= 0x21;        // 定时器1工作在方式2(自动重装)
    SCON = 0x50;        // 10位uart,允许串行接受

    TH1 = 0xFD;
    TL1 = 0xFD;

    TR1 = 1;
}

/**
 * UART发送一字节
*/
void UART_Send_Byte(uint8 dat)
{
	SBUF = dat;
	while (TI == 0);
	TI = 0;
}

/**
 * 将数据转换成ASC码并通过UART发送出去
*/
void UART_Send_Dat(uint8 dat)
{
	UART_Send_Byte(dat/10%10 + '0');
	UART_Send_Byte(dat%10 + '0');
}



void timer1_init()
{
	TMOD  |= 0x01;
  
	TH0   = 0xFe;
	TL0   = 0x31;
	TR0   = 1;
}
void int_init()
{
	ET0 = 1;
	EA  = 1;
}


void transt(void)
 {
	 
	
	 int16 p;
	 int8 k;
	 ET0=0;
     p= read_temp();
	 ET0=1;
	 k=p;  //16为转为8为

	 word4[0]=k/10;
	 word4[1]=k%10;


  }

void refresh_led()
{
	  static uint8 j = 0;
	   	P0=0xff;
		switch(j)
	   {
	   	
		case 1: ADDR0 = 0;ADDR1 = 0;ADDR2 = 0;ADDR3 = 1;P0 = number[word4[1]];break;
		case 2: ADDR0 = 1;ADDR1 = 0;ADDR2 = 0;ADDR3 = 1;P0 = number[word4[0]];break;

			
		default: break;
		}
		
		if(2 == j++) j = 0;
		  
		
}

  

void interrupt_timer0()	interrupt 1
									
{    
	  	 TH0   = 0xFe;
	     TL0   = 0x31;
			
		  refresh_led(); 
		   
	 TF0=0;				 
}

main()
{
    uint16 ans;
   	ENLED = 0; 
	 timer1_init();
  	 int_init();
   	uart_init();
	
	while (1)
	{
		start_temp_sensor();

		delay_ms (1000); // 延时1秒	//
		ET0=0;	 //关闭0号定时中断
	  	ans=read_temp();
	 	ET0=1;	 //打开0号定时中断
			transt();
		if (ans < 0)
		{
			UART_Send_Byte('-');
			ans = -ans;
		}
	
		UART_Send_Dat(ans);
		UART_Send_Byte('\r');
		UART_Send_Byte('\n');  
		
	}

}

 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -