【灵动微电子MM32F5330测评】2.LED控制+按键检测

之前的帖子使用例程完成了简单的点灯测试,这次自己新建个工程来进行测试,完成基础题目中的这两个
 


先新建个文件夹,把固件包里的Device文件夹复制过去,另外再新建2个文件夹用来存放keil工程文件和代码文件
 


打开keil,选择新建工程,保存目录选择刚才新建的文件夹(MDK),芯片选择MM32F5333D7PV
 


接下来的页面直接点OK就行,按照自己的习惯添加好分组
 


将Device中的库文件添加进来
 


添加头文件路径
 


参考例程添加宏定义
 


修改linker
 


添加main.c
 


先简单写个流水灯测试一下,查看原理图确定LED使用的引脚
 


编写代码,LED是低电平点亮,初始化后输出高电平使LED初始状态为熄灭

复制

#include "hal_conf.h"



enum

{

    LED_NO_1 = 0,

    LED_NO_2,

    LED_NO_3,

    LED_NO_4,

    LED_NUM,

};



GPIO_TypeDef *led_ports[] = {GPIOB,GPIOB,GPIOC,GPIOC};

uint16_t led_pins[] = {GPIO_Pin_11,GPIO_Pin_10,GPIO_Pin_7,GPIO_Pin_6};



void led_init(void)

{

    uint8_t i = 0;

    GPIO_InitTypeDef cfg;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);

    GPIO_StructInit(&cfg);

    cfg.GPIO_Mode = GPIO_Mode_Out_PP;

    cfg.GPIO_Speed = GPIO_Speed_High;

    while(i < LED_NUM)

    {

        cfg.GPIO_Pin = led_pins[i];

        GPIO_Init(led_ports[i],&cfg);

        GPIO_SetBits(led_ports[i],led_pins[i]);

        i += 1;

    }

}



void led_toggle(uint8_t led)

{

    if(led < LED_NUM)

        GPIO_WriteBit(led_ports[led], led_pins[led], !GPIO_ReadOutputDataBit(led_ports[led], led_pins[led]));

}



void test_delay(void)

{

    uint32_t delay = 0x100000;

    while(delay--);

}



int main(void)

{

    led_init();



    while (1)

    {

        test_delay();

        led_toggle(LED_NO_1);

        test_delay();

        led_toggle(LED_NO_2);

        test_delay();

        led_toggle(LED_NO_3);

        test_delay();

        led_toggle(LED_NO_4);

    }

}


编译并烧录,运行效果
 


接下来实现按键检测,通过点击按键切换LED状态,先来看原理图
 


按键1是高电平触发,剩下三个都是低电平触发,并且按键2、3、4没有上拉电阻,在配置时需要开启内部上拉,机械按键按下时会产生抖动,这里对按下状态进行计时,按下状态持续20ms视为触发点击操作,然后切换对应LED的状态,代码如下

复制

GPIO_TypeDef *key_ports[] = {GPIOC,GPIOC,GPIOB,GPIOB};

uint16_t key_pins[] = {GPIO_Pin_4,GPIO_Pin_5,GPIO_Pin_1,GPIO_Pin_2};

const uint8_t key_press_states[] = {Bit_SET,Bit_RESET,Bit_RESET,Bit_RESET};

uint8_t key_press_counts[KEY_NUM];

void keys_init(void)

{

    GPIO_InitTypeDef cfg;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);

    GPIO_StructInit(&cfg);

    cfg.GPIO_Mode = GPIO_Mode_IPU;

    cfg.GPIO_Pin = GPIO_Pin_5;

    GPIO_Init(GPIOC,&cfg);

    cfg.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;

    GPIO_Init(GPIOB,&cfg);

    

    cfg.GPIO_Mode = GPIO_Mode_FLOATING;

    cfg.GPIO_Pin = GPIO_Pin_4;

    GPIO_Init(GPIOC,&cfg);

    memset(key_press_counts,0,KEY_NUM);

}



void key_state_check(void)

{

    uint8_t i = 0;

    while(i < KEY_NUM)

    {

        if(GPIO_ReadInputDataBit(key_ports[i], key_pins[i]) == key_press_states[i])

        {

            if(key_press_counts[i] < 0xFF)

                key_press_counts[i] += 1;

        }

        else

            key_press_counts[i] = 0;

        if(key_press_counts[i] == 20)

            led_toggle(i);

        i += 1;

    }

}



