一、准备工作
- 基于STC15系列库的工程模板
参考:51单片机工程模板的建立(基于STC15系列库)-CSDN博客
- Keil编译器
二、程序编写
- 新建 led.c 和 led.h 文件并存放于 user/led 文件夹下;
- 新建 user.c 和 user.h 文件并存放于 user 文件夹下;
- 将 user.c 文件 led.c 文件添加进工程分组 user 组别下;
- 将 user.h 文件目录和 led.h 文件目录添加进头文件检索目录内;
- 在 main.c 文件中添加以下代码内容;
cpp
#include "user.h"
void main()
{
User_Init(); //上电初始化,在该函数内实现上电后所需要的所有初始化操作
while(1)
{
LED_OnOrOff(LED_ON); //打开LED
delay_ms(500);
LED_OnOrOff(LED_OFF); //关闭LED
delay_ms(500);
}
}
- 在 led.c 函数中添加以下代码内容;
cpp
#include "led.h"
//设置LED电路引脚
#define LED_Px GPIO_P1
#define LED_Py GPIO_Pin_0
//设置LED引脚为推挽输出模式
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Mode = GPIO_OUT_PP;
GPIO_InitStructure.Pin = LED_Py;
GPIO_Inilize(LED_Px, &GPIO_InitStructure);
}
//制作开关LED的驱动函数
void LED_OnOrOff(unsigned char LED_Sta)
{
if(LED_Sta)
{
GPIO_PIN_Set(LED_Px, LED_Py);
}
else
{
GPIO_PIN_ReSet(LED_Px, LED_Py);
}
}
//制作GPIO的初始化函数
void GPIO_Init(void)
{
LED_Init(); //对LED引脚初始化
}
- 在 led.h 文件中添加以下代码内容;
cpp
#ifndef __LED_H__
#define __LED_H__
#include "gpio.h"
//宏定义灯的开关标识符号,便于程序理解
#define LED_ON 0
#define LED_OFF 1
//声明所有在led.c文件中定义的函数
void LED_Init(void);
void LED_OnOrOff(unsigned char LED_Sta);
void GPIO_Init(void);
#endif
- 在 user.c 文件中添加以下代码内容;
cpp
#include "user.h"
void User_Init(void)
{
GPIO_Init(); //通用IO端口初始化
}
- 在 user.h 文件中添加以下代码内容;
cpp
#ifndef __USER_H__
#define __USER_H__
//文件引用
#include "config.h"
#include "led.h"
#include "delay.h"
//函数声明
void User_Init(void);
#endif
- 按正常库设计逻辑,LED驱动工程到此已经结束,用户应该可以编译运行,并下载看程序效果了,很遗憾,本程序出现了报错;因为在 led.c 文件中使用了两个官方库未定义的函数:
cpp
//制作开关LED的驱动函数
void LED_OnOrOff(unsigned char LED_Sta)
{
if(LED_Sta)
{
GPIO_PIN_Set(LED_Px, LED_Py); //官方库未定义
}
else
{
GPIO_PIN_ReSet(LED_Px, LED_Py); //官方库未定义
}
}
这两个函数的功能很简单用于对特定引脚置位或重置操作,即拉高或拉低电平信号;由于在以后的众多功能中都需要这么操作,在该官方库中我自作主张添加了以上两个函数;具体内容见步骤11、步骤12;
- 在 gpio.h 文件 u8 GPIO_Inilize(u8 GPIO, GPIO_InitTypeDef *GPIOx); 函数上方添加以下代码内容;
cpp
typedef struct
{
u8 Mode; //IO模式, GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
u8 Pin; //要设置的端口
} GPIO_InitTypeDef;
//添加置位与重置函数声明
u8 GPIO_PIN_Set(u8 GPIO, u8 GPIO_Pin_x);
u8 GPIO_PIN_ReSet(u8 GPIO, u8 GPIO_Pin_x);
u8 GPIO_Inilize(u8 GPIO, GPIO_InitTypeDef *GPIOx);
- 在 gpio.c 文件 u8 GPIO_Inilize(u8 GPIO, GPIO_InitTypeDef *GPIOx); 函数上方添加以下代码内容;
cpp
//添加置位函数定义
u8 GPIO_PIN_Set(u8 GPIO, u8 GPIO_Pin_x)
{
if(GPIO > GPIO_P5) return 1; //空操作
if(GPIO_Pin_x > GPIO_Pin_7) return 2; //空操作
if(GPIO == GPIO_P0)
{
if(GPIO_Pin_x == GPIO_Pin_0) P00 = 1;
if(GPIO_Pin_x == GPIO_Pin_1) P01 = 1;
if(GPIO_Pin_x == GPIO_Pin_2) P02 = 1;
if(GPIO_Pin_x == GPIO_Pin_3) P03 = 1;
if(GPIO_Pin_x == GPIO_Pin_4) P04 = 1;
if(GPIO_Pin_x == GPIO_Pin_5) P05 = 1;
if(GPIO_Pin_x == GPIO_Pin_6) P06 = 1;
if(GPIO_Pin_x == GPIO_Pin_7) P07 = 1;
}
else if(GPIO == GPIO_P1)
{
if(GPIO_Pin_x == GPIO_Pin_0) P10 = 1;
if(GPIO_Pin_x == GPIO_Pin_1) P11 = 1;
if(GPIO_Pin_x == GPIO_Pin_2) P12 = 1;
if(GPIO_Pin_x == GPIO_Pin_3) P13 = 1;
if(GPIO_Pin_x == GPIO_Pin_4) P14 = 1;
if(GPIO_Pin_x == GPIO_Pin_5) P15 = 1;
if(GPIO_Pin_x == GPIO_Pin_6) P16 = 1;
if(GPIO_Pin_x == GPIO_Pin_7) P17 = 1;
}
else if(GPIO == GPIO_P2)
{
if(GPIO_Pin_x == GPIO_Pin_0) P20 = 1;
if(GPIO_Pin_x == GPIO_Pin_1) P21 = 1;
if(GPIO_Pin_x == GPIO_Pin_2) P22 = 1;
if(GPIO_Pin_x == GPIO_Pin_3) P23 = 1;
if(GPIO_Pin_x == GPIO_Pin_4) P24 = 1;
if(GPIO_Pin_x == GPIO_Pin_5) P25 = 1;
if(GPIO_Pin_x == GPIO_Pin_6) P26 = 1;
if(GPIO_Pin_x == GPIO_Pin_7) P27 = 1;
}
else if(GPIO == GPIO_P3)
{
if(GPIO_Pin_x == GPIO_Pin_0) P30 = 1;
if(GPIO_Pin_x == GPIO_Pin_1) P31 = 1;
if(GPIO_Pin_x == GPIO_Pin_2) P32 = 1;
if(GPIO_Pin_x == GPIO_Pin_3) P33 = 1;
if(GPIO_Pin_x == GPIO_Pin_4) P34 = 1;
if(GPIO_Pin_x == GPIO_Pin_5) P35 = 1;
if(GPIO_Pin_x == GPIO_Pin_6) P36 = 1;
if(GPIO_Pin_x == GPIO_Pin_7) P37 = 1;
}
else if(GPIO == GPIO_P4)
{
if(GPIO_Pin_x == GPIO_Pin_0) P40 = 1;
if(GPIO_Pin_x == GPIO_Pin_1) P41 = 1;
if(GPIO_Pin_x == GPIO_Pin_2) P42 = 1;
if(GPIO_Pin_x == GPIO_Pin_3) P43 = 1;
if(GPIO_Pin_x == GPIO_Pin_4) P44 = 1;
if(GPIO_Pin_x == GPIO_Pin_5) P45 = 1;
if(GPIO_Pin_x == GPIO_Pin_6) P46 = 1;
if(GPIO_Pin_x == GPIO_Pin_7) P47 = 1;
}
else if(GPIO == GPIO_P5)
{
if(GPIO_Pin_x == GPIO_Pin_0) P50 = 1;
if(GPIO_Pin_x == GPIO_Pin_1) P51 = 1;
if(GPIO_Pin_x == GPIO_Pin_2) P52 = 1;
if(GPIO_Pin_x == GPIO_Pin_3) P53 = 1;
if(GPIO_Pin_x == GPIO_Pin_4) P54 = 1;
if(GPIO_Pin_x == GPIO_Pin_5) P55 = 1;
if(GPIO_Pin_x == GPIO_Pin_6) P56 = 1;
if(GPIO_Pin_x == GPIO_Pin_7) P57 = 1;
}
return 0;
}
//添加重置函数定义
u8 GPIO_PIN_ReSet(u8 GPIO, u8 GPIO_Pin_x)
{
if(GPIO > GPIO_P5) return 1; //空操作
if(GPIO_Pin_x > GPIO_Pin_7) return 2; //空操作
if(GPIO == GPIO_P0)
{
if(GPIO_Pin_x == GPIO_Pin_0) P00 = 0;
if(GPIO_Pin_x == GPIO_Pin_1) P01 = 0;
if(GPIO_Pin_x == GPIO_Pin_2) P02 = 0;
if(GPIO_Pin_x == GPIO_Pin_3) P03 = 0;
if(GPIO_Pin_x == GPIO_Pin_4) P04 = 0;
if(GPIO_Pin_x == GPIO_Pin_5) P05 = 0;
if(GPIO_Pin_x == GPIO_Pin_6) P06 = 0;
if(GPIO_Pin_x == GPIO_Pin_7) P07 = 0;
}
else if(GPIO == GPIO_P1)
{
if(GPIO_Pin_x == GPIO_Pin_0) P10 = 0;
if(GPIO_Pin_x == GPIO_Pin_1) P11 = 0;
if(GPIO_Pin_x == GPIO_Pin_2) P12 = 0;
if(GPIO_Pin_x == GPIO_Pin_3) P13 = 0;
if(GPIO_Pin_x == GPIO_Pin_4) P14 = 0;
if(GPIO_Pin_x == GPIO_Pin_5) P15 = 0;
if(GPIO_Pin_x == GPIO_Pin_6) P16 = 0;
if(GPIO_Pin_x == GPIO_Pin_7) P17 = 0;
}
else if(GPIO == GPIO_P2)
{
if(GPIO_Pin_x == GPIO_Pin_0) P20 = 0;
if(GPIO_Pin_x == GPIO_Pin_1) P21 = 0;
if(GPIO_Pin_x == GPIO_Pin_2) P22 = 0;
if(GPIO_Pin_x == GPIO_Pin_3) P23 = 0;
if(GPIO_Pin_x == GPIO_Pin_4) P24 = 0;
if(GPIO_Pin_x == GPIO_Pin_5) P25 = 0;
if(GPIO_Pin_x == GPIO_Pin_6) P26 = 0;
if(GPIO_Pin_x == GPIO_Pin_7) P27 = 0;
}
else if(GPIO == GPIO_P3)
{
if(GPIO_Pin_x == GPIO_Pin_0) P30 = 0;
if(GPIO_Pin_x == GPIO_Pin_1) P31 = 0;
if(GPIO_Pin_x == GPIO_Pin_2) P32 = 0;
if(GPIO_Pin_x == GPIO_Pin_3) P33 = 0;
if(GPIO_Pin_x == GPIO_Pin_4) P34 = 0;
if(GPIO_Pin_x == GPIO_Pin_5) P35 = 0;
if(GPIO_Pin_x == GPIO_Pin_6) P36 = 0;
if(GPIO_Pin_x == GPIO_Pin_7) P37 = 0;
}
else if(GPIO == GPIO_P4)
{
if(GPIO_Pin_x == GPIO_Pin_0) P40 = 0;
if(GPIO_Pin_x == GPIO_Pin_1) P41 = 0;
if(GPIO_Pin_x == GPIO_Pin_2) P42 = 0;
if(GPIO_Pin_x == GPIO_Pin_3) P43 = 0;
if(GPIO_Pin_x == GPIO_Pin_4) P44 = 0;
if(GPIO_Pin_x == GPIO_Pin_5) P45 = 0;
if(GPIO_Pin_x == GPIO_Pin_6) P46 = 0;
if(GPIO_Pin_x == GPIO_Pin_7) P47 = 0;
}
else if(GPIO == GPIO_P5)
{
if(GPIO_Pin_x == GPIO_Pin_0) P50 = 0;
if(GPIO_Pin_x == GPIO_Pin_1) P51 = 0;
if(GPIO_Pin_x == GPIO_Pin_2) P52 = 0;
if(GPIO_Pin_x == GPIO_Pin_3) P53 = 0;
if(GPIO_Pin_x == GPIO_Pin_4) P54 = 0;
if(GPIO_Pin_x == GPIO_Pin_5) P55 = 0;
if(GPIO_Pin_x == GPIO_Pin_6) P56 = 0;
if(GPIO_Pin_x == GPIO_Pin_7) P57 = 0;
}
return 0;
}
-
保存所有文件并编译即可完成LED驱动例程;
三、总结
使用STC15系列库在小工程上的复杂程度提升了很多倍,这会使的很多同学放弃使用库函数来学习,这是无法避免的;但我们不能忽视使用库所带来的优势,程序的可读性大大加强,程序的统一操作使程序在相互之间的流通性大大提升,也许你们还没有意识到库的优势,但还是希望你们保持一颗热情的心继续深入学习一下,也许很快你就能体会到库的魅力;