szit · 2022年08月15日 · 江苏

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

一 准备工作

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。
MM01.png

二 准备实验的功能

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秒,每秒串口打印指定内容;
MM06.png
MM05.png

三 实现过程相关代码

以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状态,定时器每秒打印信息也在串口助手中显示MM02.png
MM03.jpg

五 结尾

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

推荐阅读
关注数
6108
内容数
272
灵动MM32 MCU相关技术知识,欢迎关注~
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息