【FM33LG0系列开发板测评】02.基础工程(LED、KEY、LPUART、LPTIM、SHELL)
[复制链接]
在准备好开发资料和搭建好开发环境后,我们就要来准备一个基础工程了;好的基础建设是搭建高楼大厦的关键,所以在基础工程中使用的原创的TASK任务管理调试方式,为了方便后期程序的调试、测试和演示,我们又添加了NR_MICRO_SHELL开源代码,可以使用串口终端方便的对接正在运行的程序;
本次的基础工程包含从零开始新建工程、LED、KEY、LPUART、LPTIM、SHELL等多个方面,所以篇幅有些长,但满满的都是干货,有启发和帮助哦……
从零开始新建立工程:
我们使用KEIL开发环境进行开发,所以提前安装好了芯片支持包;打开KEIL软件,点击菜单栏Project->New uVision Project...在弹出的对话框中选择工程存放的路径及工程名,点击保存,如下图所示:
在Select Device for Target窗口中选择芯片型FM33LG04X,然后在弹出的Manage Run-Time Environment窗口直接点击OK,新建的空工程就完成啦;如下图所示:
接下来我们需要往新建的空工程中划分程序结构以及添加程序源代码,点击工具栏上的Manage Project Items按钮,在弹出的窗口中进行操作,完成后点击OK,就完成啦;如下图所示:
最后就是对工程进行相应的配置了,点击工具栏上的Configure target options按钮,以弹出的窗口中进行相应的配置,如下图所示:
至此我们一个完整的工程就创建OK啦;对于官方的程序,我们提取了Device文件夹和MF-config文件夹使用,其它的文件夹以及程序源文件都是后期创建的。接下来就是对各个部分进行代码编写了。
程序就的大体功能就是创建LED任务,每间隔250ms闪烁一次,可以通过SHELL命令来控制时行闪烁和停止闪烁;创建KEY任务,进行按键识别,并打印出相应的按键事件/状态;使用LPTIM32作为TASK的定时器,写成任务的调度;通过LPUART0作为SHELL的调试接口,并进行SHELL程序移植;
LED原理图:
LED头文件:
/*******************************************************************************
* @file LED.h
* @author King
* [url=home.php?mod=space&uid=252314]@version[/url] V1.00
* [url=home.php?mod=space&uid=311857]@date[/url] 27-Nov-2021
* [url=home.php?mod=space&uid=159083]@brief[/url] ......
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __LED_H__
#define __LED_H__
#ifdef __cplusplus
extern "C" {
#endif
#undef EXTERN
#ifdef __LED_C__
#define EXTERN
#else
#define EXTERN extern
#endif
/* Includes ------------------------------------------------------------------*/
#include "config.h"
/* Exported constants --------------------------------------------------------*/
#define LED_NUMBER 4
#define LED1_GPIO GPIOC
#define LED1_PIN FL_GPIO_PIN_1
#define LED2_GPIO GPIOC
#define LED2_PIN FL_GPIO_PIN_0
#define LED3_GPIO GPIOD
#define LED3_PIN FL_GPIO_PIN_12
#define LED4_GPIO GPIOB
#define LED4_PIN FL_GPIO_PIN_15
/* Exported types ------------------------------------------------------------*/
typedef struct
{
GPIO_Type *GPIOx;
uint32_t pin;
} LED_TypeDef;
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
EXTERN void LED_Init(void);
EXTERN void LED_Toggle(void);
EXTERN void LED_SHELL_Handler(uint8_t Enable);
#ifdef __cplusplus
}
#endif
#endif
/******************* (C) COPYRIGHT 2021 *************************END OF FILE***/
LED源程序:
/*******************************************************************************
* @file LED.c
* @author King
* @version V1.00
* @date 27-Nov-2021
* @brief ......
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#define __LED_C__
/* Includes ------------------------------------------------------------------*/
#include "LED.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
LED_TypeDef LED[LED_NUMBER] =
{
{LED1_GPIO, LED1_PIN},
{LED2_GPIO, LED2_PIN},
{LED3_GPIO, LED3_PIN},
{LED4_GPIO, LED4_PIN},
};
uint8_t LED_ToggleEnable = 1;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported function prototypes ----------------------------------------------*/
/*******************************************************************************
* @brief
* @param
* @retval
* [url=home.php?mod=space&uid=1020061]@attention[/url] *******************************************************************************/
void LED_Init(void)
{
FL_GPIO_InitTypeDef GPIO_InitStruct;
for(uint8_t i = 0; i < LED_NUMBER; i++)
{
FL_GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.pin = LED[i].pin;
GPIO_InitStruct.mode = FL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
FL_GPIO_Init(LED[i].GPIOx, &GPIO_InitStruct);
FL_GPIO_SetOutputPin(LED[i].GPIOx, LED[i].pin);
}
TASK_Append(TASK_ID_LED, LED_Toggle, 250);
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void LED_Toggle(void)
{
if(LED_ToggleEnable)
{
for(uint8_t i = 0; i < LED_NUMBER; i++)
{
FL_GPIO_ToggleOutputPin(LED[i].GPIOx, LED[i].pin);
}
}
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void LED_SHELL_Handler(uint8_t Enable)
{
LED_ToggleEnable = Enable;
}
/******************* (C) COPYRIGHT 2021 *************************END OF FILE***/
KEY原理图:
KEY头文件:
/*******************************************************************************
* @file KEY.h
* @author King
* @version V1.00
* @date 27-Nov-2021
* @brief ......
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __KEY_H__
#define __KEY_H__
#ifdef __cplusplus
extern "C" {
#endif
#undef EXTERN
#ifdef __KEY_C__
#define EXTERN
#else
#define EXTERN extern
#endif
/* Includes ------------------------------------------------------------------*/
#include "config.h"
/* Exported constants --------------------------------------------------------*/
#define KEY_NUMBER 4
#define KEY1_GPIO GPIOD
#define KEY1_PIN FL_GPIO_PIN_9 /* WKUP8 */
#define KEY2_GPIO GPIOE
#define KEY2_PIN FL_GPIO_PIN_6 /* WKUP9 */
#define KEY3_GPIO GPIOE
#define KEY3_PIN FL_GPIO_PIN_7
#define KEY4_GPIO GPIOC
#define KEY4_PIN FL_GPIO_PIN_6 /* WKUP4 */
/* Exported types ------------------------------------------------------------*/
typedef struct
{
GPIO_Type *GPIOx;
uint32_t pin;
} KEY_TypeDef;
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
EXTERN void KEY_Init(void);
EXTERN void KEY_Scan(void);
#ifdef __cplusplus
}
#endif
#endif
/******************* (C) COPYRIGHT 2021 *************************END OF FILE***/
KEY源程序:
/*******************************************************************************
* @file KEY.c
* @author King
* @version V1.00
* @date 27-Nov-2021
* @brief ......
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#define __KEY_C__
/* Includes ------------------------------------------------------------------*/
#include "KEY.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
KEY_TypeDef KEY[KEY_NUMBER] =
{
{KEY1_GPIO, KEY1_PIN},
{KEY2_GPIO, KEY2_PIN},
{KEY3_GPIO, KEY3_PIN},
{KEY4_GPIO, KEY4_PIN},
};
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported function prototypes ----------------------------------------------*/
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void KEY_Init(void)
{
FL_GPIO_InitTypeDef GPIO_InitStruct;
for(uint8_t i = 0; i < KEY_NUMBER; i++)
{
FL_GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.pin = KEY[i].pin;
GPIO_InitStruct.mode = FL_GPIO_MODE_INPUT;
GPIO_InitStruct.pull = FL_ENABLE;
FL_GPIO_Init(KEY[i].GPIOx, &GPIO_InitStruct);
}
TASK_Append(TASK_ID_KEY, KEY_Scan, 10);
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void KEY_SubScan(uint8_t *State, uint8_t *Count, uint32_t Value, char *Name)
{
if(*State == 0)
{
if(Value == 0)
{
*Count += 1;
if(*Count > 5)
{
*Count = 0; *State = 1;
printf("\r\n%s Pressed...", Name);
}
}
else
{
*Count = 0;
}
}
else
{
if(Value != 0)
{
*Count += 1;
if(*Count > 5)
{
*Count = 0; *State = 0;
printf("\r\n%s Release\r\n", Name);
}
}
else
{
*Count = 0;
}
}
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void KEY_Scan(void)
{
static uint8_t KEY1_State = 0, KEY1_Count = 0;
static uint8_t KEY2_State = 0, KEY2_Count = 0;
static uint8_t KEY3_State = 0, KEY3_Count = 0;
static uint8_t KEY4_State = 0, KEY4_Count = 0;
KEY_SubScan(&KEY1_State, &KEY1_Count,
FL_GPIO_GetInputPin(KEY[0].GPIOx, KEY[0].pin),
"KEY1");
KEY_SubScan(&KEY2_State, &KEY2_Count,
FL_GPIO_GetInputPin(KEY[1].GPIOx, KEY[1].pin),
"KEY2");
KEY_SubScan(&KEY3_State, &KEY3_Count,
FL_GPIO_GetInputPin(KEY[2].GPIOx, KEY[2].pin),
"KEY3");
KEY_SubScan(&KEY4_State, &KEY4_Count,
FL_GPIO_GetInputPin(KEY[3].GPIOx, KEY[3].pin),
"KEY4");
}
/******************* (C) COPYRIGHT 2021 *************************END OF FILE***/
LPUART、SHELL移植头文件:
/*******************************************************************************
* @file LPUARTx.h
* @author King
* @version V1.00
* @date 27-Nov-2021
* @brief ......
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __LPUARTx_H__
#define __LPUARTx_H__
#ifdef __cplusplus
extern "C" {
#endif
#undef EXTERN
#ifdef __LPUARTx_C__
#define EXTERN
#else
#define EXTERN extern
#endif
/* Includes ------------------------------------------------------------------*/
#include "config.h"
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
EXTERN void LPUARTx_Init(LPUART_Type *LPUARTx);
#ifdef __cplusplus
}
#endif
#endif
/******************* (C) COPYRIGHT 2021 *************************END OF FILE***/
LPUART、SHELL移植源程序:LPUART的最大波特率为9600,在SHELL中实现了LED闪烁控制的实现部分
/*******************************************************************************
* @file LPUARTx.c
* @author King
* @version V1.00
* @date 27-Nov-2021
* @brief ......
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#define __LPUARTx_C__
/* Includes ------------------------------------------------------------------*/
#include "LPUARTx.h"
#include "nr_micro_shell.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported function prototypes ----------------------------------------------*/
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void LPUARTx_Init(LPUART_Type *LPUARTx)
{
FL_GPIO_InitTypeDef GPIO_InitStruct;
FL_LPUART_InitTypeDef LPUART_InitStruct;
if(LPUARTx == LPUART0)
{
FL_GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.pin = FL_GPIO_PIN_13;
GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_ENABLE;
GPIO_InitStruct.remapPin = FL_ENABLE;
FL_GPIO_Init(GPIOA, &GPIO_InitStruct);
FL_GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.pin = FL_GPIO_PIN_14;
GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_DISABLE;
GPIO_InitStruct.remapPin = FL_ENABLE;
FL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
if(LPUARTx == LPUART1)
{
FL_GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.pin = FL_GPIO_PIN_2;
GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_ENABLE;
GPIO_InitStruct.remapPin = FL_ENABLE;
FL_GPIO_Init(GPIOC, &GPIO_InitStruct);
FL_GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.pin = FL_GPIO_PIN_3;
GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_DISABLE;
GPIO_InitStruct.remapPin = FL_ENABLE;
FL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
FL_LPUART_StructInit(&LPUART_InitStruct);
LPUART_InitStruct.clockSrc = FL_CMU_LPUART_CLK_SOURCE_LSCLK; //时钟源LSCLK
// LPUART_InitStruct.clockSrc = FL_CMU_LPUART_CLK_SOURCE_RCHF; //时钟源RCHF
// LPUART_InitStruct.clockSrc = FL_CMU_LPUART_CLK_SOURCE_RCLF; //时钟源RCLF
LPUART_InitStruct.baudRate = FL_LPUART_BAUDRATE_9600;
LPUART_InitStruct.dataWidth = FL_LPUART_DATA_WIDTH_8B;
LPUART_InitStruct.stopBits = FL_LPUART_STOP_BIT_WIDTH_1B;
LPUART_InitStruct.parity = FL_LPUART_PARITY_NONE;
LPUART_InitStruct.transferDirection = FL_LPUART_DIRECTION_TX_RX;
FL_LPUART_Init(LPUARTx, &LPUART_InitStruct);
NVIC_DisableIRQ(LPUARTx_IRQn);
NVIC_SetPriority(LPUARTx_IRQn, 2);
NVIC_EnableIRQ(LPUARTx_IRQn);
FL_LPUART_EnableIT_RXBuffFull(LPUARTx);
printf("\r\n");
shell_init();
printf("\r\n");
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void LPUARTx_IRQHandler(void)
{
if((FL_ENABLE == FL_LPUART_IsEnabledIT_RXBuffFull(LPUART0)) &&
(FL_SET == FL_LPUART_IsActiveFlag_RXBuffFull(LPUART0)) )
{
shell(FL_LPUART_ReadRXBuff(LPUART0));
}
if((FL_ENABLE == FL_LPUART_IsEnabledIT_RXBuffFull(LPUART1)) &&
(FL_SET == FL_LPUART_IsActiveFlag_RXBuffFull(LPUART1)) )
{
FL_LPUART_WriteTXBuff(LPUART1, FL_LPUART_ReadRXBuff(LPUART1));
}
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
int fputc(int ch, FILE *f)
{
FL_LPUART_WriteTXBuff(LPUART0, (uint8_t)ch);
while(FL_LPUART_IsActiveFlag_TXShiftBuffEmpty(LPUART0) == 0);
FL_LPUART_ClearFlag_TXShiftBuffEmpty(LPUART0);
return ch;
}
/******************* (C) COPYRIGHT 2021 *************************END OF FILE***/
LPTIM、TASK移植头文件:
/*******************************************************************************
* @file LPTIMxx.h
* @author King
* @version V1.00
* @date 27-Nov-2021
* @brief ......
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __LPTIMxx_H__
#define __LPTIMxx_H__
#ifdef __cplusplus
extern "C" {
#endif
#undef EXTERN
#ifdef __LPTIMxx_C__
#define EXTERN
#else
#define EXTERN extern
#endif
/* Includes ------------------------------------------------------------------*/
#include "config.h"
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
EXTERN void LPTIM32_Init(void);
#ifdef __cplusplus
}
#endif
#endif
/******************* (C) COPYRIGHT 2021 *************************END OF FILE***/
LPTIM、TASK移植源程序:使用的官方程序库中已经使用SysTick定时器作为Delay函数的实现,所以我们需要重新初始化一个定时器来实现TASK的功能实现;
/*******************************************************************************
* @file LPTIMxx.c
* @author King
* @version V1.00
* @date 27-Nov-2021
* @brief ......
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#define __LPTIMxx_C__
/* Includes ------------------------------------------------------------------*/
#include "LPTIMxx.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
volatile uint32_t LPTIM32_Tick = 0;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported function prototypes ----------------------------------------------*/
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void LPTIM32_Init(void)
{
FL_LPTIM32_InitTypeDef LPTIM32_InitStruct;
FL_LPTIM32_StructInit(&LPTIM32_InitStruct);
LPTIM32_InitStruct.clockSource = FL_CMU_LPTIM32_CLK_SOURCE_APBCLK;
LPTIM32_InitStruct.mode = FL_LPTIM32_OPERATION_MODE_NORMAL;
LPTIM32_InitStruct.prescalerClockSource = FL_LPTIM32_CLK_SOURCE_INTERNAL;
LPTIM32_InitStruct.prescaler = FL_LPTIM32_PSC_DIV8;
LPTIM32_InitStruct.autoReload = 1000 - 1;
LPTIM32_InitStruct.onePulseMode = FL_LPTIM32_ONE_PULSE_MODE_CONTINUOUS;
LPTIM32_InitStruct.triggerEdge = FL_LPTIM32_ETR_TRIGGER_EDGE_RISING;
LPTIM32_InitStruct.countEdge = FL_LPTIM32_ETR_COUNT_EDGE_RISING;
FL_LPTIM32_Init(LPTIM32, &LPTIM32_InitStruct);
FL_LPTIM32_ClearFlag_Update(LPTIM32);
FL_LPTIM32_EnableIT_Update(LPTIM32);
NVIC_DisableIRQ(LPTIMx_IRQn);
NVIC_SetPriority(LPTIMx_IRQn, 2);
NVIC_EnableIRQ(LPTIMx_IRQn);
FL_LPTIM32_Enable(LPTIM32);
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void LPTIM_IRQHandler(void)
{
if(FL_LPTIM32_IsEnabledIT_Update(LPTIM32) &&
FL_LPTIM32_IsActiveFlag_Update(LPTIM32) )
{
LPTIM32_Tick++;
TASK_TimeSlice(LPTIM32_Tick);
FL_LPTIM32_ClearFlag_Update(LPTIM32);
}
}
/******************* (C) COPYRIGHT 2021 *************************END OF FILE***/
主程序:
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
int main(void)
{
MCU_Init();
KEY_Init();
LED_Init();
printf("\r\nDEMO V1.1 FM33LG0xx %s %s\r\n", __DATE__, __TIME__);
while(1)
{
TASK_Scheduling();
}
}
MCU初始化:
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void MCU_Init(void)
{
MF_Clock_Init();
MF_SystemClock_Config();
FL_Init();
MF_Config_Init();
LPTIM32_Init();
LPUARTx_Init(LPUART0);
}
调试运行:
将编写完成的程序进行编译,确认无误后下载程序;打开串口调试终端,配置为9600,N,8,1;程序在启动运行后,可以看到如下图的打印消息;然后依次按下KEY1~KEY4按键,并可看终端打印的消息;最后输入led 0和led 1来控制LED灯停止闪烁和恢复闪烁功能;如下图所示:
至此基础工程就完成了,后期可以在此工程的基础上添加、验证其它的功能了……
工程源代码:
FM33LG048_xld0932.zip
(356.05 KB, 下载次数: 49)
|