STM32实战五 板载LED显示数据

发布者:幸福家庭最新更新时间:2019-08-01 来源: eefocus关键字:STM32  实战  板载LED  显示数据 手机看文章 扫描二维码
随时随地手机看文章

写到第五章,终于有可以看见的结果了。不过磨刀不误砍柴功。正因为前面的基础,才有今天的成果,而且有一定的实用价值。封装一个BoardLED类,主要功能是利用板载LED显示数据,类似于 Morse code 电报码,以点亮时间的长短表示二进制数据的0和1,最多4位二进制,十进制15,可以扩展到更多。下面的程序显示主循环周期时间,单位1us,实际上可以用来显示设置运行状态。购买或开发不同的开发板,LED对应的脚号不同,修改程序对应的IO号即可。


 BoardLED.h 代码中用到了前几章的封装类,需要前面的原程序,全部做完以后做一个总的封包,上传到资源库中。


#ifndef __BOARDLED__

#define __BOARDLED__

 

extern "C" { // 兼容C,按C语言编译,Keil5中的包含文件已经加入了C++兼容,不用再加这一段

#pragma diag_remark 368 //消除 warning:  #368-D: class "" defines no constructor to initialize the following:

 

#include "stm32f10x.h"

 

#pragma diag_default 368 // 恢复368号警告

}

 

#include "GeneralTimer.h"

#include "IO.h"

 

class BoardLED : public IO

{

// Construction

public:

BoardLED(GeneralTimer * pTimer);

 

// Properties

public:

GeneralTimer * m_pTimer; // 定时器

u16 m_nNum; // 要显示的数

u16 m_nCurrent; // 当前显示的位

 

private:

 

// Methods

public:

void showNumber(void); // 四位二进制形式显示m_nNum

void showLED(u16 nPin, u8 nOn); // 开关LED

// Overwrite

public:

};

 

#endif

 BoardLED.cpp


/**

  ******************************************************************************

  * @file BoardLED.cpp

  * @author Mr. Hu

  * @version V1.0.0 STM32F103VET6

  * @date 05/20/2019

  * @brief 板载LED

  * @IO

  * PB13 板载LED2,不同的开发板,端口不同,做相应调整

  * PE14 板载LED3

  * m_t[0] 定时器m_pTimer中的计数1

  ******************************************************************************

  * @remarks

  * 从IO类继承,初始化对应端口

  * LED2长短编码形式显示二进制数据,短是0,长是1

  * 只显示m_nNum的低四位

  */ 

 

/* Includes ------------------------------------------------------------------*/

extern "C" { // 兼容C,按C语言编译,Keil5中的包含文件已经加入了C++兼容,不用再加这一段

#pragma diag_remark 368 //消除 warning:  #368-D: class "" defines no constructor to initialize the following:

 

#include "stm32f10x_tim.h"

 

#pragma diag_default 368 // 恢复368号警告

}

 

#include "GeneralTimer.h" // 通用定时器

#include "BoardLED.h"

 

/**

  * @date 05/20/2019

  * @brief  板载LED类

: * IO(GPIOB, GPIO_Pin_13 | GPIO_Pin_14, GPIO_Mode_Out_PP, 1)

  * 初始化板载LED对应端口,不同的开发板,端口不同,做相应调整,

  * 最后一个参数1表示初始化为上拉

  * @param pTimer,指向通用定时器类对象

  * @retval None

  */

BoardLED::BoardLED(GeneralTimer * pTimer)

: IO(GPIOB, GPIO_Pin_13 | GPIO_Pin_14, GPIO_Mode_Out_PP, 1) // 初始化板载LED对应端口,不同的开发板,端口不同,做相应调整,最后一个参数1表示初始化为上拉

, m_pTimer(pTimer) // 保存定时器

, m_nNum(0) // 要显示的数,0-15

, m_nCurrent(0x8) // 当前显示的位,最多4位

{

}

 

/**

  * @date 05/20/2019

  * @brief  以二进制形式显示m_nNum指定的数据

: * LED2点亮时间的长短表示二进制位,短是0,长是1,最大二进制数1111,十进制15。

  * @param None

  * @retval None

  */

void BoardLED::showNumber(void)

{

u32 & tim = m_pTimer->m_t[0]; // 定时时间

if(tim)

return; // 只有计数到0才显示

u8 level = GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_13);

