个人创建基于rt_thread的项目

在学习了中断函数后突发奇想想自己创建一个用中断函数来控制led灯的闪烁,说干就干,期望达到的效果如下:

按下key1后蜂鸣器发出声音同时led以绿,蓝,红的顺序进行闪烁;按下key2后蜂鸣器停止发出声音同时led灯熄灭。

在经过一番操作后代码如下:

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

#define KEY0_PIN_NUM 0
#define BEEP_PIN_NUM 8

int jb,junbian;
/*完成对led的初始化*/
void led_start(){
  rt_pin_mode(16,PIN_MODE_OUTPUT);
  rt_pin_write(16,PIN_HIGH);
  rt_pin_mode(17,PIN_MODE_OUTPUT);
  rt_pin_write(17,PIN_HIGH);
  rt_pin_mode(21,PIN_MODE_OUTPUT);
  rt_pin_write(21,PIN_HIGH);	
}
/*完成对蜂鸣器的初始化*/
void jun_ready(){

  rt_pin_mode(8,PIN_MODE_OUTPUT);
  rt_pin_write(8,PIN_HIGH); 

}
/*完成led的闪烁控制*/
void jun_on(){
  
  rt_pin_write(16,PIN_LOW);
  rt_thread_delay(50);
  rt_pin_write(16,PIN_HIGH); 
  
  rt_pin_write(17,PIN_LOW);
  rt_thread_delay(50);
  rt_pin_write(17,PIN_HIGH);
  
  rt_pin_write(21,PIN_LOW);
  rt_thread_delay(50);
  rt_pin_write(21,PIN_HIGH);	
  
}
/*完成关闭led的控制*/
void jun_off(){
  rt_pin_write(8,PIN_LOW);
  rt_pin_write(16,PIN_HIGH);
  rt_pin_write(17,PIN_HIGH);
  rt_pin_write(21,PIN_HIGH);
}

void jun_start(){
  led_start();//调用led初始化函数
/*将key1和key2设置成上拉输入*/
  rt_pin_mode(0,PIN_MODE_INPUT_PULLUP );
  rt_pin_mode(45,PIN_MODE_INPUT_PULLUP );
  while(1){
  rt_pin_attach_irq(0,PIN_IRQ_MODE_FALLING,jun_ready,RT_NULL);//绑定引脚中断回调函数
  rt_pin_irq_enable(0,PIN_IRQ_ENABLE);//使能引脚中断
  
  jb=rt_pin_read(8);//读取蜂鸣器的电平
  
  if(jb==PIN_HIGH){
    while(jb==PIN_HIGH){
    jun_on();
  rt_pin_attach_irq(45,PIN_IRQ_MODE_FALLING,jun_off,RT_NULL);
  rt_pin_irq_enable(45,PIN_IRQ_ENABLE);
      junbian=rt_pin_read(8);
      if(junbian==PIN_LOW){
        break;
      }
      
    }
  }
}
}

MSH_CMD_EXPORT(jun_start,sat8 is the best)

现在说一下项目设计的思路,首先在完成对于引脚的初始化后我们首先要做的事就是实现闪烁功能,通过延时函数rt_thread_delay()我们可以轻易做到闪烁的功能。有关本项目所使用到的函数在这里我都写了注释:https://www.mdrfb.com/2019/09/03/examples-of-functions-in-rt_thread/

接下来就要解决用按钮控制的问题了,根据中断回调函数我们可以让程序在读到这一行的时候执行中断并作出相应的操作,

rt_pin_attach_irq(0,PIN_IRQ_MODE_FALLING,jun_ready,RT_NULL);//绑定引脚中断回调函数 
rt_pin_irq_enable(0,PIN_IRQ_ENABLE);//使能引脚中断

这两行实现了使用key1按钮来让蜂鸣器器响起来的功能因为蜂鸣器要和led灯一起闪烁所以我们需要时刻对蜂鸣器进行电平检测,当电平被检测为高时就代表我们的led就要开始闪起来了,

jb=rt_pin_read(8);//读取蜂鸣器的电平

