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

📄 main.c

📁 51单片机项目集
💻 C
字号:
/********该程序主要是利用DS18B20采集温度,然后通过数码管显示温度*************/
/*当程序收到上位机发送的命令之后,该程序会将当时的温度值通过串口发送给上位机*/
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ = P1^0;		//定义DS18B20的信号线端口
uchar i,j;
uchar dis_buffer[4];//定义数据缓冲数组
uchar bit_ser[]={0xfe,0xfd,0xfb,0xf7}; //定义数码管片选数组
uchar seven_seg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
									   //定义数码管段选数组
/****************************延时函数*********************************/
void delay(uint x)
{
	while(x)   
	x--;
}
/*************************DS18B20初始化函数***************************/
void Init_DS18B20(void)
{
	unsigned char x=0;
	DQ = 1;         //DQ复位
	delay(8);       //稍做延时
	DQ = 0;    	    //单片机将DQ拉低
	delay(80);   	//精确延时 大于 480us
	DQ = 1;      	//拉高总线
	delay(14);
	x=DQ;      	    //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
	delay(20);
}
/***************************从18B20中读一个字节************************/
uchar ReadOneChar(void)
{
	uchar i=0;
	uchar dat = 0;
	for (i=8;i>0;i--)
 	{
  		DQ = 0; 	// 给脉冲信号
  		dat>>=1;
  		DQ = 1; 	// 给脉冲信号
  		if(DQ)
   		dat|=0x80;  
  		delay(8);
 	}
 	return(dat);
}
/***************************向18B20中写一个字节************************/
Write_OneChar(uchar dat)
{
	uchar i=0;
	for (i=8; i>0; i--)
	{
		DQ = 0;	  //给脉冲信号
		DQ = dat & 0x01;
		delay(5); 
		DQ = 1;	  //给脉冲信号
		dat >>= 1;
	}
	delay(4);
}
/**************************从18B20中读取一个字节***********************/
int Read_Temperature(void)
{
	uchar i = 0,t = 0,a,b;
	int temp;
	Init_DS18B20();
	Write_OneChar(0xcc); 	// 跳过读序号列号的操作
	Write_OneChar(0x44); 	// 启动温度转换
	Init_DS18B20();
	Write_OneChar(0xcc); 	//跳过读序号列号的操作
	Write_OneChar(0xbe); 	//读取温度寄存器等(共可读9个寄存器) 前两个就是温度
	i = ReadOneChar();   	//读取温度值低位
	t = ReadOneChar();   	//读取温度值高位
	a = i & 0x0f;
	b = t;
	i = i >> 4;             //低位右移4位,舍弃小数部分
	t = t << 4;             //高位左移4位,舍弃符号位
	t = t | i;
	temp = (t + a * 0.0625) * 100; //得到一个比实际温度扩到100倍的值,主要是为了更好的显示和传输          
	return(temp);			//返回温度值
}

/***************************初始化定时器0******************************/
void timer0_init(void)			 //
{
	TMOD = 0x21; //由于串口通信需要使用定时器1,因此TMOD的值是0x21
	TL0 = (65536-5000) % 256;
	TH0 = (65536-5000) / 256;
	EA = 1;
	ET0 = 1;
	TR0 = 1;
}
/*************************发送数据的函数********************************/
void txd_data(char send_data)	
{
	SBUF = send_data; //将需要发送的数据放入发送缓冲区
	while(!TI);		  //等待发送数据
	TI = 0;
}
/********************T0中断处理函数,主要用于显示当前温度***************/
void timer0_isr(void) interrupt 1
{
	int temp; 
	TR0 = 0;
	TL0 = (65536-5000) % 256;
	TH0 = (65536-5000) / 256;
	TR0 = 1;
	switch(i)
	{
		case 0:
			P2 = bit_ser[0];
			P0 = seven_seg[dis_buffer[0]];				
			break;
		case 1:
			P2 = bit_ser[1];
			P0 =seven_seg[dis_buffer[1]] & 0x7f;
			break;
		case 2:
			P2 = bit_ser[2];
			P0 =seven_seg[dis_buffer[2]];
			break;
		case 3:
			P2 = bit_ser[3];
			P0 =seven_seg[dis_buffer[3]];
			break;
	} 
	i++;
	if(i >= 4) 
	{
		i = 0;
		j++;
		if(j >= 10)	//如果到200ms就会读取一次温度,并将温度值放入显示缓冲区
		{
			j = 0;
			temp = Read_Temperature();
			dis_buffer[0] = temp / 1000;
		   	dis_buffer[1] = temp % 1000 / 100;
			dis_buffer[2] = temp % 100 / 10;
			dis_buffer[3] = temp % 10;
		}
	}
}

/***************************串口通信初始化函数***************************/
void uart_init(void)
{ 
	SCON = 0x50;         //方式1,充许接收
	TMOD = 0x21;         //T1方式2定时,T0方式是1          
	TH1 = 0xFd;          //波特率9600,Fosc=11.0592MHz
	TL1 = 0xFd;
	TR1 = 1;
	ES = 1;           	 // 打开串口中断
}
/**************************串口中断处理函数*****************************/
void uart() interrupt 4			  
{
	char y,i;
	while(!RI);
	y = SBUF;			 //读取接收的信息,然后判断是否为发送温度命令
	if(y == '0')		 //如果为发送命令,就将当前数据缓冲数组内的数据发送给上位机
	{
		for(i = 0;i <= 3;i++)
		{
			txd_data(dis_buffer[i] + 48);
		}
	}
	RI = 0;		
}
/*******************************主函数*********************************/
void main()
{
	timer0_init();		//调用T0初始化函数
	uart_init();		//调用串口初始化函数
	while(1)
	{}
}

⌨️ 快捷键说明

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