STM32
直播中

硕达科讯

7年用户 845经验值
私信 关注
[问答]

基于寄存器与基于固件库的stm32 LED流水灯编程方式有何差异

如何去实现基于寄存器的STM32 LED流水灯程序呢?
基于寄存器与基于固件库的stm32 LED流水灯编程方式有何差异?

回帖(1)

林森

2021-12-6 15:36:48
一、学习任务




  • 学习相关资料,说名基于寄存器与基于固件库的stm32 LED流水灯例子的编程方式有什么差异。
  • 学习和阅读“零死角玩转STM32F103–指南者”文档中的第20、21章内容,完成STM32的USART窗口通讯程序,要求:1)设置波特率为115200,1位停止位,无校验位。2)STM32系统给上位机(win10)连续发送“hello windows!”,上位机接收程序可以使用“串口调试助手“,也可自己编程。3)当上位机给stm32发送“Stop,stm32”后,stm32停止发送。

二、学习内容

1.基于寄存器与基于固件库的stm32 LED流水灯编程方式差异

1.1基于寄存器的stm32 LED流水灯程序

1.1.1寄存器简介

寄存器的功能是存储二进制代码,它是由具有存储功能的触发器组合起来构成的。一个触发器可以存储1位二进制代码,故存放n位二进制代码的寄存器,需用n个触发器来构成。
按照功能的不同,可将寄存器分为基本寄存器和移位寄存器两大类。基本寄存器只能并行送入数据,也只能并行输出。移位寄存器中的数据可以在移位脉冲作用下依次逐位右移或左移,数据既可以并行输入、并行输出,也可以串行输入、串行输出,还可以并行输入、串行输出,或串行输入、并行输出,十分灵活,用途也很广。
1.1.2.代码


led.h编程
#ifndef __LED_H#define __LED_H #include "sys.h"//LED端口定义#define LED0 PBout(5) // DS0#define LED1 PEout(5) // DS1 void LED_Init(void);        //初始化 #endifled.cwindows
#include "led.h"//初始化PB5和PE5为输出口.并使能这两个口的时钟 //LED IO初始化void LED_Init(void){            RCC->APB2ENR|=1<<3;    //使能PORTB时钟         RCC->APB2ENR|=1<<6;    //使能PORTE时钟                             GPIOB->CRL&=0XFF0FFFFF;         GPIOB->CRL|=0X00300000;//PB.5 推挽输出   GPIOB->ODR|=1<<5;      //PB.5 输出高                                                                                                  GPIOE->CRL&=0XFF0FFFFF;        GPIOE->CRL|=0X00300000;//PE.5推挽输出        GPIOE->ODR|=1<<5;      //PE.5输出高 }main.csvg
#include "sys.h"#include "usart.h" #include "delay.h" #include "led.h"int main(void){                                              Stm32_Clock_Init(9);//系统时钟设置        delay_init(72);                  //延时初始化        LED_Init();                          //初始化与LED链接的硬件接口        while(1)        {                    LED0=0;                //低电平有效                LED1=1;                delay_ms(1000);                LED0=1;                LED1=0;                delay_ms(1000);        }         }1.2基于固件库的stm32 LED流水灯程序

1.2.1固件库概述

固件是介于软件和硬件之间的产品,给开发者访问底层硬件提供一个中间的API,大大提高应用程序开发效率。CMSIS: ARM Cortex™ 微控制器软件接口标准(CMSIS:Cortex Microcontroller Software Interface Standard) 是 Cortex-M 处理器系列的与供应商无关的硬件抽象层,使用CMSIS,可以为处理器和外设实现一致且简单的软件接口,从而简化软件的重用、缩短微控制器新开发人员的学习过程,并缩短新设备的上市时间。
1.2.2代码


