本帖最后由 刘洋讲单片机 于 2017-1-11 15:33 编辑
第10讲.点亮第一个发光二极管.zip
(438.59 KB)
第10讲 点亮第一个发光二极管-上
第10讲 点亮第一个发光二极管-中
第10讲 点亮第一个发光二极管-下
众拳【剑齿虎STM8】开发板学习笔记分享
点击此处查看全部资料
第10讲 点亮第一个发光二极管
目 录
10.1概述 2
10.2 应用领域 3
10.3 剑齿虎开发板内自定义LED灯控制 4
10.3.1 配置寄存器实现LED控制 5
10.3.2 使用库函数方法实现LED控制 6
10.3.3 库函数编程的优势 6
10.4 工程模版的建立 7
10.5 程序文件设计 8
10.5.1 lib文件中内容分析 9
10.5.2 main.c文件中的程序 10
10.5.3 led.c文件中的程序 11
10.5.4 led.h文件中的程序 12
10.1概述
发光二极管简称为LED。由含镓(Ga)、砷(As)、磷(P)、氮(N)等的化合物制成。当电子与空穴复合时能辐射出可见光,因而可以用来制成发光二极管。在电路及仪器中作为指示灯,或者组成文字或数字显示。砷化镓二极管发红光,磷化镓二极管发绿光,碳化硅二极管发黄光,氮化镓二极管发蓝光。因化学性质又分有机发光二极管OLED和四轴飞行器发光二极管LED。
10.2 应用领域
目前,LED 全彩显示屏主要应用于广告传媒、体育场馆、舞台背景、市政工程等。
1.广告传媒
LED 全彩显示屏是上世纪90 年代在全球迅速发展起来的新型信息显示媒体,它显示面积大,视觉效果震撼,能充分吸引受众的眼球,是媒体与高科技的全新结合。而且,LED全彩显示屏并不是单纯户外媒体,它同时兼具电视等媒体的特性和优势,还拥有更大的创意空间和更广阔的与消费者沟通的立体空间,可满足个性化需求,具有数字时代的传播概念。
除了其独特的表现形式外,LED全彩显示屏在户外广告传媒领域得到的迅速发展还得益于户外传媒受众的特点、网络化的媒体运营以及广告的成本等因素。首先,户外媒体影响的是城市的主流人群,传统媒体的受众对相大众化和老龄化,受众人群的差别和优势助推了户外LED 广告显示屏市场的发展。其次,户外LED 广告显示屏实现了网络化的媒体运营,易于实现品牌广告的集中投放。第三,户外LED广告显示屏新媒体相对于传统媒体的广告投放成本低,且具有有效到达率高的特性,吸引了更多的广告投资。
2.体育场馆
过去,LED 显示屏主要是以单色和红绿双色为主,在体育场馆中的作用仅限于显示比分和运动员姓名、名次等信息。随着LED 全彩显示屏技术的成熟,现已能够满足体育场馆观看距离远、环境亮度高等特殊要求,确保观众获得清晰、鲜明的彩色图像,并可提供比赛经典镜头回放、实时转播、背景画面、广告传媒等多种功能。近几年世界杯、奥运会、亚运会等一系列赛事的成功举办,掀起了体育场馆LED 全彩显示屏应用的热潮,高标准现代化的体育场馆中LED 全彩显示屏已经成为必备设施,体育场馆对显示屏的需求迅速增加。
3.舞台背景
随着LED 全彩显示技术以及大屏拼接技术的日益完善,LED 全彩显示屏产品日趋成熟,被大量应用在舞台背景显示和现场直播显示方面,成为大型会演场所必备的布景和色彩效果工具。LED 全彩显示屏通过大屏幕的不断变换,可以深入表现舞台演出每个节目的主题和风格,是舞美设计中必不可少的工具。同时,其亮度和点距性能的提升,使得LED 屏幕在室内外场所的应用都获得了重大突破。另外,部分LED 显示屏可以弯曲的特性令产品的部署、特效的实现和特殊的应用成为了可能。近几年奥运会、世博会、央视春节联欢晚会等大型演出活动对LED 全彩显示屏的广泛采用,带动了舞台背景市场对LED 全彩显示屏的需求。
4.市政工程
近年来,在城市主干道、金融商业中心、大型广场、地铁等极具发展活力的城市黄金地带以及重要市政场所,LED 显示屏被市政部门越来越多地用于政务公开和公共宣传的视频播放,既提升了政府形象又塑造了城市品牌。目前,我国许多省市在市政公共信息显示和展示工程方面大力推进LED 全彩显示屏的使用,为相关生产厂家开辟了新的市场。
10.3 剑齿虎开发板内自定义LED灯控制
从“图10.1 剑齿虎开发板自定义LED灯控制管脚原理图”中可以看出管脚PE0控制LED1;PA3控制LED2;PA6控制LED3。在这个实验中我们只控制一个LED发光二极管发光。我们选择控制LED1,让它按照我们的程序设计思路发光或熄灭。
图10.1 剑齿虎开发板自定义LED灯控制管脚原理图
从原理图中可以看出,当管脚PE0输出低电平时,发光二极管发光;当管脚PE0输出高电平时,发光二极管熄灭。
10.3.1 配置寄存器实现LED控制
从生活常识我们能知道,想要控制灯发光就必须有电源送过来控制它,从单片机的角度讲,想要控制LED1发光,必须让CPU管脚输出高低电平。从上一节表9.6中可以查出。通过配置GPIO寄存器相应的位,可以实现相应管脚的输入输出功能。
PE_DDR|=0x00;//PE0配置为输出模式
PE_CR1&=0xFE;//PE0配置为开漏输出
PE_CR2&=0xFE;//PE0输出2M
PE_ODR|=0x01;//高电平输出
PE_ODR&=0xFE;//低电平输出
通过控制相关寄存器对应位就可以控制LED1的发光和熄灭,这种方法我们称之为寄存器控制。
10.3.2 使用库函数方法实现LED控制
我们还可以采用库函数的方法实现LED1的控制。在电路设计中我们固定使用PE0控制LED1,所有的库函数配置要围绕这个硬件条件展开。库函数参数部分一般顺序都是“端口-管脚-具体功能”。
GPIO_Init(GPIOE, GPIO_PIN_0, GPIO_MODE_OUT_OD_HIZ_SLOW );//初始化
注释:在这条程序语句中,括号内的内容是功能配置,现在逐项说明:“GPIOE”是PE端口;“GPIO_PIN_0”是前面规定端口的第1个管脚;“ GPIO_MODE_OUT_OD_HIZ_SLOW ”慢速开漏输出高阻态。
GPIO_WriteLow(GPIOE,GPIO_PIN_0);//PE0输出低电平
注释:在这条程序语句中,括号内的内容是功能配置,现在逐项说明:“GPIOE”是PE端口;“GPIO_PIN_0”是前面规定端口的第1个管脚。
GPIO_WriteHigh(GPIOE,GPIO_PIN_0);//PE0输出高电平
有人会问,我怎么知道这些程序代码的编写规则及功能书写格式呢?具体的都要查找《STM8库函数参考手册》,在这份文档中有非常详细的说明及书写格式,很多我们直接拿过来套用就可以。
10.3.3 库函数编程的优势
STM8库函数里把所有寄存器用结构体一一对应并且封装起来,而且提供了基本的配置函数。我们要去操作配置某个外设的时候不需要再去翻眼花缭乱的数据手册,直接找到库函数描述拿来就可以用,这样就能把精力放在逻辑代码的开发上,而不是去费力的研究一个芯片的外设要怎么配置寄存器才能驱动起来。
简单讲,库函数是为了让开发者从大量繁琐的寄存器操作中脱离出来的一个文件包。
10.4 工程模版的建立
使用IAR软件进行程序设计,要先建立一个工程,由于C语言程序设计的灵活性,使得每个人对于程序设计的工程文件有不同的分配,有人习惯于把主要工作都放在主程序呢,有人习惯把所有的程序都放在主程序中。根据这么多年的设计经验我们有着自己的一套程序设计思路,通过整理后认为这样规范合理,分类清楚,阅读方便。
图10.2 工程设计文件目录
在一个新的工程中我们建立了4个文件夹,分别是BSP\LIB\USR\Readme。BSP文件夹中存放自定义底层驱动程序文件;LIB文件夹中引入C语言自己的库函数文件;USR文件夹中存放自定义主程序及数据库头文件等;Readme文件夹中存放自定义程序设计说明文件。
在编译后IAR软件会自动生成一个Output文件夹。
以这个实验为例,目录树展开后如“图10.3 工程目录树展开内容3”。
图10.3 工程目录树展开内容
10.5 程序文件设计
前文我们已经详细介绍了工程模版的建立,我们按照前文建立工程文件。按照我们的编程习惯,我们自己定义了main.c、pbdata.c和pbdata.h三个函数文件,全部放置在“USR”文件夹中。pbdata.c和pbdata.h函数文件主要存放我们自定义的公共函数和全局变量,以方便以后每个功能模块之间传递参数。
在这里我们自定义了BSP文件夹,在我们的设计规划中,把所有的底层驱动函数全部放在这个文件中,使程序的可读性很好。在本课节中把LED1发光的执行过程子函数放在这个文件中。
下面详细说明此驱动函数书写规范。
10.5.1 lib文件中内容分析
我们建立一个“Lib”文件夹,把引用系统本身定义好的库函数加在其中,我们使用到哪个外设功能,直接引用到此文件夹中即可。一般情况下下面这三个文件都得引用。
Stm8s_gpio.c // 定义GPIO函数
Stm8s_clk.c // 定义时钟函数
Stm8s_conf.h // 外设声明函数(头文件)
图10.4 stm8s_conf.h头文件内部选择
本节实验及以后的实验我们都是用到库文件,其中 stm8s_conf.h头文件包含了所有外设的声明头文件,在本试验中我们使用到时钟外设和GPIO端口外设。所以#include "stm8s_clk.h"和#include "stm8s_gpio.h"需要“打开”(就是把语句前面的双斜线注释符号删除即可,参考图10.4)。Stm8s_gpio.c库函数包含了所有管脚初始化功能和具体的执行操作;Stm8s_clk.c库函数主要包含了内部时钟和外部时钟设置,在主函数中规定了具体的执行方法,在这个函数中就有具体相关的执行步骤。
10.5.2 main.c文件中的程序
主程序就实现初始化和调用驱动程序,这样主程序控制思路清晰,流程简单。在以后的课节中我们就不再描述主程序的书写过程,留出主要思路讲述驱动部分的编写过程。详情请大家参考光盘(网盘)中程序及程序注释。
/***********************************************************************
* 说 明: 点亮第一个发光二极管
* 开发平台: 剑齿虎STM8开发板
* 作 者: 刘洋 张殿东
* 版 本: V1.0
* 日 期: 2016-05-03
*
* IAR开发环境 版本 V2.20.1
* ST库函数 版本 V2.2.0
***********************************************************************/
#include "pbdata.h"//引入自定义公共头文件
void BSP_Configuration(void);//硬件初始化函数声明
/***********************************************************************
* 函 数 名: main
* 功能说明: c程序入口
* 形 参:无
* 返 回 值: 错误代码(无需处理)
***********************************************************************/
int main(void)
{
BSP_Configuration();//硬件驱动初始化函数
while(1)//主程序循环,反复执行循环体里的语句
{
//LED_Demo1();//在主程序中调用LED_Demo1()函数
LED_Demo2();//在主程序中调用LED_Demo2()函数
}
}
/***********************************************************************
* 函 数 名: BSP_Configuration
* 功能说明: 初始化硬件设备。只需要调用一次。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。
* 形 参:无
* 返 回 值: 无
***********************************************************************/
void BSP_Configuration(void)
{
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);//时钟速度为内部16M,1分频,
LED_Init();//调用LED初始化函数
}
/*断言函数:它的作用是在编程的过程中为程序提供参数检查*/
#ifdef USE_FULL_ASSERT
void assert_failed(u8* file,u32 line)
{
while(1)
{
}
}
#endif
10.5.3 led.c文件中的程序
#include "pbdata.h"
/**************************************************************************
* 函 数 名: LED_Init
* 功能说明: LED的GPIO管脚初始化
* 形 参:无
* 返 回 值: 无
**************************************************************************/
void LED_Init(void)
{
GPIO_Init(LED1_PORT, LED1_PIN, GPIO_MODE_OUT_OD_HIZ_SLOW);//初始化LED1管脚为低速开漏输出高阻态
GPIO_Init(LED2_PORT, LED2_PIN, GPIO_MODE_OUT_OD_HIZ_SLOW);//初始化LED2管脚为低速开漏输出高阻态
GPIO_Init(LED3_PORT, LED3_PIN, GPIO_MODE_OUT_OD_HIZ_SLOW);//初始化LED3管脚为低速开漏输出高阻态
}
/**************************************************************************
* 函 数 名: LED_Demo1
* 功能说明: 闪烁例程,间隔时间为1秒。
* 形 参:无
* 返 回 值: 无
***************************************************************************/
void LED_Demo1(void)
{
LED1_L;//拉低PE0引脚,LED1发光二极管(发光)
LED2_L;//拉低PA3引脚,LED2发光二极管(发光)
LED3_L;//拉低PA6引脚,LED3发光二极管(发光)
delay_ms(1000);//延时1秒
LED1_H;//拉高PE0引脚,LED1发光二极管(熄灭)
LED2_H;//拉高PA3引脚,LED2发光二极管(熄灭)
LED3_H;//拉高PA6引脚,LED3发光二极管(熄灭)
delay_ms(1000);//延时1秒
}
/**************************************************************************
* 函 数 名: LED_Demo2
* 功能说明: 闪烁例程,间隔时间为1秒。
* 形 参:无
* 返 回 值: 无
**************************************************************************/
void LED_Demo2(void)
{
LED1_R;//PE0引脚电平取反,高电平时LED1发光二极管(熄灭),底电平时LED1发光二极管(发光)
LED2_R;//PA3引脚电平取反,高电平时LED2发光二极管(熄灭),底电平时LED2发光二极管(发光)
LED3_R;//PA6引脚电平取反,高电平时LED3发光二极管(熄灭),底电平时LED3发光二极管(发光)
delay_ms(1000);//延时1秒
}
10.5.4 led.h文件中的程序
/***********************************************************************
* 剑齿虎STM8开发板硬件连接
* LED1-PE0
* LED2-PA3
* LED3-PA6
************************************************************************/
#ifndef _LED_H //宏定义,定义文件名称
#define _LED_H
#include "stm8s.h"//引用STM8头文件
/*---------------------------宏定义声明-------------------------------/*
#define LED1_PIN GPIO_PIN_0 //定义GPIO_PIN_0引脚为LED1_PIN,相当于重新命名。
#define LED2_PIN GPIO_PIN_3 //定义GPIO_PIN_3引脚为LED2_PIN,相当于重新命名。
#define LED3_PIN GPIO_PIN_6 //定义GPIO_PIN_6引脚为LED3_PIN,相当于重新命名。
#define LED1_PORT GPIOE //定义GPIOE端口为LED1_PORT,相当于重新命名。
#define LED2_PORT GPIOA //定义GPIOA端口为LED2_PORT,相当于重新命名。
#define LED3_PORT GPIOA //定义GPIOA端口为LED3_PORT,相当于重新命名。
//如果想用其他管脚控制LED,那么只需更改上面对应的端口与引脚编号即可
#define LED1_L GPIO_WriteLow(LED1_PORT,LED1_PIN); //定义LED1_L,调用LED1_L命令,PE0引脚输出低电平
#define LED1_H GPIO_WriteHigh(LED1_PORT,LED1_PIN); //定义LED1_H,调用LED1_H命令,PE0引脚输出低高平
#define LED1_R GPIO_WriteReverse(LED1_PORT,LED1_PIN); //定义LED1_R,调用LED1_R命令,PE0引脚输出电平状态取反
#define LED2_L GPIO_WriteLow(LED2_PORT,LED2_PIN); //定义LED2_L,调用LED2_L命令,PA3引脚输出低电平
#define LED2_H GPIO_WriteHigh(LED2_PORT,LED2_PIN); //定义LED2_H,调用LED2_H命令,PA3引脚输出低高平
#define LED2_R GPIO_WriteReverse(LED2_PORT,LED2_PIN); //定义LED2_R,调用LED2_R命令,PA3引脚输出电平状态取反
#define LED3_L GPIO_WriteLow(LED3_PORT,LED3_PIN); //定义LED3_L,调用LED2_L命令,PA6引脚输出低电平
#define LED3_H GPIO_WriteHigh(LED3_PORT,LED3_PIN); //定义LED3_H,调用LED2_H命令,PA6引脚输出低高平
#define LED3_R GPIO_WriteReverse(LED3_PORT,LED3_PIN); //定义LED3_R,调用LED2_R命令,PA6引脚输出电平状态取反
/*---------------------------函数声明-----------------------------------*/
void LED_Init(void); //LED初始化函数
void LED_Demo1(void); //闪烁例程1,间隔时间为1秒
void LED_Demo2(void); //闪烁例程2,间隔时间为1秒
#endif //定义文件名称结束
在这里我们对程序的主要部分做了详细的说明,如果想了解全部程序,请使用IAR软件打开我们的第10讲试验程序(位置以光盘内容为主)。以后的试验程序中主程序功能都是一样的,在后续课节中我们就不再详细介绍主程序部分。
图10.5 实验程序所在位置
|