【51单片机实验笔记】前篇(三) 模块功能封装汇总(持续更新)

文章目录

  • 通用函数
    • public.h
    • public.c
  • 延时函数
    • delay.h
    • delay.c
  • LED模块
  • 数码管模块
    • smg.h
    • smg.c
  • LED点阵模块
  • 独立按键模块
  • 矩阵按键模块
  • 外部中断模块
  • 定时器模块
  • 串口通讯模块
  • ADC模块
  • PWM模块


通用函数

包含常用头文件宏定义自定义类型函数工具等。

public.h

#ifndef _PUBLIC_H_
#define _PUBLIC_H_

/*---------------------常用头文件---------------------------------*/
#include 
#include 

#include 
#include 
#include 


#define false 0
#define true 1

typedef unsigned char u8;
typedef unsigned int u16;

void delay_10us(u16);
void delay_ms(u16);

u8 * int2String(int, bit);
u8 * float2String(float, u8);

#endif

public.c

#include "public.h"
/** 
 **  @brief    通用函数
 **  @author   QIU
 **  @data     2023.09.03
 **/

/*-------------------------------------------------------------------*/

/**
 **  @brief   延时函数(10us)
 **  @param   t:0~65535,循环一次约10us
 **  @retval  无
 **/
void delay_10us(u16 t){
	while(t--);
}


/**
 **  @brief   延时函数(ms)
 **  @param   t:0~65535,单位ms
 **  @retval  无
 **/
void delay_ms(u16 t){
	while(t--){
		delay_10us(100);
	}
}


/**
 **  @brief   整数转字符串
 **  @param   num:接受整型值
 **  @param   sign:是否带符号
 **  @retval  返回字符串指针
 **/
u8 * int2String(int num, bit sign){
	static u8 str[8];
	
	// 是否带符号
	if(sign){
		sprintf(str, "%d", num);
	}else{
		sprintf(str, "%u", num);
	}
	// 返回指针
	return str;
}


/**
 **  @brief   浮点数转字符串
 **  @param   num:接受浮点数
 **  @param   len:指定精度,小数点位数0~6(四舍五入)
 **  @retval  返回字符串指针
 **/
u8 * float2String(float num, u8 len){
	static u8 str[10];
	
	// 筛选
	switch(len){
		case 0: sprintf(str, "%.0f", num); break;
		case 1: sprintf(str, "%.1f", num); break;
		case 2: sprintf(str, "%.2f", num); break;
		case 3: sprintf(str, "%.3f", num); break;
		case 4: sprintf(str, "%.4f", num); break;
		case 5: sprintf(str, "%.5f", num); break;
		default: sprintf(str, "%f", num); break;  // 默认6位小数
	}
	// 返回指针
	return str;
}

延时函数

包含常用延时函数通用函数兼容延时函数

delay.h

#ifndef _DELAY_H_
#define _DELAY_H_

#include 

#define false 0
#define true 1

typedef unsigned char u8;
typedef unsigned int u16;

void delay_10us(u16);
void delay_ms(u16);

#endif

delay.c

#include "delay.h"
/** 
 **  @brief    通用函数
 **  @author   QIU
 **  @data     2023.08.23
 **/

/*-------------------------------------------------------------------*/

/**
 **  @brief   延时函数(10us)
 **  @param   t:0~65535,循环一次约10us
 **  @retval  无
 **/
void delay_10us(u16 t){
	while(t--);
}


/**
 **  @brief   延时函数(ms)
 **  @param   t:0~65535,单位ms
 **  @retval  无
 **/
void delay_ms(u16 t){
	while(t--){
		delay_10us(100);
	}
}

LED模块


数码管模块

主要实现了延时法刷新定时器法刷新两种方式。提供字符串写入函数

smg.h

#ifndef _SMG_H_
#define _SMG_H_

#include "public.h"

#define SMG_PORT P0 
 
// 位选引脚,与38译码器相连
sbit A1 = P2^2;
sbit A2 = P2^3;
sbit A3 = P2^4;

void smg_showString(u8*, u8);

void smg_showString_Bytimer(u8*, u8);

#endif

smg.c

#include "smg.h"
/** 
 **  @brief    数码管封装
 **  		   1. 延时刷新
 **  		   2. 定时器刷新
 **  @author   QIU
 **  @date     2023.09.03
 **/


/*-------------------------------------------------------------------*/

//共阴极数码管字形码编码
u8 code smgduan[] = {0x3f,0x06,0x5b,0x4f,0x66, //0 1 2 3 4
					 0x6d,0x7d,0x07,0x7f,0x6f, //5 6 7 8 9
					 0x77,0x7c,0x58,0x5e,0x79, //A b c d E
					 0x71,0x76,0x30,0x0e,0x38, //F H I J L
					 0x54,0x3f,0x73,0x67,0x50, //n o p q r
					 0x6d,0x3e,0x3e,0x6e,0x40};//s U v y -  


/**
 **  @brief   指定第几个数码管点亮,38译码器控制位选(不对外声明)
 **  @param   pos:从左至右,数码管位置 1~8
 **  @retval  无
 **/
void select_38(u8 pos){
	u8 temp_pos = 8 - pos; // 0~7
	A1 = temp_pos % 2; //高位
	temp_pos /= 2;
	A2 = temp_pos % 2; 
	temp_pos /= 2;
	A3 = temp_pos % 2; //低位
}


