梦由心动
前言
硬件资源:硬件用正点原子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文件

- 代码如下(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_MISO | PB14 |
| SPI_SCK | PB13 |
| SPI_MOSI | PB15 |
| 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

图中,标红的几个文件需要进行修改。
首先修改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工程快速搭建。



1万+

被折叠的 条评论
为什么被折叠?