int main(void)

{

    led_init();

    keys_init();

    while (1)

    {

        YUYY_DelayMs(1);

        key_state_check();

    }

}


运行效果
 


上面是通过不断查询io电平来实现的按键检测,接下来通过中断来进行按键检测,所有 IO 引脚可以连接到 16 个外部中断线,对应关系如下图
 


 


配置按键1为上升沿触发,其他3个为下降沿触发,代码如下

复制

void exit_init(void)

{

    EXTI_InitTypeDef exit_cfg;

    NVIC_InitTypeDef nvic_cfg;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource4);

    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource5);

    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource1);

    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource2);

    EXTI_StructInit(&exit_cfg);

    

    exit_cfg.EXTI_Line    = EXTI_Line4;

    exit_cfg.EXTI_Mode    = EXTI_Mode_Interrupt;

    exit_cfg.EXTI_Trigger = EXTI_Trigger_Rising;

    exit_cfg.EXTI_LineCmd = ENABLE;

    EXTI_Init(&exit_cfg);

    nvic_cfg.NVIC_IRQChannel = EXTI4_IRQn;

    nvic_cfg.NVIC_IRQChannelPreemptionPriority = 0;

    nvic_cfg.NVIC_IRQChannelSubPriority = 1;

    nvic_cfg.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&nvic_cfg);

    

    exit_cfg.EXTI_Line    = EXTI_Line5;

    exit_cfg.EXTI_Trigger = EXTI_Trigger_Falling;

    EXTI_Init(&exit_cfg);

    nvic_cfg.NVIC_IRQChannel = EXTI9_5_IRQn;

    NVIC_Init(&nvic_cfg);

    

    exit_cfg.EXTI_Line    = EXTI_Line1;

    exit_cfg.EXTI_Trigger = EXTI_Trigger_Falling;

    EXTI_Init(&exit_cfg);

    nvic_cfg.NVIC_IRQChannel = EXTI1_IRQn;

    NVIC_Init(&nvic_cfg);

    

    exit_cfg.EXTI_Line    = EXTI_Line2;

    exit_cfg.EXTI_Trigger = EXTI_Trigger_Falling;

    EXTI_Init(&exit_cfg);

    nvic_cfg.NVIC_IRQChannel = EXTI2_IRQn;

    NVIC_Init(&nvic_cfg);

}



void EXTI4_IRQHandler(void)

{

    if (SET == EXTI_GetITStatus(EXTI_Line4) && GPIO_ReadInputDataBit(key_ports[KEY_NO_1], key_pins[KEY_NO_1]) == key_press_states[KEY_NO_1])

    {

        led_toggle(LED_NO_1);

        EXTI_ClearITPendingBit(EXTI_Line4);

    }

}

void EXTI9_5_IRQHandler(void)

{

    if (SET == EXTI_GetITStatus(EXTI_Line5) && GPIO_ReadInputDataBit(key_ports[KEY_NO_2], key_pins[KEY_NO_2]) == key_press_states[KEY_NO_2])

    {

        led_toggle(LED_NO_2);

        EXTI_ClearITPendingBit(EXTI_Line5);

    }

}

void EXTI1_IRQHandler(void)

{

    if (SET == EXTI_GetITStatus(EXTI_Line1) && GPIO_ReadInputDataBit(key_ports[KEY_NO_3], key_pins[KEY_NO_3]) == key_press_states[KEY_NO_3])

    {

        led_toggle(LED_NO_3);

        EXTI_ClearITPendingBit(EXTI_Line1);

    }

}

void EXTI2_IRQHandler(void)

{

    if (SET == EXTI_GetITStatus(EXTI_Line2) && GPIO_ReadInputDataBit(key_ports[KEY_NO_4], key_pins[KEY_NO_4]) == key_press_states[KEY_NO_4])

    {

        led_toggle(LED_NO_4);

        EXTI_ClearITPendingBit(EXTI_Line2);

    }

}



int main(void)

{

    led_init();

    keys_init();

    exit_init();

    while (1)

    {

    }

}


运行效果和轮询的类似,这里就不再重复上图了件
---------------------
作者:yuyy1989
链接:https://bbs.21ic.com/icview-3384992-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值