作者:Mr_Minato
简单介绍:
在备赛全国大学生智能汽车竞赛的过程中基于逐飞无线串口的例程封装了三个懒人函数,实现了通过无线串口快速发送int型,float型数据,还有类似'printf'函数的功能。想实现这一功能其实还有很多方法,看个人喜好而定,我个人就比较喜欢这种简单的懒人式函数,如果有不同想法也欢迎交流。由于网上缺乏相关教程与资料,秉持着共同学习,共同进步的开源理念,将我封装的三个函数在此无条件免费分享给各位,也祝各位备赛顺利~
注意事项:在与逐飞交流后发现,我封装的这几个函数对运行速度是有一定折损的,如果不能接受的话可以去更改'printf'的映射端口,用printf函数直接发送数据到无线串口。如果可以接受速度损耗的话欢迎继续往下看。
有朋友说不会改printf的映射,我专门写了一个新手向的修改教程,可以参考一下~
http://t.csdnimg.cn/QnaJFhttp://t.csdnimg.cn/QnaJF
逐飞库中无线串口发送数据的原函数介绍:
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 无线转串口模块 发送数据块
// 参数说明 *buff 发送缓冲区
// 参数说明 len 发送数据长度
// 返回参数 uint32 剩余发送长度
// 使用示例 wireless_uart_send_buffer(buff, 64);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint32 wireless_uart_send_buffer (const uint8 *buff, uint32 len)
如果直接用该函数发送一个数据,该数据会被强制转换为16进制,并通过ASCII 编码在你的串口助手上以一些奇怪的结果出现,篇幅有限就不在这里演示了。为了方便大家使用,我采用了'sprintf'封装了三个函数,实现了数据的转换与发送,过程简单,可以直接调用。
具体功能实现函数:
1.使用无线串口发送整型(int类型)数据
函数名称:wireless_send_number(uint32_t number)
/**
* @brief 用无线串口发送int型数字
*
* @param number 要发送的int型数字
*本函数由Mr_Minato编写,免费开源,欢迎关注我的CSDN~
*/
void wireless_send_number(uint32_t number)
{
// 发送回车换行,用于分隔数据
wireless_uart_send_byte('\r');
wireless_uart_send_byte('\n');
// 定义一个缓冲区来存储转换后的ASCII码
char ascii_buffer[20]; // 假设最大的数字为20位
sprintf(ascii_buffer, "%d", number); // 将数字转换为字符串
uint32_t len = strlen(ascii_buffer); // 计算字符串的长度
wireless_uart_send_buffer((const uint8_t *)ascii_buffer, len); // 发送ASCII码缓冲区到串口
}
函数使用历程:
注意:本历程是基于逐飞库的CYT 4BB7芯片开发的,可以直接复制粘贴到空白的开源库中编译烧录测试。其他芯片比如TC264也都倒差不差,很容易移植,我就不示范了。
本历程定义了整形变量speed=1000,通过函数"wireless_send_number(uint32_t number)'发送到电脑,有过有问题欢迎评论区交流。
//引用逐飞库
#include "zf_common_headfile.h"
//声明咱们写的函数,可以放在自定义的头文件中
void wireless_send_number(uint32_t number);
//定义LED1的引脚
#define LED1 (P19_0)
//定义变量
uint32_t speed = 10086; // 定义并赋值 speed 变量
int main(void)
{
clock_init(SYSTEM_CLOCK_250M); // 时钟配置及系统初始化<务必保留>
debug_info_init(); // 调试串口信息初始化
// 此处编写用户代码 例如外设初始化代码等
gpio_init(LED1, GPO, GPIO_HIGH, GPO_PUSH_PULL); // 初始化 LED1 输出 默认高电平 推挽输出模式
if(wireless_uart_init()) // 判断无线串口是否通过初始化
{
while(1)
{ // 初始化失败就在这进入死循环
gpio_toggle_level(LED1); // 翻转 LED 引脚输出电平 控制 LED 亮灭
system_delay_ms(100); // 短延时快速闪灯表示异常
}
}
wireless_uart_send_byte('\r');
wireless_uart_send_byte('\n');
wireless_uart_send_string("SEEKFREE wireless uart demo.\r\n"); // 初始化正常 输出测试信息
// 此处编写用户代码 例如外设初始化代码等
while(true) {
// 此处编写需要循环执行的代码
// 发送 speed 数据
wireless_send_number(speed);
system_delay_ms(50);
// 此处编写需要循环执行的代码
}
}
void wireless_send_number(uint32_t number) //用无线串口发送int型数字
{
// 发送回车换行,用于分隔数据
wireless_uart_send_byte('\r');
wireless_uart_send_byte('\n');
// 定义一个缓冲区来存储转换后的ASCII码
char ascii_buffer[20]; // 假设最大的数字为20位
sprintf(ascii_buffer, "%d", number); //将数字转换为字符串
uint32_t len = strlen(ascii_buffer); // 计算字符串的长度
wireless_uart_send_buffer((const uint8_t *)ascii_buffer, len); // 发送ASCII码缓冲区到串口
}
2.使用无线串口发送浮点型(float、double类型)数据
函数名称:wireless_send_number(uint32_t number)
/**
* @brief 用无线串口发送 double 数据
*
* @param number 要发送的 double 类型数字
* 本函数由Mr_Minato编写,免费开源,欢迎关注我的CSDN~
*/
void wireless_send_double(double number) //用无线串口发送double数据
{
wireless_uart_send_byte('\r');
wireless_uart_send_byte('\n');// 发送回车换行,用于分隔数据
char ascii_buffer[30]; // 定义一个缓冲区来存储转换后的ASCII码,假设最大的double值有30个字符长度
sprintf(ascii_buffer, "%lf", number);// 将double类型数字转换为字符串
uint32_t len = strlen(ascii_buffer);// 计算字符串的长度
wireless_uart_send_buffer((const uint8_t *)ascii_buffer, len);// 发送ASCII码缓冲区到串口
}
函数使用示例:
本历程写的比较简单,自行理解即可。
// 使用示例
int main(void)
{
// 其他初始化代码
// 定义一个 double 类型的变量并赋值
double data = 3.14;
// 循环执行代码
while(true)
{
// 发送 double 数据
wireless_send_double(data);
// 延时
system_delay_ms(50);
}
}
3.使用无线串口实现类似'printf'功能
函数名称:void send_data_to_uart(const char *format, ...)
这是今天的硬菜,既然都看到这里了,不妨点个赞,点个收藏,点个关注,鼓励鼓励我吧~
/**
*本函数由Mr_Minato编写,免费开源,欢迎关注我的CSDN~
* @brief 发送数据到串口函数
*
* @param format 格式化字符串,支持以下格式说明符:
* - %d: 用于发送int类型数据
* - %f: 用于发送double类型数据
* - 其他字符直接发送到串口
* @param ... 可变参数列表,根据格式化字符串中的格式说明符传递相应类型的参数
*example:
* send_data_to_uart("This is an integer: %d\r\n", 123);
* send_data_to_uart("This is a float: %f\r\n", 3.14);
*/
void send_data_to_uart(const char *format, ...)
{
va_list args;
va_start(args, format); // 初始化可变参数列表
char buffer[64]; // 用于存储转换后的数据
// 遍历格式化字符串中的每个字符
while (*format) {
if (*format == '%') {
format++; // 移动到格式说明符的下一个字符
// 根据格式说明符判断参数类型
switch (*format) {
case 'd': {
int num = va_arg(args, int); // 获取int类型参数
// 将int类型转换为ASCII码
sprintf(buffer, "%d", num);
// 发送到串口
wireless_uart_send_buffer((const uint8_t *)buffer, strlen(buffer));
break;
}
case 'f': {
double dbl = va_arg(args, double); // 获取double类型参数
// 将double类型转换为ASCII码
sprintf(buffer, "%.6f", dbl); // %.6f表示保留六位小数
// 发送到串口
wireless_uart_send_buffer((const uint8_t *)buffer, strlen(buffer));
break;
}
// 可以添加其他格式说明符以支持更多数据类型
}
} else {
// 如果不是格式说明符,则直接发送字符到串口
wireless_uart_send_byte(*format);
}
format++; // 移动到下一个字符
}
va_end(args); // 结束可变参数列表
}
函数使用示例:
// 引用逐飞库
#include "zf_common_headfile.h"
// 声明咱们写的函数,可以放在自定义的头文件中
void send_data_to_uart(const char *format, ...);
// 定义LED1的引脚
#define LED1 (P19_0)
int main(void)
{
clock_init(SYSTEM_CLOCK_250M); // 时钟配置及系统初始化<务必保留>
debug_info_init(); // 调试串口信息初始化
// 此处编写用户代码,例如外设初始化代码等
gpio_init(LED1, GPO, GPIO_HIGH, GPO_PUSH_PULL); // 初始化 LED1 输出,默认高电平,推挽输出模式
if (wireless_uart_init()) // 判断无线串口是否通过初始化
{
while (1)
{ // 初始化失败就在这进入死循环
gpio_toggle_level(LED1); // 翻转 LED 引脚输出电平,控制 LED 亮灭
system_delay_ms(100); // 短延时快速闪灯表示异常
}
}
wireless_uart_send_byte('\r');
wireless_uart_send_byte('\n');
wireless_uart_send_string("SEEKFREE wireless uart demo.\r\n"); // 初始化正常,输出测试信息
// 此处编写用户代码,例如外设初始化代码等
while (true)
{ // 此处编写需要循环执行的代码
// 发送数据示例
send_data_to_uart("Speed: %d\r\n", 10086);
send_data_to_uart("Temperature: %f\r\n", 25.5);
system_delay_ms(1000);
// 此处编写需要循环执行的代码
}
}
感谢你看到最后,希望我写的代码对你能有所帮助。
如果还有问题欢迎评论区留言讨论,如果喜欢请点个收藏加关注~
祝各位朋友备赛顺利~