[FM33LG0 series development board evaluation] 02. Basic engineering (LED, KEY, LPUART, LPTIM, SHELL)
[Copy link]
After preparing the development materials and setting up the development environment, we will prepare a basic project; good infrastructure is the key to building a high-rise building, so the original TASK task management debugging method used in the basic project, in order to facilitate the debugging, testing and demonstration of the later program, we have added the NR_MICRO_SHELL open source code, which can use the serial terminal to conveniently connect to the running program;
This basic project includes building a new project from scratch, LED, KEY, LPUART, LPTIM, SHELL and other aspects, so the article is a bit long, but it is full of practical information, inspiring and helpful...
Create a new project from scratch:
We use the KEIL development environment for development, so the chip support package has been installed in advance; open the KEIL software, click the menu bar Project->New uVision Project... In the pop-up dialog box, select the project storage path and project name, and click Save, as shown in the following figure:
In the Select Device for Target window, select the chip type FM33LG04X, and then click OK in the pop-up Manage Run-Time Environment window. The newly created empty project is completed; as shown below:
Next, we need to divide the program structure and add program source code to the newly created empty project. Click the Manage Project Items button on the toolbar, perform the operation in the pop-up window, and click OK when completed. It's done; as shown in the following figure:
Finally, configure the project accordingly. Click the Configure target options button on the toolbar to make corresponding configurations in the pop-up window, as shown in the following figure:
[attach ]575257[/attach]
At this point, we have created a complete project; for the official program, we extracted the Device folder and MF-config folder for use, and the other folders and program source files were created later. The next step is to write code for each part.
The general function of the program is to create an LED task, which flashes once every 250ms. The flashing can be controlled by SHELL commands; create a KEY task, identify the key, and print out the corresponding key events/status; use LPTIM32 as the timer of TASK and write the task schedule; use LPUART0 as the debugging interface of SHELL and transplant the SHELL program;
LED schematic diagram:
LED header file:
/*******************************************************************************
* @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 source program:
/*******************************************************************************
* @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 schematic diagram:
KEY header file:
/*******************************************************************************
* @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 source program:
/*******************************************************************************
* @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 transplant header files:
/*******************************************************************************
* @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 transplant source program: The maximum baud rate of LPUART is 9600 , and the LED flashing control is implemented in SHELL
/*******************************************************************************
* @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 transplant header files:
/*******************************************************************************
* @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 transplant source program: The official program library used has used the SysTick timer as the implementation of the Delay function , so we need to reinitialize a timer to implement the TASK function;
/*******************************************************************************
* @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***/
Main program:
/*******************************************************************************
* @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 initialization:
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void MCU_Init(void)
{
MF_Clock_Init();
MF_SystemClock_Config();
FL_Init();
MF_Config_Init();
LPTIM32_Init();
LPUARTx_Init(LPUART0);
}
Debug run:
Compile the completed program and download it after confirming that it is correct; open the serial port debugging terminal and configure it as 9600, N, 8, 1; after the program starts running, you can see the printed message as shown in the figure below; then press the KEY1~KEY4 buttons in sequence, and you can see the message printed by the terminal; finally, enter led 0 and led 1 to control the LED light to stop flashing and resume flashing function; as shown in the figure below:
At this point, the basic project is completed. Later, other functions can be added and verified based on this project...
Project source code:
FM33LG048_xld0932.zip
(356.05 KB, downloads: 49)
|