你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

查看: 1773|回复: 2

[STM32L476] 4、NUCLEO-L476RG试验三_LED闪闪亮续(定时、串口)

[复制链接]

74

主题

1368

回帖

194

蝴蝶豆

版主

最后登录
2020-5-12
发表于 2017-6-17 10:42:35 | 显示全部楼层 |阅读模式
本帖最后由 wolfgang2015 于 2017-6-17 10:51 编辑

一、实验开始之前二、实验过程0、上次实验回顾
   上次实验中,我们通过STM32CubeMX创建了通过按键捕获中断,实现LED变频闪亮的工程,通过不断按下用户键实现LED,让LED从延时512开始,逐次减半延时至0的规律循环。
   回顾实验,有几个核心函数出现在试验中:
1、按键功能并没有接其它元器件,只使用了MCU上GPIO的中断捕获功能,用到的中断回调函数 void HAL_GPIO_EXTI_Callback(uint16_tGPIO_Pin),在中断使能情况下,当捕获到了对应中断,进入中断回调函数中,执行中断代码逻辑。在HAL库中。

2、调用这个回调函数的函数为:
  void HAL_GPIO_EXTI_IRQHandler(uint16_tGPIO_Pin) 而, 这个函数是由void EXTI4_15_IRQHandler(void)中调用,EXTI4_15_IRQHandler是在启动汇编文件中的中断向量表中供ARM系统调用。当ARM系统产生中断而没有被屏蔽,立即会触发中断函数中的内容。
3、GPIO口的相关定义,B1_Pin、B1_GPIO_Port
      
        
GPIO_InitStruct.Pin = B1_Pin;
   
   
                                 
这几个引脚的定义在{项目名称}\Inc\ mxconstants.h 文件中,定义内容如下:

        
#define B1_Pin GPIO_PIN_13
   
#define B1_GPIO_Port GPIOC
   
   
   
   
GPIO_PIN_13的定义在 {项目名称}\Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_gpio.h 文件中

        
.......
   
#define    GPIO_PIN_13                   ((uint16_t)0x2000U)  /* Pin 13    selected  */
   
......
   
   
   
GPIOC的定义在 {项目名称}\Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal.h 文件中

        
.........
   
#define    PERIPH_BASE              ((uint32_t)0x40000000) /*!< Peripheral base address */
   
.........
   
#define    AHB2PERIPH_BASE       (PERIPH_BASE +    0x08000000)
   
........
   
#define    GPIOA_BASE               (AHB2PERIPH_BASE + 0x0000)
   
.......
   
#define    GPIOC               ((GPIO_TypeDef *)    GPIOC_BASE)
   
.......
   
   
   
   这里我们可以发现GPIOA是一个32位的寄存器,每个GPIO引脚都由这个积存器的bit来控制,而且这个寄存器的基地址由GPIOA_BASE 得来,GPIOA_BASE这个基地址是由AHB2PERIPH_BASE + 0x0000得来,AHB2PERIPH_BASE这个基地址是由 PERIPH_BASE +0x08000000得来;PERIPH_BASE这个基地址是由(uint32_t)0x40000000。
  这种用基址+偏移的方法来定义常量很不错,寄存器往往有一个固定的地址,如果编译、移植,如果偏移不变,只需要更换基址即可。

GPIO_TypeDef结构体是在{项目名称}\Drivers\CMSIS\Device\ST\STM32L4xx\Include\stm32l476xx.h

        
typedef    struct
   
{
   
  __IO uint32_t MODER; /*!< GPIO port    mode register,         Address    offset: 0x00  */
   
  __IO uint32_t OTYPER; /*!< GPIO port    output type register,    Address    offset: 0x04  */
   
  __IO uint32_t OSPEEDR; /*!< GPIO port    output speed register,  Address    offset: 0x08  */
   
  __IO uint32_t PUPDR; /*!< GPIO port    pull-up/pull-down register,  Address    offset: 0x0C  */
   
  __IO uint32_t IDR; /*!< GPIO port    input data register,   Address    offset: 0x10  */
   
  __IO uint32_t ODR; /*!< GPIO port    output data register,  Address    offset: 0x14  */
   
  __IO uint32_t BSRR; /*!< GPIO port bit    set/reset  register,  Address offset: 0x18  */
   
  __IO uint32_t LCKR; /*!< GPIO port    configuration lock register,  Address    offset: 0x1C  */
   
  __IO uint32_t AFR[2]; /*!< GPIO    alternate function registers,        Address offset: 0x20-0x24 */
   
  __IO uint32_t BRR; /*!< GPIO Bit Reset    register,  Address offset: 0x28  */
   
  __IO uint32_t ASCR; /*!< GPIO analog    switch control register,   Address    offset: 0x2C  */
   
}    GPIO_TypeDef;
   
   
   
  GPIO_PIN_SET、GPIO_PIN_RESET的定义在{项目名称}\Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_gpio.h 文件中

