362|0

510

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

【匠芯创D133CBS】--3.按键控灯 [复制链接]

 
本帖最后由 dirty 于 2024-8-17 11:35 编辑

      本篇讲述按键驱动实现与消息队列发送与接收控灯。

 

一.硬件原理

      匠芯创D133CBV-QFN88-V1-2 原理图可查到唤醒按键如下,使用到引脚为PD15.

 

图1:唤醒按键原理

      LED引脚如前篇所述,使用PD0脚。

 

二.代码准备

1.scons --menuconfig配置使能RT-Thread内核

2.按键初始化,这里使用上升沿触发,即按键松开后进入key_irq_handler回调。按键、LED引脚宏定义。

#define LED_PIN             "PD.0"         
#define KEY_PIN             "PD.15" 

void app_key_init(void)
{
    // 1.get pin number
    static u32 pin = 0;

    pin = rt_pin_get(KEY_PIN);
    printf("Key pin%d\n",pin);
    // 2.set pin mode to Input-PullUp
    rt_pin_mode(pin, PIN_MODE_INPUT_PULLUP);

    // 3.attach irq handler
    rt_pin_attach_irq(pin, PIN_IRQ_MODE_RISING,key_irq_handler, &pin);//PIN_IRQ_MODE_RISING_FALLING

    // 4.enable pin irq
    rt_pin_irq_enable(pin, PIN_IRQ_ENABLE); 

    rt_kprintf("%s\r\n",__func__);   

}

3.创建消息队列,数据以结构体发送与接收。编写消息队列发送函数。

typedef struct 
{
    uint16_t    msg_len;
    uint8_t     led_value;
}msg_control;


/* 消息队列控制块 */
static struct rt_messagequeue user_mq;
/* 消息队列中用到的放置消息的内存池 */
static rt_uint8_t msg_pool[2048];

msg_control msg_control_t;

//消息队列发送
void app_msg_send(uint8_t *buff,uint16_t len)
{
    rt_err_t ret;
    ret = rt_mq_send(&user_mq,buff,len);
    if (ret != RT_EOK) 
    {
        rt_kprintf("rt_mq_send fail. ret:%d\n",ret);
    }

}

void app_user_mq_init(void)
{
    rt_err_t ret;

    /* 初始化消息队列 */
    ret = rt_mq_init(&user_mq,
                        "user_mq",
                        &msg_pool,               /* 内存池指向msg_pool */
                        sizeof(msg_control_t),                          /* 每个消息的大小是 1 字节 */
                        sizeof(msg_pool),           /* 内存池的大小是msg_pool的大小 */
                        RT_IPC_FLAG_FIFO);          /* 如果有多个线程等待,按照先来先得到的方法分配消息 */
    if (ret != RT_EOK)
    {
        rt_kprintf("init user message queue failed.\n");
    }
}

4.在按键中断回调实现led状态值取反,并消息队列发送

static void key_irq_handler(void *args)

{

    unsigned int ret;

    u32 pin = *((u32 *)(args));



    printf("Key INT\r\n");

    msg_control_t.msg_len=sizeof(msg_control_t);

    msg_control_t.led_value=!msg_control_t.led_value;

    app_msg_send(&msg_control_t,sizeof(msg_control_t));

    // times_enter_irq++;

    // hal_gpio_get_value(GPIO_GROUP(pin), GPIO_GROUP_PIN(pin), &ret);

    // printf("gpio group_%d_pin_%d read = %d\n", GPIO_GROUP(pin), GPIO_GROUP_PIN(pin), ret);

}

5.在任务里接收消息队列,并按LED状态值控制LED

void led_thread_entry(void *parameter)
{

    int pin;  
    msg_control msg_control_p;
    while(1)
    {
		//消息队列接收
        if(rt_mq_recv(&user_mq, &msg_control_p, sizeof(msg_control_p), RT_WAITING_FOREVER)==RT_EOK)
        {
            rt_kprintf("Receive msg quene\r\n");
            rt_kprintf("msg_len:%d,led_value:%d\r\n",msg_control_p.msg_len,msg_control_p.led_value);

            pin = rt_pin_get(LED_PIN);
            rt_pin_write(pin, msg_control_p.led_value);

        }
        
    }
}

 

三.测验

      编译烧录,按一下WAKEUP按键,LED灯取反一次亮/灭 如视频,串口日志如下

图3:按键控灯日志

      至此,实现按键驱动及通过消息队列发送接收同步控制LED.

 

key_control_led

 

点赞 关注
个人签名

保持热爱

 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
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
快速回复 返回顶部 返回列表