if(level) // 当前是高电平,LED不亮

{

GPIO_ResetBits(GPIOB, GPIO_Pin_13); // 设置高电平,点亮

tim = (m_nCurrent & m_nNum) ? 500 : 5; // 当前二进制位是1,显示500ms,如果二进制位是0显示200ms秒

m_nCurrent >>= 1; // 移到下一位

}

else // 当前是低电平,LED亮

{

GPIO_SetBits(GPIOB, GPIO_Pin_13); // 设置高电平,熄灭

if(!m_nCurrent) // 数据显示完毕,暗1.5秒

{

tim = 1500; // 延时1500ms

m_nCurrent = 0x8; // 初始化当前位到最高位

}

else // 二个二进制位中间,暗500ms

tim = 500;

}

}

 

/**

  * @date 05/20/2019

  * @brief  板载LED点亮和熄灭

  * @param nPin,端口号,PB13 和/或 PB14

  * @param nOn,0灭,1亮

  * @retval None

  */

void BoardLED::showLED(u16 nPin, u8 nOn)

{

if( nOn )

GPIO_ResetBits(GPIOB, nPin); // 点亮

else

GPIO_SetBits(GPIOB, nPin); // 熄灭

}

Main.h 文件中还没有实际内容


 

#ifndef __MAIN__

#define __MAIN__

 

extern "C" { // 兼容C,按C语言编译,Keil5中的包含文件已经加入了C++兼容,不用再加这一段

#pragma diag_remark 368 //消除 warning:  #368-D: class "" defines no constructor to initialize the following:

 

#include "stm32f10x.h"

 

#pragma diag_default 368 // 恢复368号警告

}

 

 

#endif

Main.cpp 主入口程序,所列端口有些是以后用的。程序实现两个功能,一是计算主循环周期,二是设置两个板载按键,按下时LED3点亮,并具有防抖动和抗干扰功能。


/**

  ******************************************************************************

  * @file  Main.cpp

  * @author  Mr. Hu

  * @version  V1.0.0 STM32F103VET6

  * @date  05/18/2019

  * @brief  程序入口

* @io

* TIM3 PWM

* TIM4 Encode

* TIM7 通用定时器

* ADC1 ADC

* DAC1

* DAC2

*

* PA0-PA3 ADC

* PA4 DAC1输出

* PA5 DAC2输出

* PA6 PWM1

* PA7 PWM2

* PA9 板载串口

* PA10 板载串口

* PA13 板载JLINK占用

* PA14 板载JLINK占用

* PA15 板载JLINK占用

*

* PB1 板载SW2

* PB3 板载JLINK占用

* PB4 板载JLINK占用,部分映像的通道1不能用,所以用了没有得映像

* PB5 PWM

* PB6 编码器 A

* PB7 编码器 B

* PB8 板载CAN

* PB9 板载CAN

* PB10 板载RS485

* PB11 板载RS485

* PB13 板载LED2

* PB14 板载LED3

* PB15 板载SW3

*

* PC4 板载RS485

* PC5 板载RS485

******************************************************************************

  * @remarks

  *

  */ 

 

extern "C" { // 兼容C,按C语言编译,Keil5中的包含文件已经加入了C++兼容,不用再加这一段

#pragma diag_remark 368 //消除 warning:  #368-D: class "" defines no constructor to initialize the following:

 

#include "stm32f10x_tim.h"

#include "stm32f10x_dac.h"

 

#pragma diag_default 368 // 恢复368号警告

}

 

#include "stm32f10x_adc.h"

#include "IO.h"

#include "Timer.h"

#include "GeneralTimer.h"

#include "BoardLED.h"

#include "Main.h" 

 

/**

  * @date   05/18/2019

  * @brief  主入口,主循环

  *     如果不正常运行,可能是栈设置不够 startup_stm32f10x_hd.s Stack_Size EQU 0x600

  * @param  None

  * @retval None

*/

int main(void)