这一行代码完成了对于蜂鸣器电平的检测,再根据if函数来执行检测到蜂鸣器电平为high时led开始闪烁的功能。

因为我们还要通过key2按钮来关闭led和蜂鸣器所以我们还要再打一行中断回调函数和使能引脚中断, 

 rt_pin_attach_irq(45,PIN_IRQ_MODE_FALLING,jun_off,RT_NULL);
 rt_pin_irq_enable(45,PIN_IRQ_ENABLE);

根据上文的思路,当蜂鸣器电平变低时led就要熄灭所以我们又添加了一条检测函数,

junbian=rt_pin_read(8);

再根据if判断语句和c语言中break指令完成对闪烁的中断,也就是跳出while循环,至此我们的操作目标已经都达成了。

在编写此类程序的时候有一点需要注意,有些人在编程时会忽略编译器对于读取程序的顺序,程序在运行时速度非常快所以有时候会发生这种情况,我的程序明明符合逻辑天衣无缝为什么下载到开发板上后功能却不完全或根本没有功能,为了达到随按随停,随按随开的功能我们要在主体函数外边加一个while(1)循环,也就是无限循环,否则就会发生按了按钮灯死活不亮的反应,因为你的程序早就被执行完毕了!

野火指南者通过RT-Thread的AT组件连接板载ESP8266

先按照RTT官网的AT组件连接esp8266的教程,准备连接esp8266

开发板平台:野火 指南者开发版

CPU:STM32F103VE

RT-Thread版本:4.0.2

一、安装并配置ENV

安装env软件的方法请参考RTT的官方教程

安装完env后在野火的RTT项目中右键Con Emu Here

 在命令行中运行menuconfig

 

 进入到控制台界面

-配置串口支持(野火版上默认esp8266接uart3):进入到Hardware Drivers Config –>On-chip Peripheral Drivers –>Enable UART –>Enable UART3

-开启AT组件功能:进入到RT-Thread Components–>Network–>AT commands

AT Client 配置选项介绍如下:

  • Enable debug log output:配置开启调试日志;
  • Enable AT commands client:配置开启 AT 客户端;
  • The muxinum number of supported clients: 配置最大同时支持的客户端数量,该例程使用单客户端连接,配置为 1 即可。
  • Enable BSD Socket API support by AT commands: 配置开启 BSD Socket API 支持。
  • Enable CLI(Command-Line Interface) for AT commands: 配置开启 AT 命令行交互模式。

 

Enable print RAW format AT command communication data: 配置开启收发数据实时打印功能。

-开启SAL组件:
进入到RT-Thread Components–>Network–>Socket abstraction layer

打开Enable socket abstraction layer 和 Enable BSD socket operated by file system API

-开启AT-decive:进入到RT-Thread online packages –> IoT – internet of things –> AT DEVICE

打开后进入Espressif ESP8266

在WIFI ssid与WIFI password中填写开发板要连接的wifi网络

把AT client device name修改成uart3

-配置完成,将光标移向env下方的Save,回车保存后退出到命令行界面

在命令行中输入:pkg –update

再输入:scons –target=mdk5 来重新生成项目

二、编译调试项目

打开项目文件.uvprojx

将项目编译后,通过下载器烧录进野火指南者开发板,打开sscom观察串口内的信息:

 

 \ | /
- RT -     Thread Operating System
 / | \     4.0.2 build Aug 16 2019
 2006 - 2019 Copyright by rt-thread team
[I/sal.skt] Socket Abstraction Layer initialize success.
[I/at.clnt] AT client(V1.3.0) on device uart3 initialize success.
[D/at.dev] the network interface device(esp0) set up status
[D/at.dev] esp8266 device(esp0) initialize start.
[E/at.clnt] Read response buffer failed. The Response buffer size is out of buffer size(256)!
[D/at.clnt] execute command (ATE0) timeout (5000 ticks)!
[I/at.dev] esp8266 device(esp0) initialize retry...
[D/at.clnt] execute command (ATE0) timeout (5000 ticks)!
[I/at.dev] esp8266 device(esp0) initialize retry...
[D/at.clnt] execute command (ATE0) timeout (5000 ticks)!
[I/at.dev] esp8266 device(esp0) initialize retry...
[D/at.clnt] execute command (ATE0) timeout (5000 ticks)!
[I/at.dev] esp8266 device(esp0) initialize retry...
[D/at.clnt] execute command (ATE0) timeout (5000 ticks)!
[I/at.dev] esp8266 device(esp0) initialize retry...
[E/at.dev] esp8266 device(esp0) network initialize failed(-1).