/**
 **  @brief   解析数据并取得相应数码管字形码编码
 **  @param   dat:想要显示的字符
 **  @retval  对应字形码编码值
 **/
u8 parse_data(u8 dat){
	switch(dat){
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':return smgduan[dat-'0'];
		case 'a':
		case 'A':return smgduan[10];
		case 'b':
		case 'B':return smgduan[11];
		case 'c':
		case 'C':return smgduan[12];
		case 'd':
		case 'D':return smgduan[13];
		case 'e':
		case 'E':return smgduan[14];
		case 'f':
		case 'F':return smgduan[15];
		case 'h':
		case 'H':return smgduan[16];
		case 'i':
		case 'I':return smgduan[17];
		case 'j':
		case 'J':return smgduan[18];
		case 'l':
		case 'L':return smgduan[19];
		case 'n':
		case 'N':return smgduan[20];
		case 'o':
		case 'O':return smgduan[21];
		case 'p':
		case 'P':return smgduan[22];
		case 'q':
		case 'Q':return smgduan[23];
		case 'r':
		case 'R':return smgduan[24];
		case 's':
		case 'S':return smgduan[25];
		case 'u':
		case 'U':return smgduan[26];
		case 'v':
		case 'V':return smgduan[27];
		case 'y':
		case 'Y':return smgduan[28];
		case '-':return smgduan[29];
		default:return 0x00; //不显示
	}
}



/**
 **  @brief   根据输入的ASCII码,显示对应字符(1字节)
 **  @param   dat:字符数据,或其ASCII值
 **  @param   pos:显示位置 1~8
 **  @retval  无
 **/
void smg_showChar(u8 dat, u8 pos, bit flag){
	// 解析点亮哪一个数码管
	select_38(pos);
	// 解析数据
	SMG_PORT = parse_data(dat);
	// 加标点
	if(flag) SMG_PORT |= 0x80;
}





/*-------------------------------------------------------------------*/
/*-----------------------延时法刷新----------------------------------*/
/*-------------------------------------------------------------------*/


/**
 **  @brief   延时法刷新
 **  @param   dat:字符数组,需以'\0'结尾
 **  @param   pos:显示位置
 **  @param   dot:小数点位置
 **  @retval  无
 **/
void smg_flush_Bydelay(u8 dat[], u8 pos, u8 dot){
	u8 i;
	// 超出部分直接截断
	for(i=0;(i<9-pos)&&(dat[i]!='\0');i++){
		// 如果是小数点,跳过,往前移一位
		if(dat[i] == '.'){
			pos -= 1;
			continue;
		}
		// 显示
		smg_showChar(dat[i], pos+i, (dot == i+1)?true:false);
        // 延时1ms
		delay_ms(1);
		// 消影
		SMG_PORT = 0x00; 
	}
}





/**
 **  @brief   显示字符串(动态显示)
 **  @param   dat:字符数组,需以'\0'结尾
 **  @param   pos:显示位置
 **  @retval  无
 **/
void smg_showString(u8 dat[], u8 pos){
	u8 i = 0, dot = 0;
	// 先判断是否存在小数点
	while(dat[i]!='\0'){
		if(dat[i] == '.') break;
		i++;
	}
	// 记录下标点位置
	if(i < strlen(dat)) dot = i;
	// 延时法刷新
	smg_flush_Bydelay(dat, pos, dot);
}




/*-------------------------------------------------------------------*/
/*--------------------------定时器法刷新-----------------------------*/
/*-------------------------------------------------------------------*/

/**
 **  @brief   数码管显示字符串(定时器法刷新)
 **  @param   dat:字符数组,需以'\0'结尾
 **  @param   pos:显示位置
 **  @retval  返回值
 **/
void smg_showString_Bytimer(u8 dat[], u8 pos){
	// 数码管计数器, 小数点位置
	static u8 smg_counter = 0, dot_counter = 0, dot_port[8];
	// 暂存当前位置
	u8 temp;
	
	// 先消影
	SMG_PORT = 0x00; 
	
	// 如果是小数点,跳出。
	if(dat[smg_counter] == '.'){
		// 记录小数点位置,下一轮刷新
		dot_port[smg_counter-1] = true;
		// 计数器后移一位
		smg_counter++;
		// 小数点计数器自增
		dot_counter++;
		return;
	}
	// 计算当前位置
	temp = pos+smg_counter-dot_counter;
	// 判断是否加小数点(检测到小数点的后面几位整体前移)
	smg_showChar(dat[smg_counter], temp, dot_port[smg_counter]);
	
	// 如果是结束符,跳出(超出部分截断)
	if(temp == 8 | dat[smg_counter] == '\0'){
		// 重置
		smg_counter = 0;
		// 根据标志决定是否清除小数点
		if(dot_counter){
			// 清零
			dot_counter = 0;
		}else{
			// 清空
			strcpy(dot_port, "");
		}
		return;
	}else{
		smg_counter++;
	}
}

LED点阵模块


独立按键模块


矩阵按键模块


外部中断模块


定时器模块


串口通讯模块


ADC模块


PWM模块


你可能感兴趣的:(51单片机,51单片机,笔记,嵌入式硬件)