一、前言
学单片机编程,总是从点灯开始,因为单片机控制外设的本质就是控制IO口,所以,项目实战的第一讲,我们就从点亮LED灯开始吧。希望同学们能够坚持到最后,从入门到精通,需要耐心和坚持,从入门到放弃,只需要一个念头。
源码链接
我发布的所有关于RT-thread的教程源代码都在下面这个链接里面,随着我教程的更新,新的代码也会加入进去。
教程源码下载链接:https://pan.baidu.com/s/1N2D8dM31deKIqNqaIQfPiA
提取码:7nsx
二、编程讲解
第一步:新建或打开一个工程
新建工程的方法我就不说了,不知道的同学可以看下我的入门教程第二讲。
RT-Thread零基础快速入门第2讲链接:https://blog.csdn.net/ShenZhen_zixian/article/details/105027730
第二步:配置IO口
IO口可以通过rt_pin_mode(rt_base_t pin, rt_base_t mode)函数来配置,这个函数在pin.c里面。
/* RT-Thread Hardware PIN APIs */
void rt_pin_mode(rt_base_t pin, rt_base_t mode)
{
RT_ASSERT(_hw_pin.ops != RT_NULL);
_hw_pin.ops->pin_mode(&_hw_pin.parent, pin, mode);
}
这个函数的第一个参数是pin,这个是io口对应的pin脚序号,RT-thread对每一个IO口都有一个编号,可以在drv_gpio.c里面看到,我这里列举一部分给大家看一下。
#if defined(GPIOA)
__STM32_PIN(0 , A, 0 ),
__STM32_PIN(1 , A, 1 ),
__STM32_PIN(2 , A, 2 ),
__STM32_PIN(3 , A, 3 ),
__STM32_PIN(4 , A, 4 ),
__STM32_PIN(5 , A, 5 ),
__STM32_PIN(6 , A, 6 ),
__STM32_PIN(7 , A, 7 ),
__STM32_PIN(8 , A, 8 ),
__STM32_PIN(9 , A, 9 ),
__STM32_PIN(10, A, 10),
__STM32_PIN(11, A, 11),
__STM32_PIN(12, A, 12),
__STM32_PIN(13, A, 13),
__STM32_PIN(14, A, 14),
__STM32_PIN(15, A, 15),
#if defined(GPIOB)
__STM32_PIN(16, B, 0),
__STM32_PIN(17, B, 1),
__STM32_PIN(18, B, 2),
__STM32_PIN(19, B, 3),
__STM32_PIN(20, B, 4),
__STM32_PIN(21, B, 5),
__STM32_PIN(22, B, 6),
__STM32_PIN(23, B, 7),
__STM32_PIN(24, B, 8),
__STM32_PIN(25, B, 9),
__STM32_PIN(26, B, 10),
__STM32_PIN(27, B, 11),
__STM32_PIN(28, B, 12),
__STM32_PIN(29, B, 13),
__STM32_PIN(30, B, 14),
__STM32_PIN(31, B, 15),
#if defined(GPIOC)
__STM32_PIN(32, C, 0),
__STM32_PIN(33, C, 1),
__STM32_PIN(34, C, 2),
__STM32_PIN(35, C, 3),
__STM32_PIN(36, C, 4),
__STM32_PIN(37, C, 5),
__STM32_PIN(38, C, 6),
__STM32_PIN(39, C, 7),
__STM32_PIN(40, C, 8),
__STM32_PIN(41, C, 9),
__STM32_PIN(42, C, 10),
__STM32_PIN(43, C, 11),
__STM32_PIN(44, C, 12),
__STM32_PIN(45, C, 13),
__STM32_PIN(46, C, 14),
__STM32_PIN(47, C, 15),
#if defined(GPIOD)
__STM32_PIN(48, D, 0),
__STM32_PIN(49, D, 1),
__STM32_PIN(50, D, 2),
__STM32_PIN(51, D, 3),
__STM32_PIN(52, D, 4),
__STM32_PIN(53, D, 5),
__STM32_PIN(54, D, 6),
__STM32_PIN(55, D, 7),
__STM32_PIN(56, D, 8),
__STM32_PIN(57, D, 9),
__STM32_PIN(58, D, 10),
__STM32_PIN(59, D, 11),
__STM32_PIN(60, D, 12),
__STM32_PIN(61, D, 13),
__STM32_PIN(62, D, 14),
__STM32_PIN(63, D, 15),
第二个参数是mode,这个是io口的模式,在RT-thread里面一共有5种,在pin.h里面有定义,我把代码复制给大家看一下。关于这几种模式的区别我不做详细的介绍了,不知道的同学可以网上查一下。
#define PIN_MODE_OUTPUT 0x00 //推挽输出
#define PIN_MODE_INPUT 0x01 //浮空输入
#define PIN_MODE_INPUT_PULLUP 0x02 //上拉输入
#define PIN_MODE_INPUT_PULLDOWN 0x03 //下拉输入
#define PIN_MODE_OUTPUT_OD 0x04 //开漏输出
我们在代码里面直接调用rt_pin_mode(rt_base_t pin, rt_base_t mode)函数即可
/* defined the LED0 pin: PF9 */
#define LED0_PIN 89
int main(void)
{
/* set LED0 pin mode to output */
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
}
如果不想去找IO口的序号,还有另外一种写法
/* defined the LED0 pin: PF9 */
#define LED0_PIN GET_PIN(F, 9)
int main(void)
{
/* set LED0 pin mode to output */
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
}
GET_PIN(PORTx,PIN)这个函数在drv_gpio.h里面有定义,定义如下
#define GET_PIN(PORTx,PIN) (rt_base_t)((16 * ( ((rt_base_t)__STM32_PORT(PORTx) - (rt_base_t)GPIOA_BASE)/(0x0400UL) )) + PIN)
第三步:IO口输出高/低电平
我们可以调用rt_pin_write(LED0_PIN, PIN_HIGH)函数配置IO口电平,这个函数在pin.c里面
void rt_pin_write(rt_base_t pin, rt_base_t value)
{
RT_ASSERT(_hw_pin.ops != RT_NULL);
_hw_pin.ops->pin_write(&_hw_pin.parent, pin, value);
}
函数的第一个参数是pin,和配置IO口模式时一样,不多说了
第二个参数是配置电平的,0为低电平,1为高电平,在pin.h有定义
#define PIN_LOW 0x00
#define PIN_HIGH 0x01
根据自己的板子设置电平,如果IO口接的是LED正极,则输出高电平点亮,反之则输出低,我这里把引脚设置为低电平,代码示例如下
/* defined the LED0 pin: PF9 */
#define LED0_PIN GET_PIN(F, 9)
rt_pin_write(LED0_PIN, PIN_LOW);
三、项目实战
按照上面的步骤,我们写一个完整的工程,代码如下:
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
/* defined the LED0 pin: PF9 */
#define LED0_PIN GET_PIN(F, 9)
int main(void)
{
/* set LED0 pin mode to output */
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
while (1)
{
rt_pin_write(LED0_PIN, PIN_HIGH);
}
}
四、进阶学习
LED灯闪烁
要实现LED灯闪烁,我们只需要用RT-thread的延时函数rt_thread_mdelay(rt_int32_t ms)就行了。这个是精准的软件延时函数,而且在延时期间会挂起线程不占用cpu资源,这个等我后面讲到线程的时候再细说吧。
/* defined the LED0 pin: PF9 */
#define LED0_PIN GET_PIN(F, 9)
int main(void)
{
/* set LED0 pin mode to output */
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
while (1)
{
rt_pin_write(LED0_PIN, PIN_HIGH);
rt_thread_mdelay(500);//延时500ms
rt_pin_write(LED0_PIN, PIN_LOW);
rt_thread_mdelay(500);//延时500ms
}
}
流水灯
#define LED0_PIN GET_PIN(F, 9)
#define LED1_PIN GET_PIN(F, 10)
int main(void)
{
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);
while (1)
{
rt_pin_write(LED0_PIN, PIN_HIGH);
rt_pin_write(LED1_PIN, PIN_LOW);
rt_thread_mdelay(500);//延时500ms
rt_pin_write(LED0_PIN, PIN_LOW);
rt_pin_write(LED1_PIN, PIN_HIGH);
rt_thread_mdelay(500);//延时500ms
}
}
五、结束语
好了,关于LED的入门教程就讲到这里,比较简单,就不多说什么了,也不求赞了。如果需要看我写的源码的话可以在博文前言部分的链接下载。后续我会继续更新RT-thread入门教程系列,如果感兴趣的同学可以关注一下博主,谢谢!
RT-thread相关教程汇总:https://blog.csdn.net/ShenZhen_zixian/article/details/120563891