Keil 5 中的代码模块化封装

文章讲述了如何在Keil5环境下对89C52项目进行代码模块化封装,通过创建新的C文件和H文件,分别用于不同的功能,如DHT11和LCD1602的控制。在Core目录的Src和Inc文件夹中添加和组织文件,然后在Keil中添加这些文件,确保编译成功。在代码中定义和实现相关函数,例如LCD1602的初始化和显示函数,以及DHT11的延时函数。最后,在main函数中调用这些封装好的函数,实现项目的结构化和可维护性。

在学习89C52时,当需要编写又臭又长的代码时,会使用到代码的模块化封装,在Keil5中也可以这样进行,因为接下来是小车的项目所以代码会很长,这章作为一个简单的预备知识。

演示就在上节完成的DHT11 & LCD1602的项目中进行:

1. 想要创建新的C文件,其目录应该和main.c等一系列的所属目录一样,所以先查看main.c等c文件的目录:

按照该目录去电脑中查找:

C:\mjm_CubeMX_proj\mjm_dht11_lcd1602_proj\Core

如上图所示,在每个项目里的 Core 文件中,有 IncSrc 两个文件夹,Src 就是用来保存c文件的;Inc 就是用来保存h文件的。

2. 在 Src 文件内创建两个c文件,LCD1602.cDHT11.c

3.  在 Inc 文件内创建两个c文件,LCD1602.h DHT11.h

 

4. 在Keil中,添加这些 c文件 和 h文件 

4.1 选择刚刚添加文件的Core路径: 

 

 4.2 点击 Add Files:

上图是Core的下一级路径,所以点击上一级,然后找到Core,找到需要添加的文件:

 4.3 添加完之后:

可见,最右侧已经将两个C文件包含进来了,此时点击下方的OK,就会自动把h文件同样也包含进来。

5. 点击编译

6. 在LCD1602.c中:

6.1 include h 文件

在LCD1602.c 中必须添加“LCD1602.h”的文件,然后按需添加其他h文件

#include "LCD1602.h"
#include "DHT11.h" //要用到在DHT11.c中定义的 微秒级别延迟函数
#include "gpio.h"
#include "tim.h"
6.2 写相关代码
void write(char flag_w, char cmd) //write(1,cmd)代表写内容;write(0,cmd)代表写指令
{
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET); //RW全程置0
	
	if(flag_w == 1){
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET); //RS置1写内容
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET); //E置0
		TIM2_Delay_us(2);
		
		GPIOA->ODR = cmd; //根据时序图,E为0时开始传内容
		
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); //E置1
		HAL_Delay(5);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET); //E置0
		HAL_Delay(5);
	}
	
	if(flag_w == 0){
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET); //RS置0写指令
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET); //E置0
		TIM2_Delay_us(2);
		
		GPIOA->ODR = cmd; //根据时序图,E为0时开始传内容
		
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); //E置1
		HAL_Delay(5);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET); //E置0
		HAL_Delay(5);
	}
	
}
 

 
void Init()
{
	HAL_Delay(15);
	write(0,0x38);
	HAL_Delay(5);
	
	//detectBusy();
	write(0,0x38);
	//detectBusy();
	write(0,0x08);
	//detectBusy();
	write(0,0x01);
	//detectBusy();
	write(0,0x06);
	//detectBusy();
	write(0,0x0C);
	
}
 
void showStr(char *msg, char hang, char lie)
{
	char pos;
	
	if(hang == 0){//如果第一行
			pos = 0x80 + 0x00 + lie; 
	}else if(hang == 1){//如果第二行
			pos = 0x80 + 0x40 + lie;
	}
	//detectBusy();
	write(0,pos); //只要定下开始的位置,之后光标会自行移动
	
	while(*msg != '\0'){
		//detectBusy();
		write(1,*msg);
		msg++;
	}
		
}
6.3 再次编译,然后就可以在左侧的LCD1602.c的目录里找到LCD1602.h了:

此时,就可以在h文件中添加可能会被外部调用的函数了:

注意,和之前不同的是,还必须写一下申明:

代码格式就是:

#ifndef __XXXX_H__ // "XXXX"就是h文件的名字
#define __XXXX_H__

/////////////////////////////
//此处就是可能被外部调用的函数名
/////////////////////////////


#endif 
//必须在程序最后加上一个新行,不然会有warning

Init函数在89C52时,如果进行封装直接写 void Init( ); 就可以,但是在32的封装中必须里面加个“void”,否则会有warning

7. 在DHT11.c 中:

遵循和LCD1602.c 相同的步骤

7.1 include h 文件
#include "DHT11.h"
#include "gpio.h"
#include "tim.h"
7.2 写相关代码
char buffer;
char datas[5];
char temp[9];
char huma[9];

void TIM2_Delay_us(uint16_t n_us) //使用TIM2来做us级延时函数
{
/* 使能定时器2计数 */
	__HAL_TIM_ENABLE(&htim2);
	__HAL_TIM_SetCounter(&htim2, 0);
	while(__HAL_TIM_GetCounter(&htim2) < ((1 * n_us)-1) );
/* 关闭定时器2计数 */
	__HAL_TIM_DISABLE(&htim2);
}

void DHT_GPIO_Init(uint32_t Mode)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	__HAL_RCC_GPIOB_CLK_ENABLE();
	GPIO_InitStruct.Pin = GPIO_PIN_7;
	GPIO_InitStruct.Mode = Mode;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
 7.3 再次编译,找到并修改h文件:

 8. 在main函数中 添加h文件写代码

#include "stdio.h"
#include "LCD1602.h"
#include "DHT11.h"

extern char temp[9];
extern char huma[9];

int fputc(int a, FILE *f) //一个字符一个字符发送
{
	unsigned char temp[1] = {a};
	HAL_UART_Transmit(&huart1, temp, 1, 0xffff);
	return a;
}

int main(void)
{

  Init(); //LCD1602初始化

  while (1)
  {
		HAL_Delay(1000);
		showDataFromDHT();	
		Build_Datas();
		
		printf(temp);
		printf("\r\n");
		printf(huma);
		printf("\r\n");
		
		showStr(temp,0,4);
		showStr(huma,1,4);

  }
}

 至此,封装完成!

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值