RT_Thread

梦由心动


前言

硬件资源:硬件用正点原子Pandora开发板

学习了一些同辈的demo,我觉有有必要梳理串联一起,实现新手一条龙入门。

一、RT-Thread Studio

1.启动RT-Thread Studio;

在这里插入图片描述

2.点击创建RT-Thread项目 ;

在这里插入图片描述

3.Ctrl+B编译,Ctrl+Alt+D烧录工程,xshell串口看打印

在这里插入图片描述

4.CubeMx配置烧写、时钟、串口、配置Project Manager;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述

5.RT-Thread Studio工程修改

在这里插入图片描述
在这里插入图片描述

void clk_init(char *clk_source, int source_freq, int target_freq)
{
   // system_clock_config(target_freq);
    extern void SystemClock_Config(void);
    SystemClock_Config();
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import os
#引入os模块
from building import *
#导入building的所有模块

cwd = GetCurrentDir()
#获取获取当前路径,并保存至变量cwd
src  = Glob('*.c')
#获取当前目录下的所有 C 文件,并保存至src变量

# add cubemx drivers
#由于RT-Thread工程中存在部分相同函数文件,所以对src重新赋值
#文件中的stm32g4xx_it.c 、 system_stm32g4xx.c不加入构建
#其余文件按相同格式填写到下述括号内
src = Split('''
Src/stm32l4xx_hal_msp.c
Src/main.c
#Src/dma.c
Src/gpio.c
Src/usart.c
''')

#创建路径列表,并保存至path中
path = [cwd]
path += [cwd + '/Inc']
#这是 RT-Thread 基于 SCons 扩展的一个方法(函数)。
group = DefineGroup('cubemx', src, depend = [''], CPPPATH = path)

Return('group')
#这部分代码文章最后有解释

在这里插入图片描述

6.Ctrl+B编译,Ctrl+Alt+D烧录工程,xshell串口看打印

在这里插入图片描述

提示:STM32L4用的是0.1.9版本,用0.2.3版本遇见程序运行后串口无输出;
在这里插入图片描述

参考:https://blog.csdn.net/qq_40824852/article/details/123067421

二、设备和驱动

1.adc采样

1.1 打开board.h 文件,找到ADC 使用配置的流程,按流程操作。

在这里插入图片描述

* if you want to use adc you can use the following instructions. 
 * 如果您想使用adc,可以使用以下说明。
 *
 * STEP 1, open adc driver framework support in the RT-Thread Settings file  ,
 * 步骤1,在RT线程设置文件中打开adc驱动程序框架支持
 *
 * STEP 2, define macro related to the adc  
 *2步,定义与adc相关的宏
 *                 such as     #define BSP_USING_ADC1  例如:  #define BSP_USING_ADC1
 *
 * STEP 3, copy your adc init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file
 * STEP 3, 将adc init函数从stm32cubemx生成的stm32xxxx_hal_msp.c复制到board.c文件的末尾
 *                 such as     void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
 *
 * STEP 4, modify your stm32xxxx_hal_config.h file to support adc peripherals. define macro related to the peripherals
 * STEP 4,修改stm32xxxx_hal_config.h文件以支持adc外围设备。定义与外围设备相关的宏
 *                 such as     #define HAL_ADC_MODULE_ENABLED
 *
 */

1.2 配置驱动

第1步:打开配置

 * STEP 1, open adc driver framework support in the RT-Thread Settings file  ,
 * 步骤1,在RT线程设置文件中打开adc驱动程序框架支持

在这里插入图片描述这里插入图片描述
第2步:如图打开 ADC 相关的宏,根据硬件实际使用的是 ADC1或者其他打开对应的ADC。

 * STEP 2, define macro related to the adc  
 *2步,定义与adc相关的宏
 *        	 such as     #define BSP_USING_ADC1  例如:  #define BSP_USING_ADC1

在这里插入图片描述
第3步:设置ADC通道,配置ADC。(具体的生成过程参考专门的ADC驱动生成文件)

 * STEP 3, copy your adc init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file
 * STEP 3, 将adc init函数从stm32cubemx生成的stm32xxxx_hal_msp.c复制到board.c文件的末尾
 *          such as     void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)

看图,配置多通道数据采集,再跑裸机时注意采样周期、采样频率、是否循环扫描模式,跑系统那就无所谓了,有那个函数就行,毕竟系统的设备和驱动相关API会自动初始化。
在这里插入图片描述
这点参考:https://blog.csdn.net/qq_44826637/article/details/119787871

第4步:打开ADC的宏

 - STEP 4, modify your stm32xxxx_hal_config.h file to support adc peripherals. define macro related to the peripherals
 - STEP 4,修改stm32xxxx_hal_config.h文件以支持adc外围设备。定义与外围设备相关的宏
 -          such as     #define HAL_ADC_MODULE_ENABLED