{

SystemInit(); // 配置系统时钟为72M

 

GeneralTimer tim(TIM2); // 通用定时器,实际用TIM7,不占用IO,但软件仿真只有1-4,所以选2

BoardLED boardLED( &tim ); // 板载LED

// 板载按键,PB1 SW2, PB2 SW3,不同的板子不一样。

IO key(GPIOB, GPIO_Pin_1 | GPIO_Pin_15, GPIO_Mode_IPU, 2); // GPIOx, nPin, GPIO_Mode_IPU 上拉, 2 输入时无效

// 使能按键滤波

//tim.inb[1].level = 1; // SW2 PB1 上拉

tim.inb[1].enable = 1; // SW2 PB1 使能

//tim.inb[15].level = 1; // SW3 PB15 上拉

tim.inb[15].enable = 1; // SW3 PB15

u32 loopCount = 0; // 主循环计数

while(1)

{

tim.loop(); // 必须放在主循环的第一行,按键滤波和上下沿微分。

// LED

// 测试时间

loopCount++;

if( !tim.m_t[2] ) // 定时器2

{

tim.m_t[2] = 1000; // 延时1000ms

boardLED.m_nNum = 1000 * 1000 / loopCount; // 计算循环周期,1000*1000对应周期单位是1us,100*1000是10us,以此类推。

if( boardLED.m_nNum > 0xf )

boardLED.m_nNum = 0xf; // 大于15时,显示15

loopCount = 0;

}

boardLED.showNumber(); // 显示四位二进制boardLED.m_nNum,用了m_t[0]

 

// 开关LED

if( tim.inb[1].down | tim.inb[15].down ) // 两个板载开关的下降沿

{

boardLED.showLED(GPIO_Pin_14, 1); // 点亮LED3

}

else if( tim.inb[1].up | tim.inb[15].up ) // 两个板载开关的上升沿

{

boardLED.showLED(GPIO_Pin_14, 0); // 熄灭LED3

}

}

}

把实战三、四、五的源程序加在一起,编译下载到单片机中,会看到LED【长短长短】有节奏的显示二进制1010,说明主循环周期是6us,软件仿真示波器显示如下,低电平是点亮。



不同的开发板,数据会不同,如果全部是0或全部是1表示溢出,修改Main.cpp中的量程,【1000*1000对应周期单位是1us,100*1000是10us,以此类推。】,如果都是0,这个数加大,否则减小。这种显示方式还有一个更好的用途就是显示错误代码,0表示正常,1-15表示各种异常,当然还可以用作其它用途。


关键字:STM32  实战  板载LED  显示数据 引用地址:STM32实战五 板载LED显示数据

上一篇:STM32实战四 定时器和按键
下一篇:STM32实战六 PWM加移相正交

推荐阅读最新更新时间:2024-11-13 11:03

