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

查看: 1779|回复: 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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版