(一)STM32L4(RT- Thread)——电机和蜂鸣器,独立按键,LED灯

(一)STM32L4(RT- Thread)——电机和蜂鸣器,独立按键,LED灯

LED灯

学习目标

今天我们来学习点亮潘多拉开发板的LED灯,同时也是首次在项目中使用RT - Thread操作系统,目前感觉变化不大,和裸机开发很像,可能到后面才能发现有不同之处吧,值得一提的是 RT - Thread 的日志系统通过串口打印信息到电脑,这一点还是比较好玩的,好了,让我们进入知识的讲解。

实验结果

WeChat

WeChat

内容

说实话点亮LED灯还是比较简单的,就是通过给高低电平来控制亮灭,这部分就不详细介绍了,主要来介绍一下RT - Thread。

代码

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>

#define DBG_TAG "main"
#define DBG_LVL         DBG_LOG
#include <rtdbg.h>

/* 配置 LED 灯引脚 */          
#define LED_PIN              PIN_LED_R

int main(void)
{
    unsigned int count = 1;

    /* 设置 LED 引脚为输出模式 */
    rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);

    while (count > 0)
    {
        /* LED 灯亮 */
        rt_pin_write(LED_PIN, PIN_LOW);
        LOG_D("led on, count: %d", count);
        rt_thread_mdelay(500);

        /* LED 灯灭 */
        rt_pin_write(LED_PIN, PIN_HIGH);
        LOG_D("led off");
        rt_thread_mdelay(500);

        count++;
    }

    return 0;
}
void rt_pin_mode(rt_base_t pin, rt_base_t mode)

在这里插入图片描述

有关这个函数 ,我们来简单的介绍一下,学习途径当然是官方手册啦,这是可以设置的参数。

rt_pin_write(LED_PIN, PIN_LOW);

​ 这个就是设置低电平,比较简单。

LOG_D("led on, count: %d", count);
LOG_D("led off");

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TFOnldBN-1673401750609)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]

​ 这个是通过串口来打印,结果如下。

在这里插入图片描述


​ 接下来我们来看一看RGB灯的实现,如果理解了上面的代码,就比较好理解。

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

/* 定义 LED 亮灭电平 */
#define LED_ON  (0)
#define LED_OFF (1)

/* 定义 8 组 LED 闪灯表,其顺序为 R G B */
static const rt_uint8_t _blink_tab[][3] =
{
    {LED_ON, LED_ON, LED_ON},
    {LED_OFF, LED_ON, LED_ON},
    {LED_ON, LED_OFF, LED_ON},
    {LED_ON, LED_ON, LED_OFF},
    {LED_OFF, LED_OFF, LED_ON},
    {LED_ON, LED_OFF, LED_OFF},
    {LED_OFF, LED_ON, LED_OFF},
    {LED_OFF, LED_OFF, LED_OFF},
};

int main(void)
{
    unsigned int count = 1;
    unsigned int group_num = sizeof(_blink_tab)/sizeof(_blink_tab[0]);
    unsigned int group_current;

    /* 设置 RGB 灯引脚为输出模式 */
    rt_pin_mode(PIN_LED_R, PIN_MODE_OUTPUT);
    rt_pin_mode(PIN_LED_G, PIN_MODE_OUTPUT);
    rt_pin_mode(PIN_LED_B, PIN_MODE_OUTPUT);

    while (count > 0)
    {
        /* 获得组编号 */
        group_current = count % group_num;

        /* 控制 RGB 灯 */
        rt_pin_write(PIN_LED_R, _blink_tab[group_current][0]);
        rt_pin_write(PIN_LED_G, _blink_tab[group_current][1]);
        rt_pin_write(PIN_LED_B, _blink_tab[group_current][2]);

        /* 输出 LOG 信息 */
        LOG_D("group: %d | red led [%-3.3s] | green led [%-3.3s] | blue led [%-3.3s]",
            group_current,
            _blink_tab[group_current][0] == LED_ON ? "ON" : "OFF",
            _blink_tab[group_current][1] == LED_ON ? "ON" : "OFF",
            _blink_tab[group_current][2] == LED_ON ? "ON" : "OFF");

        /* 延时一段时间 */
        rt_thread_mdelay(500);
        count++;
    }
    return 0;
}

在这里插入图片描述

​ 比较简单,就不介绍了。

总结

​ 总体来说目前还是比较简单的使用,遇到问题也可以自行查找资料解决,期待以后关于RT - Thread的学习。

独立按键

学习目标

​ 今天要介绍的是有关独立按键的知识,简单来说,非常简单,所以就不详细介绍了。

成果展示

独立按键

硬件知识

在这里插入图片描述

代码

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

