RT-Thread 操作系统 之串口设备、ADC设备及IIC设备
一、UART串口设备
1.1、访问串口设备接口
☐ 应用程序通过RT-Thread提供的IO设备管理接口来访问串口硬件:
☐ 查找串口设备(例:“uart2”)
☐ 打开串口设备(串口收发数据模式:中断、轮询、DMA)
以上具体查看第七章IO设备章节
☐ 控制串口设备
rt_err_t rt_device_control(rt_device_t dev, rt_uint8_t cmd, void* arg);
cmd 命令控制字,可取值:RT_DEVICE_CTRL_CONFIG
arg 控制的参数,可取类型:struct serial_conigure
struct serial_configure
{
rt_uint32_t baud_rate;
rt_uint32_t data_bits :4;
rt_uint32_t stop_bits :2;
rt_uint32_t parity :2;
rt_uint32_t bit_order :1;
rt_uint32_t invert :1;
rt_uint32_t bufsz :16;
rt_uint32_t reserved :4;
};
/* 波特率可取值*/
#define BAUD_RATE_2400 2400
#define BAUD_RATE_4800 4800
#define BAUD_RATE_9600 9600
#define BAUD_RATE_19200 19200
#define BAUD_RATE_38400 38400
#define BAUD_RATE_57600 57600
#define BAUD_RATE_115200 115200
#define BAUD_RATE_230400 230400
#define BAUD_RATE_460800 460800
#define BAUD_RATE_921600 921600
#define BAUD_RATE_2000000 2000000
#define BAUD_RATE_3000000 3000000
/* 数据位可取值*/
#define DATA_BITS_5 5
#define DATA_BITS_6 6
#define DATA_BITS_7 7
#define DATA_BITS_8 8
#define DATA_BITS_9 9
/*停止位可取值 */
#define STOP_BITS_1 0
#define STOP_BITS_2 1
#define STOP_BITS_3 2
#define STOP_BITS_4 3
/*极性位可取值*/
#define PARITY_NONE 0
#define PARITY_ODD 1
#define PARITY_EVEN 2
/* 高低位顺序可取值*/
#define BIT_ORDER_LSB 0
#define BIT_ORDER_MSB 1
/*模式可取值*/
#define NRZ_NORMAL 0 /* normal mode */
#define NRZ_INVERTED 1 /* inverted mode */
/* 接收数据缓冲区默认大小*/
#define RT_SERIAL_RB_BUFSZ 64
RT-Thread 提供的默认串口配置
#define RT_SERIAL_CONFIG_DEFAULT \
{ \
BAUD_RATE_115200, /* 115200 bits/s */ \
DATA_BITS_8, /* 8 databits */ \
STOP_BITS_1, /* 1 stopbit */ \
PARITY_NONE, /* No parity */ \
BIT_ORDER_LSB, /* LSB first sent */ \
NRZ_NORMAL, /* Normal mode */ \
RT_SERIAL_RB_BUFSZ, /* Buffer size */ \
0 \
}
注:缓冲区通过 control 接口修改,缓冲区大小无法动态改变,只有在 open 设备之前可以配置。open 设备之后,缓冲区大小不可再进行更改。但除过缓冲区之外的其他参数,在 open 设备前 / 后,均可进行更改。
☐ 发送数据
☐ 设置发送完成回调函数
在应用程序调用 rt_device_write()写入数据时,如果底层硬件能够支持自动发送,那么上层应用可以设置一个回调函数。这个回调函数会在底层硬件数据发送完成后 (例如 DMA 传送完成或 FIFO 已经写入完毕产生完成中断时) 调用
☐ 设置接收回调函数
若串口以中断接收模式打开,当串口接收到一个数据产生中断时,就会调用回调函数,并且会把此时缓冲区的数据大小放在size参数里,把串口设备句柄放在dev参数里供调用者获取。
若串口以 DMA 接收模式打开,当 DMA 完成一批数据的接收后会调用此回调函数。
使用:一般情况下接收回调函数可以发送一个信号量或者事件通知串口数据处理线程有数据到达
☐ 接收数据
☐ 关闭串口设备
rt_err_t rt_device_close(rt_device_t dev);
1.2、串口案例
使用时配置:
board.h配置:
1.2.1、轮询发送和中断接收
流程图如下:
1.2.2、DMA接收和轮询发送
board.h
二、ADC设备
ADC(Analog-to-Digital Converter) 指模数转换器。是指将连续变化的模拟信号转换为离散的数字信号的器件。
ADC相关参数说明:
☐ 分辨率:
分辨率以二进制(或十进制)数的位数来表示,一般有 8 位、10 位、12 位、16 位等,它说明模数转换器对输入信号的分辨能力,位数越多,表示分辨率越高,恢复模拟信号时会更精确。
☐ 精度:
精度表示 ADC 器件在所有的数值点上对应的模拟值和真实值之间的最大误差值,也就是输出数值偏离线性最大的距离。
☐ 转换速率:
转换速率是指 A/D 转换器完成一次从模拟到数字的 AD 转换所需时间的倒数。例如,某 A/D 转换器的转换速率为 1MHz,则表示完成一次 AD 转换时间为 1 微秒。
2.1、访问ADC设备
应用程序通过 RT-Thread 提供的 ADC 设备管理接口来访问 ADC 硬件,相关接口如下所示:
☐ 查找 ADC 设备
rt_device_t rt_device_find(const char* name);
☐ 使能 ADC 通道
rt_err_t rt_adc_enable(rt_adc_device_t dev, rt_uint32_t channel)
@dev ADC 设备句柄
@channel ADC 通道
☐ 读取 ADC 通道采样值
rt_uint32_t rt_adc_read(rt_adc_device_t dev, rt_uint32_t channel);
@dev ADC 设备句柄
@channel ADC 通道
☐ 关闭 ADC 通道
rt_err_t rt_adc_disable(rt_adc_device_t dev, rt_uint32_t channel);
2.2、FinSH 命令
☐ 在使用设备前,需要先查找设备是否存在,可以使用命令 adc probe后面跟注册的 ADC 设备的名称
msh >adc probe adc1 probe adc1 success
☐ 使能设备的某个通道可以使用命令 adc enable后面跟通道号
msh >adc enable 5 adc1 channel 5 enables success
☐ 读取 ADC 设备某个通道的数据可以使用命令 adc read后面跟通道号。
msh >adc read 5 adc1 channel 5 read value is 0x00000FFF msh >
☐ 关闭设备的某个通道可以使用命令 adc disable后面跟通道号
msh >adc disable 5 adc1 channel 5 disable success msh >
2.3、ADC使用流程
/-------------------------- ADC CONFIG BEGIN --------------------------/
/** if you want to use adc you can use the following instructions.
*
* STEP 1, open adc driver framework support in the RT-Thread Settings file
*
* STEP 2, define macro related to the adc
* such as #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
* 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
* such as #define HAL_ADC_MODULE_ENABLED
*
*/
/*#define BSP_USING_ADC1*/
/*#define BSP_USING_ADC2*/
/*#define BSP_USING_ADC3*/
/-------------------------- ADC CONFIG END --------------------------/
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)函数:
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hadc->Instance==ADC1)
{
/* USER CODE BEGIN ADC1_MspInit 0 */
/* USER CODE END ADC1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**ADC1 GPIO Configuration
PA5 ------> ADC1_IN5
*/
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN ADC1_MspInit 1 */
/* USER CODE END ADC1_MspInit 1 */
}
}
三、I2C设备
I2C(Inter Integrated Circuit)总线是 PHILIPS 公司开发的一种半双工、双向二线制同步串行总线。
I2C 总线传输数据时只需两根信号线:
☐ 双向数据线 SDA
☐ 双向时钟线 SCL
电气连接:
时序:
协议:
单字节读:
多字节都:
单字节写:
多字节写:
3.1、访问I2C总线设备
☐ 查找 I2C 总线设备
3.1、 数据传输
#define RT_I2C_WR 0x0000
#define RT_I2C_RD (1u << 0)
struct rt_i2c_msg
{
rt_uint16_t addr;
rt_uint16_t flags;
rt_uint16_t len;
rt_uint8_t *buf;
};
rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus,
struct rt_i2c_msg msgs[],
rt_uint32_t num)
bh1750fvi数据手册:https://max.book118.com/html/2017/0626/118069213.shtm