在这里插入图片描述
第5步:移植ADC应用函数
1)更新SConscript
在这里插入图片描述
2)adc构建
在这里插入图片描述
3)新建adc_sample.c文件
* ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/2cd6be9d4be04ec58c48270728ed8b3b.png

  • 代码如下(adc_sample.c):
/*
 * 程序清单: ADC 设备使用例程
 * 例程导出了 adc_sample 命令到控制终端
 * 命令调用格式:adc_sample
 * 程序功能:通过 ADC 设备采样电压值并转换为数值。
 *           示例代码参考电压为3.3V,转换位数为12位。
*/

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

#define ADC_DEV_NAME        "adc1"      /* ADC 设备名称 */
#define ADC_DEV_CHANNEL     3           /* ADC 通道 */
#define REFER_VOLTAGE       330         /* 参考电压 3.3V,数据精度乘以100保留2位小数*/
#define CONVERT_BITS        (1 << 12)   /* 转换位数为12位 */

static int adc_vol_sample(int argc, char *argv[])
{
    rt_adc_device_t adc_dev;
    rt_uint32_t value, vol;
    rt_err_t ret = RT_EOK;

    /* 查找设备 */
    adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
    if (adc_dev == RT_NULL)
    {
        rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME);
        return RT_ERROR;
    }

    /* 使能设备 */
    ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL);

    /* 读取采样值 */
    value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL);
    rt_kprintf("the value is :%d \n", value);

    /* 转换为对应电压值 */
    vol = value * REFER_VOLTAGE / CONVERT_BITS;
    rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);

    /* 关闭通道 */
    ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL);

    return ret;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(adc_vol_sample, adc voltage convert sample);

4)编译烧录
在这里插入图片描述

参考:https://blog.csdn.net/yutian0606/article/details/135488611
拓展:RT-Thread ADC_DMA :https://blog.csdn.net/qq_52251819/article/details/134782983

三、RT-thread stido以太网ENC28J60直连PC的配置

配置LWIP的提醒知识
以太网芯片有很多种,大致可以分成 3 种:

  • 以太网芯片只有 PHY(物理接口收发器 ),需要单片机带 MAC(以太网媒体接入控制器 ),通过 MII 或者 RMII 接口和单片机通讯。例如 LAN8720。
  • 以太网芯片带 MAC 和 PHY,通过 SPI 接口和单片机通讯。例如 ENC28J60。
  • 以太网芯片带 MAC 和 PHY,通过 SPI 接口和单片机通讯,同时内置硬件协议栈,适合低速单片机。例如 W5500。

硬件连接说明,其连接如下图所示

ENC28J60模块STM32F475VET6
名称GPIO
SPI_MISOPB14
SPI_SCKPB13
SPI_MOSIPB15
INT(中断)PD3
CS(片选)PD5
RST(复位)PD4
VCC3.3电源
GND

1.点击创建RT-Thread项目

在这里插入图片描述

2.配置工程测试

/** if you want to use spi bus you can use the following instructions.
 *
 * STEP 1, open spi driver framework support in the RT-Thread Settings file
 *
 * STEP 2, define macro related to the spi bus
 *                 such as     #define BSP_USING_SPI1
 *
 * STEP 3, copy your spi init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file
 *                 such as     void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
 *
 * STEP 4, modify your stm32xxxx_hal_config.h file to support spi peripherals. define macro related to the peripherals
 *                 such as     #define HAL_SPI_MODULE_ENABLED
 */

2.1 步骤1

  在“项目资源管理器”中,双击“RT-Thread Settings”,打开软件配置中心。因ENC28J60和STM32的通信是基于SPI总线的,所以先进行SPI的配置,双击软件配置中心的“SPI”,在出来的选项中使能SPI总线和ENC28J60 SPI以太网接口。
在这里插入图片描述
  因本实验采用的ENC29J60模块通过普通网线和PC网口直连的方式进行测试的,没有DHCP服务器,所以要关闭“通过DHCP分配IP地址”而采用静态配置地址的方式,静态IP地址配置如下在这里插入图片描述
  再次,要打开“使能ping功能”,还要在“网络接口设备”中选中"使能网络接口设备",以便启用ping和ifconfig调试功能。最后要说明下,在lwIP配置中,lwIP默认的版本是v2.0.2,还有两个版本可供选择:v1.4.1和v2.1.0,选择更新的v2.1.0版本也能正常工作,但不要选择v1.4.1版本,因为其和2.0版的lwIP接口变动较大,会导致ENC28J60驱动不能正常工作。至此,驱动的配置阶段完成,点击IDE中“保存”
在这里插入图片描述

2.2 步骤2~4