我们发现串口报告的错误信息有两个

一个是Read response buffer failed. 缓冲区内存过小,那我们就直接增大就好了

一个是command (ATE0)运行超时,ATE0是AT指令中的关闭回显,出现这个问题的原因可能是AT组件初始化时间过短

-解决缓冲区内存过小

打开项目文件,定位到AT/at_client.c

将第364行修改成

resp = at_create_resp(512, 0, rt_tick_from_millisecond(300));

即可解决问题

-解决ATE0运行超时

 

打开项目文件,定位到at_device/at_device_esp8266.c

我们在第632行看到了相关的ATE0的代码

AT_SEND_CMD(client, resp, "AT+RST");
/* reset waiting delay */
rt_thread_mdelay(2000);
/* disable echo */
AT_SEND_CMD(client, resp, "ATE0");

将rt_thread_mdelay函数的延迟时间修改成2000ms,让AT+RST有足够时间来运行

即可解决问题

-将项目重新编译后,烧录进开发板,继续观察串口内容
 \ | /
- RT -     Thread Operating System
 / | \     4.0.2 build Aug 16 2019
 2006 - 2019 Copyright by rt-thread team
[I/sal.skt] Socket Abstraction Layer initialize success.
[I/at.clnt] AT client(V1.3.0) on device uart3 initialize success.
[D/at.dev] the network interface device(esp0) set up status
[D/at.dev] esp8266 device(esp0) initialize start.
[D/at.dev] AT version:0.22.0.0(Mar 20 2015 10:04:26)
[D/at.dev] SDK version:1.0.0
[D/at.dev] compile time:Mar 20 2015 11:00:56
[D/at.dev] 
[I/at.dev] esp8266 device(esp0) network initialize successfully.
[E/at.clnt] execute command (AT+CIPDNS_CUR?) failed!
[W/at.dev] please check and update device(esp0) firmware to support the "AT+CIPDNS_CUR?" command.
[E/at.clnt] execute command (AT+CIPDOMAIN="link.rt-thread.org") failed!

又发现了两个错误

[E/at.clnt] execute command (AT+CIPDNS_CUR?) failed! [W/at.dev] please check and update device(esp0) firmware to support the “AT+CIPDNS_CUR?” command. [E/at.clnt] execute command (AT+CIPDOMAIN=”link.rt-thread.org”) failed!

这些错误的原因是由于野火板载的ESP8266的固件版本太低造成的,可以通过刷最新的安信可ESP8266固件来解决,本文不做过多展开。

我们在串口中输入 at client 命令,并输入 AT+RST与AT+PING=”www.baidu.com”

来测试AT组件是否安装完善

msh />at client
======== Welcome to using RT-Thread AT command client cli ========
Cli will forward your command to server port(uart3). Press 'ESC' to exit.
AT+RST

OK

 ets Jan  8 2013,rst cause:4, boot mode:(3,6)

wdt reset
load 0x40100000, len 1320, room 16 
tail 8
chksum 0xb8
load 0x3ffe8000, len 776, room 0 
tail 8
chksum 0xd9
load 0x3ffe8308, len 412, room 0 
tail 12
chksum 0xb9
csum 0xb9

2nd boot version : 1.3(b3)
  SPI Speed      : 40MHz
  SPI Mode       : QIO
  SPI Flash Size : 4Mbit
jump to run user2

sl??
ready

AT+PING="www.baidu.com"
AT+PING="www.baidu.com"
+12

OK

输入输出结果如上,可以看到,AT组件正常运行了!