int main(void)
{
    unsigned int count = 1;

    /* 设置 RGB 灯引脚的模式为输出模式 */
    rt_pin_mode(PIN_LED_R, PIN_MODE_OUTPUT);
	rt_pin_mode(PIN_LED_G, PIN_MODE_OUTPUT);
	rt_pin_mode(PIN_LED_B, PIN_MODE_OUTPUT);
    /* 设置 KEY 引脚的模式为输入模式 */
    rt_pin_mode(PIN_KEY0, PIN_MODE_INPUT);
	rt_pin_mode(PIN_KEY1, PIN_MODE_INPUT);
	rt_pin_mode(PIN_KEY2, PIN_MODE_INPUT);

    while (count > 0)
    {
        /* 读取按键 KEY 的引脚状态 */
        if (rt_pin_read(PIN_KEY0) == PIN_LOW)
        {
            rt_thread_mdelay(50);
            if (rt_pin_read(PIN_KEY0) == PIN_LOW)
            {
                /* 按键已被按下,输出 log,点亮 LED 灯 */
                LOG_D("KEY0 pressed!");
                rt_pin_write(PIN_LED_R, PIN_LOW);
            }
        }
		else if (rt_pin_read(PIN_KEY1) == PIN_LOW)
        {
            rt_thread_mdelay(50);
            if (rt_pin_read(PIN_KEY1) == PIN_LOW)
            {
                /* 按键已被按下,输出 log,点亮 LED 灯 */
                LOG_D("KEY1 pressed!");
				rt_pin_write(PIN_LED_G, PIN_LOW);
            }
        }
		else if (rt_pin_read(PIN_KEY2) == PIN_LOW)
        {
            rt_thread_mdelay(50);
            if (rt_pin_read(PIN_KEY2) == PIN_LOW)
            {
                /* 按键已被按下,输出 log,点亮 LED 灯 */
                LOG_D("KEY2 pressed!");
				rt_pin_write(PIN_LED_B, PIN_LOW);
            }
        }
        else 
        {
            /* 按键没被按下,熄灭 LED 灯 */
            rt_pin_write(PIN_LED_R, PIN_HIGH);
			rt_pin_write(PIN_LED_G, PIN_HIGH);
			rt_pin_write(PIN_LED_B, PIN_HIGH);
        }
        rt_thread_mdelay(10);
        count++;
    }
    return 0;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pDnCQleW-1673401750612)(E:\照片\MarkDown\image-20230111093736022.png)]

总结

​ 下一个。

电机和蜂鸣器

学习目标

​ 接下来我们学习的是有关电机以及蜂鸣器的知识,其中用到了中断的知识点,还是有点意思的,接下来我们来看看吧!

成果展示

电机与蜂鸣器

硬件知识

电机

​ 有关电机的部分我们需要简单介绍一下,主要就是电机的驱动方式与电路连接,电机驱动芯片选用的是L9110S。

在这里插入图片描述

在这里插入图片描述

​ 其中驱动方式如下表所示,我们只需要给高低电平即可驱动电机。
在这里插入图片描述

蜂鸣器

​ 蜂鸣器就是一个简单的放大电路,之前在F407介绍过,在此就不介绍了。
在这里插入图片描述
在这里插入图片描述

代码

​ 代码如下,但是有些部分我们得要好好讲解一下,毕竟是第一次接触RT-Thread 的中断。

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

/* 枚举 */
enum
{
    MOTOR_STOP,
    MOTOR_LEFT,
    MOTOR_RIGHT
};

/* 电机控制 */
void motor_ctrl(rt_uint8_t turn)
{
    if (turn == MOTOR_STOP)
    {
        rt_pin_write(PIN_MOTOR_A, PIN_LOW);
        rt_pin_write(PIN_MOTOR_B, PIN_LOW);
    }
    else if (turn == MOTOR_LEFT)
    {
        rt_pin_write(PIN_MOTOR_A, PIN_LOW);
        rt_pin_write(PIN_MOTOR_B, PIN_HIGH);
    }
    else if (turn == MOTOR_RIGHT)
    {
        rt_pin_write(PIN_MOTOR_A, PIN_HIGH);
        rt_pin_write(PIN_MOTOR_B, PIN_LOW);
    }
    else
    {
        LOG_D("err parameter ! Please enter 0-2.");
    }
}

void beep_ctrl(rt_uint8_t on)
{
    if (on)
    {
        rt_pin_write(PIN_BEEP, PIN_HIGH);
    }
    else
    {
        rt_pin_write(PIN_BEEP, PIN_LOW);
    }
}

/* 中断回调 */
void irq_callback(void *args)
{
    rt_uint32_t sign = (rt_uint32_t)args;
    switch (sign)
    {
    case PIN_KEY0:
        motor_ctrl(MOTOR_LEFT);
        LOG_D("KEY0 interrupt. motor turn left.");
        break;
    case PIN_KEY1:
        motor_ctrl(MOTOR_RIGHT);
        LOG_D("KEY1 interrupt. motor turn right.");
        break;
    case PIN_KEY2:
        motor_ctrl(MOTOR_STOP);
        LOG_D("KEY2 interrupt. motor stop.");
        break;
    default:
        LOG_E("error sign= %d !", sign);
        break;
    }
}

