(一)STM32L4(RT- Thread)——电机和蜂鸣器,独立按键,LED灯
文章目录
- (一)STM32L4(RT- Thread)——电机和蜂鸣器,独立按键,LED灯
- LED灯
- 学习目标
- 实验结果
- 内容
- 代码
- 总结
- 独立按键
- 学习目标
- 成果展示
- 硬件知识
- 代码
- 总结
- 电机和蜂鸣器
- 学习目标
- 成果展示
- 硬件知识
- 电机
- 蜂鸣器
- 代码
- 讲解
- 总结
LED灯
学习目标
今天我们来学习点亮潘多拉开发板的LED灯,同时也是首次在项目中使用RT - Thread操作系统,目前感觉变化不大,和裸机开发很像,可能到后面才能发现有不同之处吧,值得一提的是 RT - Thread 的日志系统通过串口打印信息到电脑,这一点还是比较好玩的,好了,让我们进入知识的讲解。
实验结果
内容
说实话点亮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;
}
总结
下一个。
电机和蜂鸣器
学习目标
接下来我们学习的是有关电机以及蜂鸣器的知识,其中用到了中断的知识点,还是有点意思的,接下来我们来看看吧!
成果展示
电机与蜂鸣器
硬件知识
电机
有关电机的部分我们需要简单介绍一下,主要就是电机的驱动方式与电路连接,电机驱动芯片选用的是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 的中断,继续加油。