一 准备工作
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 <stdio.h>
#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_IRQn TIM1_UP_IRQn
#define BOARD_TIM_IRQHandler TIM1_UP_IRQHandler
#define BOARD_TIM_FREQ CLOCK_SYS_FREQ
void 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 <stdint.h>
#include <stdio.h>
#include "board_init.h"
/*
* Macros.
*/
#define APP_UART_RX_BUFF_LEN 8u
uint16_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电机上的应用。