该笔记类别主要是在自己学习时做的一些记录,方便自己很久不用忘掉时进行快速回忆
本文表述串口的使用,工程基于官方GIT代码库中的STM32F10X-HAL。
首先打开scons,进入rtt\bsp\stm32f10x-test目录下
运行
menuconfig
进入配置页面后,选择芯片种类,我这开使用的是STM32F103ZE系列,然后打开串口2(默认1是开启了的)
在编译工程
scons --target=mkd5
rt_kprintf调试打印接口
因为默认打开了串口1,系统的shell已经打印都被分配到了这个口上,直接烧写程序将会发现串口1进行如下打印
\ | /
- RT - Thread Operating System
/ | \ 3.1.1 build Sep 18 2018
2006 - 2018 Copyright by rt-thread team
main.c中应该就是一个空的主函数,这里其实应该叫做用户主函数,实际主函数不是它,具体在其他文章再讨论。这里系统封装了rt_kprintf函数,可以当做C中的printf用,例如
int main(void)
{
rt_kprintf("lissettecarlr\n");
return 0;
}
下载运行会发现,在串口1输出了这个字符串。
串口使用
不仅仅是串口,只要是按照设备操作接口编写的通讯外设都可以按照如下方式使用
- 根据设备名称查找该设备
- 绑定回调函数
- 打开设备
- 进行通讯
那么以串口为例,最简单的使用方式如下
static rt_err_t uart_intput(rt_device_t dev, rt_size_t size)
{
return RT_EOK;
}
static rt_device_t uart_device = RT_NULL;
static char* str ="lissettecarlr";
int main(void)
{
uart_device=rt_device_find("uart2");
rt_device_set_rx_indicate(uart_device, uart_intput);
rt_device_open(uart_device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX );
rt_device_write(uart_device, 0, str, strlen(str));
return 0;
}
上列代码没有进行错误判断,主要是对其使用驱动的几个步骤,所以还可以写成:
rt_err_t uart_open(const char *name)
{
rt_err_t res;
uart_device = rt_device_find(name);
if (uart_device != RT_NULL)
{
res = rt_device_set_rx_indicate(uart_device, uart_intput);
if (res != RT_EOK)
{
rt_kprintf("set %s rx indicate error.%d\n",name,res);
return ERROR;
}
res = rt_device_open(uart_device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX );
if (res != RT_EOK)
{
rt_kprintf("open %s device error.%d\n",name,res);
return ERROR;
}
}
else
{
rt_kprintf("can't find %s device.\n",name);
return -RT_ERROR;
}
return RT_EOK;
}
接下来针对上列函数简单说明一下
rt_device_set_rx_indicate(rt_device_t dev,rt_err_t (*rx_ind)(rt_device_t dev,rt_size_t size))
该函数主要绑定数据接收的回调函数,第二个参数是一个函数,rt_size_t size表示进入该回调时接收到的数据长度。进入回调后可以使用rt_device_read函数读取接收到的哪一个字节。例如测试可以写成这样
static rt_err_t uart_intput(rt_device_t dev, rt_size_t size)
{
int res=0;
rt_kprintf("size:%d\n",size);
res=rt_device_read(uart_device, 0, rcvBuff, 1);
if(res>0)
rt_kprintf("data:%d\n",rcvBuff[0]);
else
rt_kprintf("!!!!!");
return RT_EOK;
}
通过给串口2发送一个字节,串口1将会打印。该回调函数是在芯片读取到一个字节并且将其保存到了buffer中后才发生的,想要一次接收多个数据的话,只需要等待到多少次回调发生即可,还有就是在串口中进行打印是会打断后面数据接收的,如果仅仅想测试接收多个数据可以写成下列
static rt_err_t uart_intput(rt_device_t dev, rt_size_t size)
{
int res=0;
if(size>=5)
{
res=rt_device_read(uart_device, 0, rcvBuff, 5);
if(res>0)
{
for(int i=0;i<5;i++)
rt_kprintf("data:%02X ",rcvBuff[i]);
rt_kprintf("\n");
}
else
rt_kprintf("!!!!!");
}
return RT_EOK;
}
串口2发送5个字节,串口1将其打印。因为是笔记所以这些测试函数也就随便写,实际上数据接收回调接收到数据时,应该对外抛事件或者信号量,各种骚操作都不要写到这里面。
关于串口参数的修改
/* 串口设备句柄 */
static rt_device_t uart_device = RT_NULL;
/* 查找系统中的串口设备 */
uart_device = rt_device_find("uart1");
/* 串口配置结构体,使用serial.h的宏定义 */
struct serial_configure gps_use_config =
{
BAUD_RATE_9600, /* 9600 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 */
1024, /* Buffer size */
0
};
/* 先打开串口设备,才能修改 */
if (rt_device_open(device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX ) != RT_EOK)
{
rt_kprintf("uart open error.\n");
}
/* 修改串口配置参数 */
if (RT_EOK != rt_device_control(uart_device, RT_DEVICE_CTRL_CONFIG,(void *)&gps_use_config))
{
rt_kprintf("uart config baud rate failed.\n");
}
如果仅仅修改波特率可以如下
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
config.baud_rate = 115200;
rt_device_control(serial1, RT_DEVICE_CTRL_CONFIG, &config);
网友评论