图5 工程目录结构
  图中,标红的几个文件需要进行修改。
  首先修改SPI总线相关的宏定义,因在MiniSTM32的开发板上,ENC28J60模块是挂载在SPI2总线上的,所以在board.h中,要定义“#define BSP_USING_SPI2”;(步骤2
  其次,需要增加SPI1总线的初始化函数,这要使用STM32CubeMX或STM32CubeIDE来生成,在STM32CubeMX中选择“STM32F407VE”,并使能SPI2,即可生成代码,我们只需要其中的HAL_SPI_MspInit()函数,其代码如下,如不熟悉STM32CubeMX,可直接拷贝下面的代码即可。(步骤3

void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hspi->Instance==SPI2)
  {
    /* 外设时钟使能 */
    __HAL_RCC_SPI2_CLK_ENABLE();

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**SPI1 GPIO 配置
    PB13    ------> SPI2_SCK  A5
    PB14    ------> SPI2_MISO  A6
    PB15    ------> SPI2_MOSI A7
    */
    GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_15;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_14;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  }
}
//把上面的代码拷贝到board.c文件的末尾。

  最后在 stm32xxxx_hal_config.h中,要定义“#define HAL_SPI_MODULE_ENABLED”(这两个宏在原文件中是存在的,只是被注释掉了,没启用,只要把注释去掉就行),这样才能启用SPI2总线。(步骤4

补充:
  在main.c中,把LOG_D(“Hello RT-Thread!”),移到while循环的上面,免得调试时在控制台不停出现"Hello RT-Thread!"而影响调试,至此代码的修改全部完成。
  SPI2的引脚,经过前面的配置,系统已完成对应pin的初始化,现在要关注ENC28J60的中断INT引脚(对接PD3)和片选引脚(对接PD5),因在RT-Thread的ENC28J60驱动中,采用软件复位,所以其硬件复位引脚(对接PD4)可不做配置。在工程的drivers目录中新建drv_enc28j60.c文件,把以下代码拷贝进去。

#include <drivers/pin.h>
#include <enc28j60.h>
#include <drv_spi.h>
#define ENC28J60_INT    51//PD3 ENC28J60中断
static void rt_hw_enc28j60_init(void)
{
     rt_hw_spi_device_attach("spi2", "spi20", GPIOD, GPIO_PIN_5);//PD5 ENC28J60片选CS
     enc28j60_attach("spi20");
     rt_pin_mode(ENC28J60_INT, PIN_MODE_INPUT_PULLUP);
     rt_pin_attach_irq(ENC28J60_INT, PIN_IRQ_MODE_FALLING, (void(*)(void*))enc28j60_isr, RT_NULL);
     rt_pin_irq_enable(ENC28J60_INT, PIN_IRQ_ENABLE);
}
INIT_COMPONENT_EXPORT(rt_hw_enc28j60_init);

  PD3 对应的引脚号为51,可在driver目录下的drv_gpio.c的结构体pin_index中查询得到。rt_hw_spi_device_attach()函数在SPI2总线上注册一个名称为“spi20”的SPI设备,函数中的参数GPIOD、GPIO_PIN_5指定“spi10”设备的片选信号为PD5引脚。 enc28j60_attach(“spi20”)函数把ENC28J60模块挂载到“spi20”设备上,rt_pin_mode()、rt_pin_attach_irq()、rt_pin_irq_enable()三个函数分别用来设定中断引脚PD3的中断模式、中断处理函数和使能PA1引脚的中断。INIT_COMPONENT_EXPORT宏用来把rt_hw_enc28j60_init()加到初始化过程中,以便系统在启动后能自动进行lwIP和ENC28J60驱动的初始化。编译后通过J-Link或ST-LINK下载至开发板。

2.3配置电脑ip

  网线连接ENC28J60模块和PC的网口,PC网卡设置地址为:192.168.1.29,掩码:255.255.255.0,网关:192.168.1.1,注意要关闭Windows的防火墙,否则会出现ping不通的现象。
在这里插入图片描述
在这里插入图片描述

参考:
https://blog.csdn.net/weixin_49364907/article/details/114273808
https://blog.csdn.net/2201_75354475/article/details/133905943

3.拓展

问题:Pandora demo工程examples\18_iot_spi_eth_enc28j60\applications\main.c静态ip ping不了
解决方案:用参考的文章(https://blog.csdn.net/heermu/article/details/106214371)修改bug前后打印现象如下:
在这里插入图片描述

四、NM25Q128的spi_flash

  潘多拉主控板是NM25Q128的spi_flash,烧录RT-Thread-book\code\chapter15工程提示一下三个bug。
在这里插入图片描述

1.容量过大(对NM25Q128高低字节要反过来解析)

在这里插入图片描述

参考:https://club.rt-thread.org/ask/question/567877fcf1e8de59.html

2.spi_flash由W25Q128改为NM25Q128

在这里插入图片描述在这里插入图片描述

3.filesystem初始化失败

重新初始化即可解决 dfs_mkfs(“elm”,“NOR_FLASH”);
         msh />mkfs -t elm NOR_FLASH
拓展:https://club.rt-thread.org/ask/question/eb8d663cad23c015.html

4.解决bug打印

在这里插入图片描述

总结

以上就是今天要讲的内容,本文仅仅简单介绍了RT_Thread工程快速搭建。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值