led.h学习
#ifndef __LED_H#define __LED_H #include "sys.h"#define LED0 PBout(5)// PB5#define LED1 PEout(5)// PE5 void LED_Init(void);//初始化 #endifled.cui
#include "led.h"//初始化PB5和PE5为输出口.并使能这两个口的时钟 //LED IO初始化void LED_Init(void){     GPIO_InitTypeDef  GPIO_InitStructure;         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);         //使能PB,PE端口时钟  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                                 //LED0-->PB.5 端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz GPIO_Init(GPIOB, &GPIO_InitStructure);                                         //根据设定参数初始化GPIOB.5 GPIO_SetBits(GPIOB,GPIO_Pin_5);                                                 //PB.5 输出高 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                             //LED1-->PE.5 端口配置, 推挽输出 GPIO_Init(GPIOE, &GPIO_InitStructure);                                           //推挽输出 ,IO口速度为50MHz GPIO_SetBits(GPIOE,GPIO_Pin_5);                                                  //PE.5 输出高 }main.cspa
#include "sys.h"#include "delay.h"#include "usart.h"#include "led.h" int main(void) {                    delay_init();            //延时函数初始化         LED_Init();                          //初始化与LED链接的硬件接口                 while(1)        {                    LED0=0;                LED1=1;                delay_ms(300);         //延时300ms                LED0=1;                LED1=0;                delay_ms(300);        //延时300ms        }     } /** *****************下面注视的代码是经过调用库函数来实现IO控制的方法***************************************** int main(void) { delay_init(); //初始化延时函数 LED_Init(); //初始化LED端口 while(1) { GPIO_ResetBits(GPIOB,GPIO_Pin_5); //LED0对应引脚GPIOB.5拉低,亮 等同LED0=0; GPIO_SetBits(GPIOE,GPIO_Pin_5); //LED1对应引脚GPIOE.5拉高,灭 等同LED1=1; delay_ms(300); //延时300ms GPIO_SetBits(GPIOB,GPIO_Pin_5); //LED0对应引脚GPIOB.5拉高,灭 等同LED0=1; GPIO_ResetBits(GPIOE,GPIO_Pin_5); //LED1对应引脚GPIOE.5拉低,亮 等同LED1=0; delay_ms(300); //延时300ms } }1.3 差异

仔细观察源代码发现主要是led.c中的LED_Init()函数有很大的差别。基于寄存器的主要是使用指针指向地址进行使能和赋值;基于固件库主要使用的函数包进行使能和赋值。在小工程中可以看出使用寄存器和固件库是没有多大差别的,但从实现多功能和多端口的工程设计来看,使用固件库可以大大减少开发时间,提高工作效率。
使用固件库,目前比较多的例程是使用固件库编写的。官方的例子也都采用固件库方式。特点就是简单,易于理解,资料多。如果你没有CortexM系列内核的开发基础,建议从固件库开始玩起。等有一定基础,或是特别需要时再用寄存器。
使用寄存器,想要深入理解CortexM3内核或是需要为了获得更好的可移植性,学习寄存器编程会比较有帮助。但是从专业的角度上看,寄存器更贴近底层,对外设的工作原理和运行机理会有更深的理解。
2.STM32的USART窗口通讯程序

2.1 实验环境

开发板:野火指南者(STM32F103)
STM32库版本:STM32F10x_StdPeriph_Lib_V3.5.0
IDE:KEIL5
使用到的串口:USART1
硬件原理图:





2.2 实验文件

下载完成后如箭头所示打开keil文件。





2.3.相关代码及修改

2.3.1 找到stm32f10x_it.c,及main.c;





2.3.2 代码
stm32f10x_it.c:

int i=0;uint8_t ucTemp[50];void DEBUG_USART_IRQHandler(void){            if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET)        {                    ucTemp = USART_ReceiveData(USART1);                }  if(ucTemp == '!')        {                    if(ucTemp[i-1] == '2'&&ucTemp[i-2] == '3'&&ucTemp[i-3] == 'm'&&ucTemp[i-4] == 't'&&ucTemp[i-5] == 's'&&ucTemp[i-6] == ' ')                        if(ucTemp[i-7] == 'p'&&ucTemp[i-8] == 'o'&&ucTemp[i-9] == 't'&&ucTemp[i-10] == 's')                        {                                    printf("收 到!");        while(1);                        }        }        i++;}main.c:
#include "stm32f10x.h"#include "bsp_usart.h"void delay(uint32_t count){            while(count--);}int main(void){              USART_Config();  while(1)        {                            printf("hello windows!n");                delay(5000000);        }        }2.3.3.修改如下
stm32f10x_it.c:





main.c:





2.3.4编译及生成hex文件





2.4.烧录程序

2.4.1 连接开发板

2.4.2打开串口下载器选择刚编译生成的.hex文件,然后进行烧写




举报

更多回帖

×
20
完善资料,
赚取积分