4、GPIO口的模式: [url=]上升沿触发[/url]

        
......
   
GPIO_InitStruct.Mode=GPIO_MODE_IT_RISING;
   
......
   
   
   
GPIO_MODE_IT_RISING的定义在 {项目名称}\Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_gpio.h 文件中

        
....
   
#define  GPIO_MODE_IT_RISING  (0x10110000U)   
   
        /*!< External Interrupt Mode    with Rising edge trigger detection   */
   
......
   
   
   

5、外部中断初始化并中断使能。

        
......
   
HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0,    0);
   
HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
   
......
   
   
   
中断的相关初始化和使能,在{项目名称}\Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_cortex.h 文件中。

1、新实验设想
GPIO的输出、中断捕获功能原理熟悉之后,可以进一步设想,能否对实验进行改进,利用CPU的定时器作为参照灯或心跳灯,检测程序是否运行;并利用串口将按键后改变的延时值输出到上位机进行展示。
A)定时器设置:
使用CubeMX打开芯片引脚设置,将定时器1的时钟源设置为内部时钟。
                                     01.jpg

02.jpg

系统时钟频率设置为80MHz
03.jpg

在定时器功能中设置如下:
04.jpg
设置预分频40000-1(0~39999),计数时间1000-1(0~1999),确定每次中断计数就是一个2000次计数,每次计数是1ms,。

定时器中断使能。
06.jpg

B)串口设置:
07.jpg
     选择功能树上Usart2,为异步模式,VCP仅使用了Rx和Tx 并无流控,因此硬件流控为禁用:
08.jpg
  设定PIN脚 PA2为Usart_TX,PA3为Usart_RX。
       09.jpg

在串口功能中设置如下:
10.jpg

波特率:115200,数据长度,8bits,起停位1bit,其他的保持默认
11.jpg

USART2 中断使能
12.jpg

GPIO口及标签设置如上图
设置完以上内容后,通过CubeMX创建试验代码。

CubeMX创建的实验代码有专门的章节介绍,这里介绍分析省略。


2、实验步骤
  A)定时器设置:
  定时器设置虚要外界一个LED或者蜂鸣器,通过GPIO F4口来进行控制
  先设置好定时器的回调函数,通过回调函数控制LED的闪亮和熄灭:
在mxconstants.h 文件定义定时器的GPIO引脚,GPIO的相关设置参考前面的设置方法:

        
......
   
#define LDTimer_Pin GPIO_PIN_4
   
#define LDTimer_GPIO_Port GPIOF
   
.......
   
   

在main.h设置定时器控制的LED相关控制函数

        
......
   
#define TIMERLED(STA)     (STA)?HAL_GPIO_WritePin(LDTimer_GPIO_Port,LDTimer_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(LDTimer_GPIO_Port,LDTimer_Pin,GPIO_PIN_RESET)
   
......
   
   
   




定义定时器回调函数中的内容:

        
.......
   
static uint8_t staTimer = ON;
   
......
   
void    HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
   
  TIMERLED(staTimer);
   
  staTimer    = !staTimer;
   
}
   
......
   
   


main()函数中主循环里设置启动定时器:
     
        
.......
   
//TIME启动;
   
         HAL_TIM_Base_Start_IT(&htim1);
   
......
   
   



  B)串口设置:
先设置串口的发送数据缓冲区和接收缓冲区
在main.h 文件定义发送和接收缓冲区的大小:

        
......
   
#define RxBufferSize  64
   
#define TxBufferSize  64
   
.......
   
   

在main.c文件中定义发送和接收缓冲区的数组:
     
        
......
   
static uint8_t Rx_Buffer[RxBufferSize]    = { 0 };
   
