【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。
二 准备实验的功能
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状态,定时器每秒打印信息也在串口助手中显示
五 结尾
MM32F5277E9P功能强大,本作只是小试牛刀,最近也一直在尝试多种国产芯片的测试与应用,后续可能测试在语音处理与BLDC电机上的应用。