int main(void)
{
    unsigned int count = 1;

    /* 设置按键引脚为输入模式 */
    rt_pin_mode(PIN_KEY0, PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(PIN_KEY1, PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(PIN_KEY2, PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(PIN_WK_UP, PIN_MODE_INPUT_PULLDOWN);

    /* 设置电机控制引脚为输入模式 */
    rt_pin_mode(PIN_MOTOR_A, PIN_MODE_OUTPUT);
    rt_pin_mode(PIN_MOTOR_B, PIN_MODE_OUTPUT);

    /* 设置蜂鸣器引脚为输出模式 */
    rt_pin_mode(PIN_BEEP, PIN_MODE_OUTPUT);

    /* 设置按键中断模式与中断回调函数 */
    rt_pin_attach_irq(PIN_KEY0, PIN_IRQ_MODE_FALLING, irq_callback, (void *)PIN_KEY0);
    rt_pin_attach_irq(PIN_KEY1, PIN_IRQ_MODE_FALLING, irq_callback, (void *)PIN_KEY1);
    rt_pin_attach_irq(PIN_KEY2, PIN_IRQ_MODE_FALLING, irq_callback, (void *)PIN_KEY2);

    /* 使能中断 */
    rt_pin_irq_enable(PIN_KEY0, PIN_IRQ_ENABLE);
    rt_pin_irq_enable(PIN_KEY1, PIN_IRQ_ENABLE);
    rt_pin_irq_enable(PIN_KEY2, PIN_IRQ_ENABLE);

    while (count > 0)
    {
        if (rt_pin_read(PIN_WK_UP) == PIN_HIGH)
        {
            rt_thread_mdelay(50);
            if (rt_pin_read(PIN_WK_UP) == PIN_HIGH)
            {
                LOG_D("WK_UP pressed. beep on.");
                beep_ctrl(1);
            }
        }
        else
        {
            beep_ctrl(0);
        }
        rt_thread_mdelay(10);
        count++;
    }
    return 0;
}

在这里插入图片描述


讲解

 rt_pin_attach_irq(PIN_KEY0, PIN_IRQ_MODE_FALLING, irq_callback, (void *)PIN_KEY0);

​ 核心就是这个函数第一次见,关于参数什么的也不理解,所以我们首先去查找官方手册,看看官方的介绍。

rt_err_t rt_pin_attach_irq	(	rt_int32_t 	         pin,
                                rt_uint32_t 	     mode,
                                void(*)(void *args)  hdr,
                                void * 	             args 
)	

​ 参数含义如下所示,可以说是非常清楚了。

在这里插入图片描述

返回RT_EOK 成功;失败返回其他错误码。

总结

​ 本次还是收获比较大的,学习了RT-Thread 的中断,继续加油。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于STM32RT-Thread Nano系统的多线程流水项目参考代码: ```c #include "rtthread.h" #include "stm32f10x.h" #define LED1_PIN GPIO_Pin_0 #define LED2_PIN GPIO_Pin_1 #define LED3_PIN GPIO_Pin_2 #define LED4_PIN GPIO_Pin_3 static rt_thread_t led1_thread = RT_NULL; static rt_thread_t led2_thread = RT_NULL; static rt_thread_t led3_thread = RT_NULL; static rt_thread_t led4_thread = RT_NULL; static void led1_thread_entry(void *parameter) { while(1) { GPIO_ResetBits(GPIOC, LED1_PIN); rt_thread_delay(100); GPIO_SetBits(GPIOC, LED1_PIN); rt_thread_delay(100); } } static void led2_thread_entry(void *parameter) { while(1) { GPIO_ResetBits(GPIOC, LED2_PIN); rt_thread_delay(200); GPIO_SetBits(GPIOC, LED2_PIN); rt_thread_delay(200); } } static void led3_thread_entry(void *parameter) { while(1) { GPIO_ResetBits(GPIOC, LED3_PIN); rt_thread_delay(300); GPIO_SetBits(GPIOC, LED3_PIN); rt_thread_delay(300); } } static void led4_thread_entry(void *parameter) { while(1) { GPIO_ResetBits(GPIOC, LED4_PIN); rt_thread_delay(400); GPIO_SetBits(GPIOC, LED4_PIN); rt_thread_delay(400); } } void rt_init_thread_entry(void* parameter) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = LED1_PIN | LED2_PIN | LED3_PIN | LED4_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); led1_thread = rt_thread_create("led1", led1_thread_entry, RT_NULL, 512, 20, 5); if(led1_thread != RT_NULL) { rt_thread_startup(led1_thread); } led2_thread = rt_thread_create("led2", led2_thread_entry, RT_NULL, 512, 20, 5); if(led2_thread != RT_NULL) { rt_thread_startup(led2_thread); } led3_thread = rt_thread_create("led3", led3_thread_entry, RT_NULL, 512, 20, 5); if(led3_thread != RT_NULL) { rt_thread_startup(led3_thread); } led4_thread = rt_thread_create("led4", led4_thread_entry, RT_NULL, 512, 20, 5); if(led4_thread != RT_NULL) { rt_thread_startup(led4_thread); } while(1) { rt_thread_delay(1000); } } ``` 这段代码实现了四个LED的流水效果,每个LED的流水速度不同,通过四个线程来控制每个LED的流水效果,每个线程通过调用rt_thread_delay函数来控制流水速度。主线程只是用来启动四个LED的线程,然后进入一个无限循环等待。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值