static uint8_t Tx_Buffer[TxBufferSize]    = { 0 };
   
.......
   
   

在非DMA方式下实现串口通信时需要设置以下内容:
Usart2的初始化函数(MX_USART2_UART_Init)中,设置中断和数据接收缓冲区
     
        
......
   
HAL_UART_Receive_IT(&huart2,Rx_Buffer,RxBufferSize);
   
.......
   
   

在Main.c文件中,设置好串口中断回调函数:
     
        
........
   
void    HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
  if    (huart==&huart2){
   
     //printf("Rx: %s \n",Rx_Buffer);  //设置好Printf方式输出后可去掉注释符号
   
     .........//捕获中断后,将接收到的缓冲数据,进行数据处理的函数(这里略)
   
     HAL_UART_Receive_IT(&huart2,Rx_Buffer,RxBufferSize);
   
  }
   
}
   
.......
   
   

在Main.c文件中,设置好发送数据函数
     
        
........
   
static uint8_t *TxBuffer;
   
static uint32_t StrN; //设置动态字符串长度值
   
........
   
void SendWithOutDMA_Len(void) {
   
       TxBuffer = (uint8_t *) malloc(StrN * sizeof(uint8_t));
   
       .......//组织TxBuffer 将发送的字符串拼接起来;
   
    HAL_UART_Transmit(&huart2,    TxBuffer, StrN, 0xff);
   
       free(TxBuffer);
   
}
   
.......
   
   

SendWithOutDMA_Len();函数放到需要发送数据的功能下便可实现串口发送数据;
这里将函数放在按键响应函数中:
     
        
........
   
void KeyPass(void) {
   
........
   
       //按键发送数据
   
    SendWithOutDMA_Len();
   
......
   
}
   
.......
   
   




通过Printf函数进行串口输出设置:
      
        
........
   
/* USER CODE BEGIN Includes */
   
.......
   
#ifdef __GNUC__
   
     /* With GCC, small printf (option LD Linker->Libraries->Small    printf
   
        set to 'Yes') calls __io_putchar() */
   
     #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
   
#else
   
     #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
   
#endif /* __GNUC__ */
   
......
   
/* USER CODE END Includes */
   
.......
   
   
/* USER CODE BEGIN 4 */
   
........
   
/* retarget the C library printf    function to the USART */
   
PUTCHAR_PROTOTYPE
   
{
   
     /* Place your implementation of fputc here */
   
     /* e.g. write a character to the EVAL_COM1 and Loop until the end of    transmission */
   
     HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);
   
     return ch;
   
}
   
.......
   
/* USER CODE END 4 */
   
   
   
   
   

经过以上设置之后,即可用printf函数向串口输出字符串了
printf("HelloSTM32L476RC! \n");
3、实验的观察结果
  A)定时器:
  外接的LED(注意串接一个分压电阻)每一秒钟闪亮一次;
  B)串口:
  可通过SendWithOutDMA_Len()函数向串口输出信息;
  也可通过Printf("xxxxxxx")函数向串口输出信息;
三、实验后的心得
    这个实验,可以了解到定时器回调函数、串口回调函数的使用方式,在串口发送数据的实验中,还体验到串口不同的数据发送方式(使用中断方式方式发送和接收数据,使用Printf函数发送数据)。



此前以为发了次文章,后来检查文章时才发现忘发此帖了(补一个)
界此,基于Nucleo系列板卡的试验基础环境搭建好了,之后回基于这些基本LED、按键、中断、串口、定时器的基本功能做一系列的试验,下一个系列是低功耗系列


后文连接:
   1、ST线下培训(05-23成都站)STM32L476低功耗设计(一)
回复

使用道具 举报

11

主题

661

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-6-8
发表于 2017-6-27 08:03:19 | 显示全部楼层
学习学习。。。。。。。
回复 支持 反对

使用道具 举报

1

主题

16

回帖

0

蝴蝶豆

初级会员

最后登录
2019-4-30
发表于 2018-10-15 16:05:52 | 显示全部楼层
谢谢大佬
回复 支持 反对

使用道具 举报

关于 意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
13245底部标题123相同标题
12底部标题123相同标题
33333底部标题123相同序号
3435底部标题-无链接
关注我们
st-img 微信公众号
st-img 手机版