keil分文件

DHT11,将冗长的代码分为移植性和可读性高的代码模块

1.添加新的文件

2. 选择C语言,并命名为uart.c

3. 重复1,2步,分别创建uart.cLCD1602.cdht11.c, delay.c(文件名不区分大小写,不能有同名文件) 

 4. 将原来冗长的代码,通过这四个分类分别把对应的代码移动到相应的C文件下

uart.c

#include "reg52.h"

sfr AUXR = 0x8E;

void UartInit()		//9600bps@11.0592MHz
{
	AUXR = 0x01;
	SCON = 0x40;  //配置串口工作方式1,REN不使能接收
	
	//配置定时器1,工作方式为8位自动重载
	TMOD &= 0x0f;//
	TMOD |= 0x20;
	
	TH1 = 0xFD; 
	TL1 = 0xFD; //9600波特率的初值
	
	TR1 = 1;//启动定时器
	
	
}

void Send_byte(char data_msg)
{
	SBUF = data_msg;
	while(!TI);//在请求中断时,TI= 1,既!TI=0,等待数据的发送完成;响应中断结束后TI = 0,既!TI = 1,将TI清零
	TI = 0;

}

void Send_string(char* str)
{
	while(*str != '\0')
	{
		Send_byte(*str);
		str++;
	}
}

 LCD1602.c

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

#define databuffer P0 //定义8位数据线,Po端口组
sbit RS   = P1^0;
sbit RW   = P1^1;
sbit EN   = P1^4;

void Check_Busy()//(4)以后每次写指令,读/写数据操作均需要检测忙信号
{
	char temp = 0x80;
	databuffer = 0x80;//先将databuffer置为忙
	while(temp &= 0x80 ){//1000 0000//BF(D7)位为高电平,代表忙
	//然后如果temp不变化的话,就一直检查是否busy
	RS = 0;
	RW = 1;
	EN = 0;
	
	_nop_();
	
	EN = 1;
	temp = databuffer;//根据时序图,E为1时开始读
	_nop_();
	_nop_();
	EN = 0;
	_nop_();
	}
}
 
 
 
void Write_cmd_Func(char cmd)//写入指令的函数
{
	Check_Busy();//(4)以后每次写指令,读/写数据操作均需要检测忙信号
	RS = 0;//写指令
	RW = 0;
	
	EN = 0;
	_nop_();
	databuffer = cmd;
	EN = 1;
	_nop_();
	_nop_();
	EN = 0;
}
 
void Write_data_Func(char dataShow)//写入数据的函数
{
	Check_Busy();//(4)以后每次写指令,读/写数据操作均需要检测忙信号
	RS = 1;//写内容
	RW = 0;
	
	EN = 0;
	_nop_();
	databuffer = dataShow;
	_nop_();
	EN = 1;
	_nop_();
	_nop_();
	EN = 0;
}



void LCD1602_Init()
{
	//(1)延时 15ms
	Delay15ms();
	//(2)写指令 38H(不检测忙信号)
	Write_cmd_Func(0x38);
	//(3)延时 5ms
	Delay5ms();
	//(4)以后每次写指令,读/写数据操作均需要检测忙信号
	
	//(5)写指令 38H:显示模式设置
	Write_cmd_Func(0x38);
	//(6)写指令 08H:显示关闭
	Write_cmd_Func(0x08);
	//(7)写指令 01H:显示清屏
	Write_cmd_Func(0x01);
	//(8)写指令 06H:显示光标移动设置
	Write_cmd_Func(0x06);
	//(9)写指令 0CH:显示开及光标设置
	Write_cmd_Func(0x0C);
	
}


void LCD1602_ShowLine(char row,char col,char *string)
{
	switch(row){
		case 1:
			Write_cmd_Func(0x80+col);//只要定下开始的位置,之后光标会自行移动
			while(*string){
				Write_data_Func(*string);
				string++;
			}
			break;
		
		
		case 2:
			Write_cmd_Func(0x80+0x40+col);//只要定下开始的位置,之后光标会自行移动
			while(*string){
				Write_data_Func(*string);
				string++;
			}
			break;	
		}
	/*
		char pos;
	
	if(hang == 0){//如果第一行
			pos = 0x80 + 0x00 + lie; 
		}else if(hang == 1){//如果第二行
			pos = 0x80 + 0x40 + lie;
		}
		Check_Busy();
		Write_data_Func(*string);
	
	while(*string != '\0'){
		Check_Busy();
		Write_data_Func(*string);
		string++;
	}
		*/
}

dht11.c

#include "reg52.h"
#include "delay.h"

sbit dht  = P3^3;

char datas[5];
char temperature[8];
char humidity[8];


