[极海M3内核 APM32E103VET6S MINI开发板]01.GPIO的基础LED&KEY功能
[复制链接]
开箱
中秋佳节就收到了极海的APM32E103VCS MINIBOARD开发板,包装简洁了些,但开发板还是一样的香!板载的APM32E103VET6S主控芯片是基于32位Arm Cortex-M3内核的微控制器,最高工作频率可达到120MHz,工作温度更是能达到零下40摄氏度以及105摄氏度,满足了对不同严苛工作环境的需求。该芯片还具有丰富的片上资源,512KB FLASH、128KB SRAM、ADC、CAN、CRC、DAC、EMMC、FPU、I2C、RTC、SDIO、SPI/I2S、TIMER、UART/USART、USBD、WDT等等。
硬件环境准备
除了APM32E103VCS MINIBOARD开发板之外,还准备了J-LINK调试下载工具和USB转TTL工具。
软件环境准备
当前IAR已经全面支持极海APM32系列的MCU,但作者还是习惯用KEIL MDK集成开发环境来开发,另外再准备一个串口调试终端软件,这个选择有很多了,根据人个喜好随意选择。
相关资料准备
数据手册:
APM32E103xCxE数据手册 V1.3.pdf
(4.33 MB, 下载次数: 2)
用户手册:
APM32E103xCxE用户手册 V1.2.pdf
(20.53 MB, 下载次数: 2)
使用说明:
APM32E103VET6S MINI使用说明书 V1.0.pdf
(677.56 KB, 下载次数: 1)
硬件原理图:
APM32E103VET6S MINIBOARD V1.0.pdf
(30.63 KB, 下载次数: 0)
APM32E10x_SDK:https://www.geehy.com/apm32?id=45
安装KEIL Pack支持包
在使用极海MCU进行开发时,需要先安装KEIL Pack芯片支持包,这样在创建工程时才能够选择到极海对应的芯片型号,进行后续的配置和开发工作。在上述相关资料中APM32E10x_SDK\Package包含了最新的版本Geehy.APM32E1xx_DFP.1.0.1,我们双击这个文件进行安装,如下图所示:
新建工程
通过官方提供的一芯片底层库程序创建一个基础工程,实现LED闪烁、KEY按键识别、USART实现printf的功能,对于系统任务的调度我们使用开源的MultiTimer组件,而按键识别我们使用开源的MultiButton组件,具体如下所示:
创建工程
配置工程
编写代码
/*******************************************************************************
* [url=home.php?mod=space&uid=159083]@brief[/url] * @param
* @retval
* [url=home.php?mod=space&uid=1020061]@attention[/url] *******************************************************************************/
void LED_MultiTimerCallback(MultiTimer *timer, void *userData)
{
GPIO_WriteOutputPort(GPIOB, GPIO_ReadOutputPort(GPIOB)
^ (GPIO_PIN_8 | GPIO_PIN_9));
MultiTimerStart(&LED_MultiTimer, 250, LED_MultiTimerCallback, "LED");
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void LED_Init(void)
{
GPIO_Config_T GPIO_ConfigStruct;
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOB);
GPIO_ConfigStructInit(&GPIO_ConfigStruct);
GPIO_ConfigStruct.pin = GPIO_PIN_8 | GPIO_PIN_9;
GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
GPIO_ConfigStruct.mode = GPIO_MODE_OUT_PP;
GPIO_Config(GPIOB, &GPIO_ConfigStruct);
GPIO_WriteBitValue(GPIOB, GPIO_PIN_8, BIT_SET);
GPIO_WriteBitValue(GPIOB, GPIO_PIN_9, BIT_RESET);
MultiTimerStart(&LED_MultiTimer, 250, LED_MultiTimerCallback, "LED");
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
uint8_t read_pin_level(uint8_t pin_id)
{
if(pin_id == 0)
{
return GPIO_ReadInputBit(GPIOA, GPIO_PIN_0);
}
else
{
return GPIO_ReadInputBit(GPIOA, GPIO_PIN_1);
}
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void KEY_Handler(void *btn)
{
Button *key = btn;
switch(key->event)
{
case PRESS_DOWN:
printf("\r\nKEY%d : PRESS_DOWN", key->button_id);
break;
case PRESS_UP:
printf("\r\nKEY%d : PRESS_UP", key->button_id);
break;
case SINGLE_CLICK:
printf("\r\nKEY%d : SINGLE_CLICK", key->button_id);
break;
case DOUBLE_CLICK:
printf("\r\nKEY%d : DOUBLE_CLICK", key->button_id);
break;
case LONG_PRESS_START:
printf("\r\nKEY%d : LONG_PRESS_START", key->button_id);
break;
case LONG_PRESS_HOLD:
printf("\r\nKEY%d : LONG_PRESS_HOLD", key->button_id);
break;
default:
break;
}
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void KEY_RepeatHandler(void *btn)
{
Button *key = btn;
printf("\r\nKEY%d : PRESS_REPEAT", key->button_id);
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void KEY_MultiTimerCallback(MultiTimer *timer, void *userData)
{
button_ticks();
MultiTimerStart(&KEY_MultiTimer, 5, KEY_MultiTimerCallback, "KEY");
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void KEY_Init(void)
{
GPIO_Config_T GPIO_ConfigStruct;
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
GPIO_ConfigStructInit(&GPIO_ConfigStruct);
GPIO_ConfigStruct.pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_ConfigStruct.mode = GPIO_MODE_IN_PU;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
button_init( &btnKEY, read_pin_level, BIT_RESET, 1);
button_attach(&btnKEY, SINGLE_CLICK, KEY_Handler);
button_start( &btnKEY);
MultiTimerStart(&KEY_MultiTimer, 5, KEY_MultiTimerCallback, "KEY");
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
uint64_t PlatformTicksFunction(void)
{
return SysTick_Tick;
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void USART1_Init(void)
{
GPIO_Config_T GPIO_ConfigStruct;
USART_Config_T USART_ConfigStruct;
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_USART1);
USART_ConfigStructInit(&USART_ConfigStruct);
USART_ConfigStruct.baudRate = 115200;
USART_ConfigStruct.wordLength = USART_WORD_LEN_8B;
USART_ConfigStruct.stopBits = USART_STOP_BIT_1;
USART_ConfigStruct.parity = USART_PARITY_NONE;
USART_ConfigStruct.mode = USART_MODE_TX_RX;
USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
USART_Config(USART1, &USART_ConfigStruct);
USART_EnableInterrupt(USART1, USART_INT_RXBNE);
NVIC_EnableIRQRequest(USART1_IRQn, 0, 1);
USART_Enable(USART1);
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
GPIO_ConfigStructInit(&GPIO_ConfigStruct);
GPIO_ConfigStruct.pin = GPIO_PIN_9;
GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
GPIO_ConfigStruct.mode = GPIO_MODE_AF_PP;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
GPIO_ConfigStructInit(&GPIO_ConfigStruct);
GPIO_ConfigStruct.pin = GPIO_PIN_10;
GPIO_ConfigStruct.mode = GPIO_MODE_IN_FLOATING;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void USART1_IRQHandler(void)
{
if(USART_ReadIntFlag(USART1, USART_INT_RXBNE) == SET)
{
USART_TxData(USART1, USART_RxData(USART1));
while(USART_ReadStatusFlag(USART1, USART_FLAG_TXBE) == RESET);
}
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void USART2_Init(void)
{
GPIO_Config_T GPIO_ConfigStruct;
USART_Config_T USART_ConfigStruct;
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_USART2);
USART_ConfigStructInit(&USART_ConfigStruct);
USART_ConfigStruct.baudRate = 115200;
USART_ConfigStruct.wordLength = USART_WORD_LEN_8B;
USART_ConfigStruct.stopBits = USART_STOP_BIT_1;
USART_ConfigStruct.parity = USART_PARITY_NONE;
USART_ConfigStruct.mode = USART_MODE_TX_RX;
USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
USART_Config(USART2, &USART_ConfigStruct);
USART_EnableInterrupt(USART2, USART_INT_RXBNE);
NVIC_EnableIRQRequest(USART2_IRQn, 0, 0);
USART_Enable(USART2);
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
GPIO_ConfigStructInit(&GPIO_ConfigStruct);
GPIO_ConfigStruct.pin = GPIO_PIN_2;
GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
GPIO_ConfigStruct.mode = GPIO_MODE_AF_PP;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
GPIO_ConfigStructInit(&GPIO_ConfigStruct);
GPIO_ConfigStruct.pin = GPIO_PIN_3;
GPIO_ConfigStruct.mode = GPIO_MODE_IN_FLOATING;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void USART2_IRQHandler(void)
{
if(USART_ReadIntFlag(USART2, USART_INT_RXBNE) == SET)
{
USART_TxData(USART2, USART_RxData(USART2));
while(USART_ReadStatusFlag(USART2, USART_FLAG_TXBE) == RESET);
}
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
int main(void)
{
uint32_t PCLK1 = 0, PCLK2 = 0;
MultiTimerInstall(PlatformTicksFunction);
SysTick_Config(SystemCoreClock / 0x03E8);
USART1_Init();
USART2_Init();
KEY_Init();
LED_Init();
printf("\r\nAPM32E103VCS MINIBOARD V1.0 %s %s\r\n", __DATE__, __TIME__);
printf("\r\nSYSCLKFreq : %dHz", RCM_ReadSYSCLKFreq());
printf("\r\nHCLKFreq : %dHz", RCM_ReadHCLKFreq());
RCM_ReadPCLKFreq(&PCLK1, &PCLK2);
printf("\r\nPCLK1Freq : %dHz", PCLK1);
printf("\r\nPCLK2Freq : %dHz", PCLK2);
printf("\r\nADCCLKFreq : %dHz", RCM_ReadADCCLKFreq());
printf("\r\n");
while(1)
{
MultiTimerYield();
}
}
运行结果
运行演示
100
答疑解惑
APM32E103VCS MINIBOARD开发板上板载的是LQFP封装的APM32E103VET6S,在数据手册中产品信息章节提到该芯片支持存储控制器(EMMC)功能,但不支持SDRAM,如下图所示:
但在数据手册中订货信息章节给出了产品的命令规则,如下所示:
也就是说板载的APM32E103VET6S这颗芯片是合封了2MB SDRAM的,我想问题的问题是:
- 是不是因为芯片内部已经合封了2MB SDRAM,所以在产品信息中才注明不支持SDRAM的?
- 芯片合封了2MB SDRAM,这么激动人心的资源,我们该如何使用呢?
|