STM32时钟RCC详解(二)
一、RCC寄存器介绍: typedef struct { __IO uint32_t CR; __IO uint32_t CFGR; __IO uint32_t CIR; __IO uint32_t APB2RSTR; __IO uint32_t APB1RSTR; __IO uint32_t AHBENR; __IO uint32_t APB2ENR; __IO uint32_t APB1ENR; __IO uint32_t BDCR; __IO uint32_t CSR; #ifdef STM32F10X_CL __IO uint32_t AHBRSTR; __IO uint32_t CFGR2; #
[单片机]
STM32水温控制系统硬件详解
系统介绍:基于STM32F103的水温控制系统.实现室温到100度任意区间水温控制.精度;+/-1摄氏度.平均响应应时间:5分钟.控制对象:1公斤水. 系统主要组成;铂金测温驱动电路(恒流源实现),市电电压过零检测电路.功率驱动电路(固态继电器实现),小信号放大电路(仪用运放实现),STM32单片机最小系统.500W水温加热管. 1,铂金电阻测温驱动电路 驱动PT100铂金测温电阻.和电阻桥原理相似.利用1MA精密恒流源加在铂金电阻一端,另一端接地.用另一个1MA精密恒流源加在精密100欧姆电阻一端,另一端接地.(选择100欧姆,是因为PT100在零度时电阻值是100欧姆) 这是铂金电
[单片机]
SD NAND在STM32应用上的保姆级教程
SD NAND与正点原子精英板的连接 由于正点原子精英板没有SD NAND接口,只有TF卡接口,所以SD NAND需要用到转接板来连接。 SD NAND正常运行现象 本次实验的程序是正点原子的SD卡实验例程,先用读卡器把SD NAND接到电脑上,并复制一个文件进去,再插到开发板上; 用送的数据线连接USB UART接口,下载好程序,打开电脑上的串口助手,按下KEY0,即可读取到数据, 具体实验步骤和现象可以看例程文件夹中的readme, 另外LED-DS0闪烁也表示SD NAND芯片在正常运行, SD NAND芯片用的是MK-米客方德的工业级芯片MKDV1GIL-AS;MK-米客方德家还有其他各种型号的SD NAN
[单片机]
SD NAND在<font color='red'>STM32</font>应用上的保姆级教程
UART和USART有区别
  UART   UART是一种通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输和接收。在嵌入式设计中,UART用于主机与辅助设备通信,如汽车音响与外接AP之间的通信,与PC机通信包括与监控调试器和其它器件,如EEPROM通信。   UART的功能计算机内部采用并行数据,不能直接把数据发到Modem,必须经过UART整理才能进行异步传输,其过程为:CPU先把准备写入串行设备的数据放到UART的寄存器(临时内存块)中,再通过FIFO(First Input First Output,先入先出队列)传送到串行设备,若是没有FIFO,信息将变得杂乱无章,不可能传送到Modem。它是用于控制计算机与串行设备的芯片。有
[单片机]
STM32之蓝牙透传模块(昇润科技HY-254124 V8)
一、简介 本文介绍如何使用STM32控制蓝牙透传模块,蓝牙透传模块使用昇润科技的HY-254124 V8。 二、实验平台 库版本:STM32F10x_StdPeriph_Lib_V3.5.0 编译软件:MDK4.53 硬件平台:STM32开发板(主芯片stm32f103c8t6) 仿真器:JLINK 三、版权声明 四、实验前提 在进行本文步骤前,请先阅读并实现以下博文: 1、《STM32之NVIC》:http://blog.csdn.net/feilusia/article/details/52819709 2、《STM32之串口》:http://blog.csdn.net/feilus
[单片机]
<font color='red'>STM32</font>之蓝牙透传模块(昇润科技HY-254124 V8)
gd32和stm32程序可以互用吗?
GD32和STM32是两种不同的芯片系列,相同点是都属于ARM Cortex-M系列芯片。虽然它们有相似的架构和指令集,但是由于它们来自不同的厂商,所以它们之间仍然存在一些差异。因此,GD32和STM32之间不能直接互用程序。 首先,GD32和STM32之间的主要差异在于硬件平台。GD32和STM32的硬件平台不完全相同,存在一些不同之处,例如引脚定义、时钟控制、中断控制等。这些差异会影响程序在不同硬件平台上的运行。因此,如果要实现程序互用,需要在代码中加入条件编译和适配。 其次,GD32和STM32之间的软件支持也有所不同。虽然它们都遵循ARM Cortex-M系列的指令集,但它们的官方开发环境、库文件和驱动程序可能存在差异。因
[单片机]
STM32 GPIO设置
STM32的输入输出管脚有下面8种可能的配置:(4输入+2输出+2复用输出) ① 浮空输入_IN_FLOATING ② 带上拉输入_IPU ③ 带下拉输入_IPD ④ 模拟输入_AIN ⑤ 开漏输出_OUT_OD ⑥ 推挽输出_OUT_PP ⑦ 复用功能的推挽输出_AF_PP ⑧ 复用功能的开漏输出_AF_OD 1.1 I/O口的输出模式下,有3种输出速度可选(2MHz、10MHz和50MHz),这个速度是指I/O口驱动电路的响应速度而不是输出信号的速度,输出信号的速度与程序有关(芯片内部在I/O口的输出部分安排了多个响应速度不同的输出驱动电路,用户可以根据自己的需要选择合适的驱动电路)。通过选
[单片机]
STM32外部中断(EXTI)分析和应用
本篇博文基于STM32F103ZET6芯片,与大多数STM32F10x芯片兼容; 代码基于ST官网提供的3.5.0标准库 如有不足之处,还望前辈多多指教; 一些需要了解的基础知识 STM32每个GPIO口都可以作为外部中断输入口使用 每个中断都设有状态位 每个中断/事件都有独立的触发和屏蔽设置。 STM32103有19个外部中断(但是供GPIO口使用的中断只有16个) 分别是: 0~15:对应外部中断IO的输入中断 16 : 连接到PVD输出 17 :连接到RTC闹钟时间 18 :连接到USB唤醒事件 这里会容易出现一个问题说:STM32F103ZET6的GPIO管脚一共有6*16即96个GPIO管脚,如何对应只有0~15
[单片机]
<font color='red'>STM32</font>外部中断(EXTI)分析和应用
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved