> 文档中心 > 【MM32F5270开发板试用】+串口中断接收与定时器

【MM32F5270开发板试用】+串口中断接收与定时器


本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:szit

一 准备工作

PLUS-F5270开发板基于灵动MM32F5系列芯片的Armv8-M 架构的 “星辰” STAR-MC1 处理器,资料链接:https://aijishu.com/a/1060000000341750。
试用前准备好开发环境Keil 3.7以及安装当前灵动官网固件包MindMotion.MM32F5277E_DFP.0.0.6.pack。在https://mindsdk.mindmotion.com.cn/注册并配置下载MindSDK。

【MM32F5270开发板试用】+串口中断接收与定时器

二 准备实验的功能

2.1 PC端串口发送 FF FF XX 12 DD,XX低4位控制4个LED的亮灭,1亮0灭,最低位bit0对应LED1,bit1对应LED2,bit2对应LED3,bit3对应LED4;

2.2 定时中断1秒,每秒串口打印指定内容;

三 实现过程相关代码

以SDK中“uart_rx_interrupt”工程作为基础,里面添加相关功能函数与定义。

3.1时钟初始化

在clock_init.c里void BOARD_InitBootClocks(void)添加LED与定时器的时钟。

void BOARD_InitBootClocks(void){    CLOCK_ResetToDefault();    CLOCK_BootToHSE120MHz();    /* UART1. */    RCC_EnableAPB2Periphs(RCC_APB2_PERIPH_UART1, true);    RCC_ResetAPB2Periphs(RCC_APB2_PERIPH_UART1);    /* GPIOB. */    RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOB, true);    RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOB); /* GPIOC. */    RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOC, true);    RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOC); /* GPIOD. */    RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOD, true);    RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOD);    /* GPIOI. */    RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOI, true);    RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOI);    /* TIM1. */    RCC_EnableAPB2Periphs(RCC_APB2_PERIPH_TIM1, true);    RCC_ResetAPB2Periphs(RCC_APB2_PERIPH_TIM1);}

3.2 添加LED与TIM1宏定义

board_init.h

#ifndef __BOARD_INIT_H__#define __BOARD_INIT_H__#include #include "hal_common.h"#include "clock_init.h"#include "hal_tim.h"#include "hal_uart.h"#include "pin_init.h"#include "hal_gpio.h"#include "string.h"/* LED. */#define LED1ON  GPIO_WriteBit(GPIOI, GPIO_PIN_0, 0u)#define LED1OFF GPIO_WriteBit(GPIOI, GPIO_PIN_0, 1u)#define LED2ON  GPIO_WriteBit(GPIOD, GPIO_PIN_2, 0u)#define LED2OFF GPIO_WriteBit(GPIOD, GPIO_PIN_2, 1u)#define LED3ON  GPIO_WriteBit(GPIOB, GPIO_PIN_14, 0u)#define LED3OFF GPIO_WriteBit(GPIOB, GPIO_PIN_14, 1u)#define LED4ON  GPIO_WriteBit(GPIOC, GPIO_PIN_9, 0u)#define LED4OFF GPIO_WriteBit(GPIOC, GPIO_PIN_9, 1u)/* DEBUG UART. */#define BOARD_DEBUG_UART_PORT UART1#define BOARD_DEBUG_UART_BAUDRATE    9600u#define BOARD_DEBUG_UART_FREQ CLOCK_APB2_FREQ#define BOARD_DEBUG_UART_IRQn UART1_IRQn#define BOARD_DEBUG_UART_IRQHandler  UART1_IRQHandler/* TIM1. */#define BOARD_TIM_PORT(TIM_Type *)TIM1#define BOARD_TIM_IRQnTIM1_UP_IRQn#define BOARD_TIM_IRQHandler TIM1_UP_IRQHandler#define BOARD_TIM_FREQCLOCK_SYS_FREQvoid BOARD_Init(void);#endif /* __BOARD_INIT_H__ */

3.3 配置IO口

pin_init.c

#include "pin_init.h"#include "hal_rcc.h"#include "hal_gpio.h"void BOARD_InitPins(void){    /* PB6 - UART1_TX. */    GPIO_Init_Type gpio_init;    gpio_init.Pins  = GPIO_PIN_6;    gpio_init.PinMode  = GPIO_PinMode_AF_PushPull;    gpio_init.Speed = GPIO_Speed_50MHz;    GPIO_Init(GPIOB, &gpio_init);    GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_7);    /* PB7 - UART1_RX. */    gpio_init.Pins  = GPIO_PIN_7;    gpio_init.PinMode  = GPIO_PinMode_In_Floating;    gpio_init.Speed = GPIO_Speed_50MHz;    GPIO_Init(GPIOB, &gpio_init);    GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_7);    /* PI0 - LED1. */    gpio_init.Pins  = GPIO_PIN_0;    gpio_init.PinMode  = GPIO_PinMode_Out_PushPull;    gpio_init.Speed = GPIO_Speed_50MHz;    GPIO_Init(GPIOI, &gpio_init);    GPIO_PinAFConf(GPIOI, gpio_init.Pins, GPIO_AF_15);  /* PD2 - LED2. */    gpio_init.Pins  = GPIO_PIN_2;    gpio_init.PinMode  = GPIO_PinMode_Out_PushPull;    gpio_init.Speed = GPIO_Speed_50MHz;    GPIO_Init(GPIOD, &gpio_init);    GPIO_PinAFConf(GPIOD, gpio_init.Pins, GPIO_AF_15);     /* PB14 - LED3. */    gpio_init.Pins  = GPIO_PIN_14;    gpio_init.PinMode  = GPIO_PinMode_Out_PushPull;    gpio_init.Speed = GPIO_Speed_50MHz;    GPIO_Init(GPIOB, &gpio_init);    GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_15);     /* PD2 - LED4. */    gpio_init.Pins  = GPIO_PIN_9;    gpio_init.PinMode  = GPIO_PinMode_Out_PushPull;    gpio_init.Speed = GPIO_Speed_50MHz;    GPIO_Init(GPIOC, &gpio_init);    GPIO_PinAFConf(GPIOC, gpio_init.Pins, GPIO_AF_15);}

3.4 主程序

main.c里包含定时器初始化与定时器中断处理,串口字符输出函数以及串口中断接收处理函数。

#include #include #include "board_init.h"/* * Macros. */#define APP_UART_RX_BUFF_LEN 8uuint16_t i=0;uint8_t *LEDStatus;#define APP_TIM_UPDATE_PERIOD  2000u/* * Variables. */uint8_t  app_uart_rx_buff[APP_UART_RX_BUFF_LEN]= {0};uint32_t app_uart_rx_buff_idx = 0u;uint8_t USART_RX_STA=0;/* * Declerations. */void app_uart_init(void);void app_uart_rx_isr_hook(void);void app_uart_putchar(uint8_t c);void app_uart_putstr(uint8_t *str);void app_tim_init(void);/* * Functions. */void delayMS(uint16_t ms){    uint16_t i=0,j=0;    for(i=0;i<1000;i++)    for(j=0;i<ms;j++);}int main(void){BOARD_Init();   app_tim_init();   app_uart_init(); LED1ON;    LED2ON;    LED3ON;    LED4ON;    printf(" 灵动PLUS-F5270开发板测试-安谋科技\r\n");    while (1)    {      if(USART_RX_STA ==1) { //app_uart_putstr((uint8_t *)app_uart_rx_buff);     if(app_uart_rx_buff[0] == 0xFF &&app_uart_rx_buff[1] == 0xFF &&app_uart_rx_buff[4] == 0XDD)    {     if((app_uart_rx_buff[2]&0x01) !=0) {LED1ON;printf("LED1 ON\r\n");}     else {LED1OFF;printf("LED1 OFF\r\n");}     if((app_uart_rx_buff[2]&0x02) !=0) {LED2ON;printf("LED2 ON\r\n");}      else {LED2OFF;printf("LED2 OFF\r\n");}     if((app_uart_rx_buff[2]&0x04) !=0) {LED3ON;printf("LED3 ON\r\n");}     else {LED3OFF;printf("LED3 OFF\r\n");}     if((app_uart_rx_buff[2]&0x08) !=0) {LED4ON;printf("LED4 ON\r\n");}     else {LED4OFF;printf("LED4 OFF\r\n");}  }      memset(app_uart_rx_buff,0,sizeof(app_uart_rx_buff));app_uart_rx_buff_idx = 0u;USART_RX_STA=0;   } }    }void app_uart_init(void){    UART_Init_Type uart_init;    /* Setup the xfer engine. */    uart_init.ClockFreqHz   = BOARD_DEBUG_UART_FREQ; /* 48mhz, APB2. */    uart_init.BaudRate      = BOARD_DEBUG_UART_BAUDRATE;    uart_init.WordLength    = UART_WordLength_8b;    uart_init.StopBits      = UART_StopBits_1;    uart_init.Parity = UART_Parity_None;    uart_init.XferMode      = UART_XferMode_RxTx;    uart_init.HwFlowControl = UART_HwFlowControl_None;    UART_Init(BOARD_DEBUG_UART_PORT, &uart_init);    /* Enable RX interrupt. */    UART_EnableInterrupts(BOARD_DEBUG_UART_PORT, UART_INT_RX_DONE, true);    NVIC_EnableIRQ(BOARD_DEBUG_UART_IRQn);    /* Enable UART. */    UART_Enable(BOARD_DEBUG_UART_PORT, true);}//串口接收 以OX0D 0X0A为结尾void app_uart_rx_isr_hook(void){    if ( (0u != (UART_INT_RX_DONE & UART_GetEnabledInterrupts(BOARD_DEBUG_UART_PORT))) && (0u != (UART_INT_RX_DONE & UART_GetInterruptStatus(BOARD_DEBUG_UART_PORT))) )    { app_uart_rx_buff[app_uart_rx_buff_idx] = UART_GetData(BOARD_DEBUG_UART_PORT); /* read data to clear rx interrupt bits. */ BOARD_LedOnTimeout(app_uart_rx_buff[app_uart_rx_buff_idx] % 4u + 1u);app_uart_rx_buff_idx++;if(app_uart_rx_buff[app_uart_rx_buff_idx-1] == 0x0A && app_uart_rx_buff[app_uart_rx_buff_idx-2] == 0x0D)    USART_RX_STA = 1;     }}/* BOARD_DEBUG_UART_IRQHandler ISR entry. */void BOARD_DEBUG_UART_IRQHandler(void){    app_uart_rx_isr_hook();}void app_uart_putstr(uint8_t *str){    while ((*str) != '\0')    { app_uart_putchar(*str); str++;    }}void app_uart_putchar(uint8_t c){    while ( 0u == (UART_STATUS_TX_EMPTY & UART_GetStatus(BOARD_DEBUG_UART_PORT)) )    {;}    UART_PutData(BOARD_DEBUG_UART_PORT, (uint8_t)(c));}/* Setup the timer. */void app_tim_init(void){    /* Set the counter counting step. */    TIM_Init_Type tim_init;    tim_init.ClockFreqHz = BOARD_TIM_FREQ;    tim_init.StepFreqHz = APP_TIM_UPDATE_PERIOD; /* 1s. */    tim_init.Period = APP_TIM_UPDATE_PERIOD - 1u;    tim_init.EnablePreloadPeriod = false;    tim_init.PeriodMode = TIM_PeriodMode_Continuous;    tim_init.CountMode = TIM_CountMode_Increasing;    TIM_Init(BOARD_TIM_PORT, &tim_init);    /* Enable interrupt. */    NVIC_EnableIRQ(BOARD_TIM_IRQn);    TIM_EnableInterrupts(BOARD_TIM_PORT, TIM_INT_UPDATE_PERIOD, true);    /* Start the counter. */    TIM_Start(BOARD_TIM_PORT);}/* TIM_BASIC Period timeout ISR. */void BOARD_TIM_IRQHandler(void){      static uint32_t i=0;    uint32_t flags = TIM_GetInterruptStatus(BOARD_TIM_PORT);    if ( 0u != (flags & TIM_STATUS_UPDATE_PERIOD ) ) /* Check update status. */    {      printf ("tim1Cnt = %d\r\n",i++);     if(i==100) i=0;    }    TIM_ClearInterruptStatus(BOARD_TIM_PORT, flags);}/* EOF. */

四 效果

用串口助手发送 FF FF 06 12 DD,其中06可以控制LED2与LED3点亮,LED1与LED4熄灭,并串口打印LED状态,定时器每秒打印信息也在串口助手中显示

【MM32F5270开发板试用】+串口中断接收与定时器

【MM32F5270开发板试用】+串口中断接收与定时器

五 结尾

MM32F5277E9P功能强大,本作只是小试牛刀,最近也一直在尝试多种国产芯片的测试与应用,后续可能测试在语音处理与BLDC电机上的应用。

麦克风网