1907|5

208

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

[极海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的,我想问题的问题是:

  1. 是不是因为芯片内部已经合封了2MB SDRAM,所以在产品信息中才注明不支持SDRAM的?
  2. 芯片合封了2MB SDRAM,这么激动人心的资源,我们该如何使用呢?

最新回复

问题1:极海APM32E103系列MCU,提供了不同引脚资源,引脚数覆盖48~144pin,在选择最大引脚资源的产品型号时可以支持外扩SDRAM使用。问题2:在极海APM32E103系列MCU的基础上提供了合封SDRAM的型号,扩展片内存储空间、便于工程师进行板级开发,可以下载官网对应的产品数据手册了解合封产品说明  详情 回复 发表于 2022-9-21 17:19
点赞 关注
个人签名We are a team and we work as a team !
 
 

回复
举报

7671

帖子

2

TA的资源

五彩晶圆(高级)

沙发
 

这又是那个厂的?这几年做32的真是雨后春笋,不知道谁笑到最后。

点评

极海哈 大浪淘沙,是金子总会发光的……  详情 回复 发表于 2022-9-16 17:34
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 
 

回复

7048

帖子

11

TA的资源

版主

板凳
 

这个板子支持DAP仿真器吗?Jlink那是土豪的高配呀!

点评

必须支持  详情 回复 发表于 2022-9-16 17:34
 
 
 

回复

208

帖子

0

TA的资源

纯净的硅(初级)

4
 
freebsder 发表于 2022-9-15 22:50 这又是那个厂的?这几年做32的真是雨后春笋,不知道谁笑到最后。

极海哈

大浪淘沙,是金子总会发光的……

个人签名We are a team and we work as a team !
 
 
 

回复

208

帖子

0

TA的资源

纯净的硅(初级)

5
 
lugl4313820 发表于 2022-9-16 16:30 这个板子支持DAP仿真器吗?Jlink那是土豪的高配呀!

必须支持

个人签名We are a team and we work as a team !
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(中级)

6
 
问题1:极海APM32E103系列MCU,提供了不同引脚资源,引脚数覆盖48~144pin,在选择最大引脚资源的产品型号时可以支持外扩SDRAM使用。问题2:在极海APM32E103系列MCU的基础上提供了合封SDRAM的型号,扩展片内存储空间、便于工程师进行板级开发,可以下载官网对应的产品数据手册了解合封产品说明
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表