历史上的今天
返回首页

历史上的今天

今天是:2025年08月01日(星期五)

正在发生

2019年08月01日 | STM32实战五 板载LED显示数据

2019-08-01 来源:eefocus

写到第五章,终于有可以看见的结果了。不过磨刀不误砍柴功。正因为前面的基础,才有今天的成果,而且有一定的实用价值。封装一个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表示各种异常,当然还可以用作其它用途。


推荐阅读

史海拾趣

Conexcon Group公司的发展小趣事

面对日益激烈的市场竞争,Conexcon Group积极寻求与国内外知名企业的战略合作。通过与行业巨头的联合研发和市场推广,公司成功将自身产品推向了更广阔的市场。同时,这些合作也为公司带来了先进的技术和管理经验,进一步提升了公司的核心竞争力。在合作中,Conexcon Group始终坚持开放、共赢的原则,与合作伙伴共同推动电子行业的发展。

BOWEI公司的发展小趣事

在电子行业的快速发展中,Conexcon Group以其前瞻性的技术视野,成功研发出一款新型智能芯片,这款芯片不仅性能卓越,而且功耗极低,迅速赢得了市场的青睐。公司凭借这一技术突破,逐步扩大了在国内外市场的份额,成为了行业内技术创新的领军者。随着产品线的不断丰富,Conexcon Group逐渐形成了从芯片设计到整机制造的完整产业链,进一步巩固了其在电子行业的领先地位。

Excellence Optoelectronics Inc公司的发展小趣事

EOI始终将产品质量放在首位。公司建立了严格的质量管理体系,从原材料采购到生产流程,再到产品检测,每一个环节都严格把控。同时,EOI还注重员工的培训和教育,提高员工的质量意识和技能水平。这些努力使得EOI的产品质量得到了客户的广泛认可,公司也因此树立了良好的品牌形象。

台湾美丽微(FMS)公司的发展小趣事

FTDI的历史可以追溯到1992年3月13日,由弗雷德·达特(Fred Dart)创立。公司初期专注于个人电脑市场,推出了针对主板芯片组的解决方案。其中,早期的主要客户之一是IBM,这些芯片被应用于AMBRA和PS/2系列的个人电脑中,为当时的计算机技术发展做出了重要贡献。这一时期的成功不仅奠定了FTDI的技术基础,也为其后续的市场拓展奠定了坚实的客户基础。

DURATOOL公司的发展小趣事

人才是企业发展的第一资源。DURATOOL公司一直高度重视人才的培养和引进。公司建立了一套完善的人才选拔和培养机制,通过内部培训、外部招聘等方式不断吸纳优秀人才加入公司。同时,公司还为员工提供了广阔的发展空间和良好的福利待遇,激发了员工的积极性和创造力。这些举措使得DURATOOL公司拥有一支高素质、专业化的员工队伍,为企业的发展提供了有力的人才保障。

American Custom Components公司的发展小趣事

American Custom Components公司自创立之初,就致力于电子元器件的创新研发。在一次技术研讨会上,公司的研发团队发现了一种新型的半导体材料,具有出色的导电性和稳定性。经过数月的实验和验证,团队成功地将这种材料应用于新产品中,推出了一款性能卓越的集成电路。这一创新技术不仅提升了公司的产品质量,还赢得了市场的广泛认可,为公司的发展奠定了坚实基础。

问答坊 | AI 解惑

PSPICE电子线路仿真详细资料!!!

这个十分的精典.... 里面详细介绍了元件模型的建立...以及各电源模型的超详细介绍...最基础的东西... 是国内的ORCAD书中没有介绍的....…

查看全部问答>

ARM文件系统的实现

ARM文件系统的实现…

查看全部问答>

基于DSP的全桥移相控制感应加热电源研究

引言 随着感应加热电源对自动化控制程度及可靠性要求的提高,感应加热电源正向智能化与数字化控制的方向发展。DSP具有高速的数字处理能力及丰富的外设功能,使得一些先进的控制策略能够应用实践,研究基于DSP的数字控制感应加热电源,可使产品具有 ...…

查看全部问答>

关于8bit编码短信接收的问题

使用系统是wince60,RIL驱动已经实现 使用SMS API收发短信 发送: SmsSendMessage函数 发7bit 16bit编码短信成功。8bit编码使用RIL API发送 接收: SmsReadMessage函数 接收过程是: SmsOpen函数获得短信句柄与事件 WaitForSingleObject ...…

查看全部问答>

散分!同时寻找北京WINCE开发人员加入“嵌入式技术外包群”

帮朋友发布一下消息,请大家多多捧场哈! 如题!诚请在北京的WINCE技术高手加入“嵌入式技术外包群”,该群将不定期       发布一些外包信息!       群号:48348107…

查看全部问答>

新建嵌入式交流群6239452 欢迎加入!

新建嵌入式交流群6239452 欢迎加入!…

查看全部问答>

PNG双缓冲问题,为什么我的图片不能显示呢??

int width= dstRc.right-dstRc.left,                                         heigth = dstRc.top-dstRc.bottom;       ...…

查看全部问答>

wceload.exe 后台安装 CAB 文件

        平台:WinCE>NET4.2 开发平台EVC4.2         目的: 运行 wceload.exe打开SD卡里面的Main.CAB自动安装文件,而且是在后台安装,就是不是显示有关安装信息.    &nbs ...…

查看全部问答>

有没有人和我来一起做STM32的学习板

                                 不知道2面板可以不?QQ:11830067…

查看全部问答>