void Build_datas()
{
	humidity[0] = 'H';
	humidity[1] = datas[0]/10 + 0x30;
	humidity[2] = datas[0]%10 + 0x30;
	humidity[3] = '.';
	humidity[4] = datas[1]/10 + 0x30;
	humidity[5] = datas[1]%10 + 0x30;
	humidity[6] = '%';
	humidity[7] = '\0';
	
	temperature[0] = 'T';
	temperature[1] = datas[2]/10 + 0x30;
	temperature[2] = datas[2]%10 + 0x30;
	temperature[3] = '.';
	temperature[4] = datas[3]/10 + 0x30;
	temperature[5] = datas[3]%10 + 0x30;
	temperature[6] = 'C';
	temperature[7] = '\0';

}


void Start_DHT()
{

	dht = 1;
	dht = 0;
	
	Delay30ms();
	
	dht =  1;
	while(dht == 1);//不断读取直到DHT再次变低,跳出循环,说明模块响应
	while(dht == 0);//不断读取直到DHT再次拉高,80us之后,再经过50us后DHT变成低电平,就代表要开始变高并开始传输数据了
	while(dht == 1);//等待数据传输,不断读取直到DHT再次变低,如退出循环说明数据传输前的50us低电平开始了
    
	
}

void Read_data_From_DHT()
{
	int i;//轮
	int j;//每一轮读多少次
	char temp;
	char flag;
	Start_DHT();
	
	for(i = 0;i < 5;  i++)
	{//5组数据
		for(j =0;j<8;j++)
		{//每组数据8位
			while(!dht);//等待上拉  dht = 1 退出循环
			Delay40us();//高电平持续26-28us是‘0’,高电平持续70us是'1',所以delay40us之后观察还是否是高电平
			if(dht == 1)
			{
				flag = 1;
				while(dht);//不断读取下拉的一瞬间,因为在开始传输数据之前要延迟80us,如果提前结束,下一次开始传输数据就会出错,因为“开始传输数据”是从判断上拉开始的

			}
			else
			{
				flag = 0;
			}
			temp =  temp << 1;//temp左移一位,例如temp= 10101011  左移之后变成-》01010110(第一个数移出去,最后一位补零)
			temp |= flag;//假如flag=1,temp=01010111
		}
		datas[i] = temp;
	}
	
}

delay.c

#include <intrins.h> 

void Delay15ms()		//@11.0592MHz
{
	unsigned char i, j;
 
	i = 27;
	j = 226;
	do
	{
		while (--j);
	} while (--i);
}
 
void Delay5ms()		//@11.0592MHz
{
	unsigned char i, j;
 
	i = 9;
	j = 244;
	do
	{
		while (--j);
	} while (--i);
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void Delay30ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 54;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}



void Delay40us()		//@11.0592MHz
{
	unsigned char i;

	_nop_();
	i = 15;
	while (--i);
}

5. 光是分文件不行,其他文件要调用文件,例如main.c文件要调用delay.c文件, 因此需要创建delay.h的头文件: (头文件也不分大小写)

 6. 在h文件中,删除函数的实现体,只保留需要在其他C文件调用的函数的声明(在文件内调用的函数可以不声明)

delay.h

void Delay15ms();		//@11.0592MHz
void Delay5ms();		//@11.0592MHz
void Delay1000ms();		//@11.0592MHz
void Delay30ms();		//@11.0592MHz
void Delay40us();		//@11.0592MHz

 7.同理

dht11.h

void Build_datas();
void Read_data_From_DHT();

 lcd1602.h

void LCD1602_Init();


void LCD1602_ShowLine(char row,char col,char *string);

 uart.h

void UartInit();		//9600bps@11.0592MHz
void Send_byte(char data_msg);
void Send_string(char* str);

8. 由于“humidity”和“temperature”变量是在dht11中被定义,但是在main函数中被使用,但现在dht11变成了单独的C文件,所以为了让main的C文件也认识这两个变量,需要将他们在main的C文件中也定义一下,并加上“extern”前缀!

具体的extern解释可查看一文彻底搞懂extern用法

main.c

#include "reg52.h"
#include <intrins.h> 
#include <string.h>
#include "delay.h"
#include "uart.h"
#include "lcd1602.h"
#include "dht11.h"

sbit led1 = P3^7;//根据原理图(电路图),设备变量led1指向P3组IO口的第7口


extern char temperature[8];
extern char humidity[8];



void main()
{
	Delay1000ms();//传感器上电后,要等待 1s 以越过不稳定状态在此期间无需发送任何指令
	
	UartInit();
	 
	LCD1602_Init(); 
	Delay1000ms();
	Delay1000ms();
	led1 = 0;
	while(1)
	{
		Delay1000ms();
		Read_data_From_DHT();
	
		Build_datas();
		
		Send_string(humidity);
		Send_string("\r\n");
		Send_string(temperature);
		Send_string("\r\n");
		LCD1602_ShowLine(1,2,humidity);
		LCD1602_ShowLine(2,2,temperature);
	}
}

结果一样 

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值