TencentOS-tiny官方开发板EVB_MX上手Demo

零、 序

由于基础理论不扎实,在上手过程中出现了各种非常规状况,导致很多时候一度无法继续学习。不过好在坚持了下来,并且将其一一击破,转化为了自己的经验与知识。

可能有些点在别人看来微不足道,但是每个人都是从小白过来的不是吗?不积跬步,无以至千里;不积小流,无以成江海。

以此劝戒自己。

一、问题清单

首先列举一下我遇到的几个问题:

  • 浮点类型:交叉编译器对浮点类型的支持

  • AT指令:相关命令的执行与反馈

  • 代码包含问题:函数的声明与实现差异

  • 代码洁癖:对几个编译时发现的warning的修复

以上几个问题,我将穿插在下文中详细说明。

二、上手Demo

话不多说,逐个击破

1、板载LED

这个LED是接在GPIOC13上,主要是为了学习GPIO的使用。使用的方式很简单:

定义:

void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);

使用:

HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, 0); // 0:关 1:开

2、板载OLED

之前没有使用过OLED,刚上手有点懵的,但是好在官方代码很好理解,看一下就明白了。

void OLED_Init(void); // 初始化

void OLED_Clear(void); // 清除屏幕

void OLED_Display_On(void); // 打开显示功能

void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size); // 向屏幕输出数字

void OLED_ShowString(uint8_t x,uint8_t y, uint8_t *p,uint8_t Char_Size); // 向屏幕输出字符

void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no); // 向屏幕输出汉字

void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]); // 向屏幕输出图片

这里最开始使用的时候会有些不太清楚,主要是x和size的值不太确定。以 OLED_ShowNum举例:

x表示横向坐标,y表示行,num是需要输出的数字,size则是输出的字号

每一个字符的显示,是占用了8位,所以如果我想紧密显示内容,则需要这样:

OLED_ShowString(0, 0, "Lux:", strlen("Lux:"));

OLED_ShowNum(8 * strlen("Lux:"), 0, (int)E53_IA1_Data.Lux, 4, 12); //第四个参数4 表示最多显示4位数字,第五个参数12则表示字号使用12号。

3、E53_IA1使用

这个模块是个智能农业的模块,上面带有温度、湿度、光强、灯光、马达 五组数据节点。

模块的使用非常简单:

Init_E53_IA1(); //初始化模块

E53_IA1_Read_Data(); //读取一次模块上所有节点的数据

printf("Lux:%f\r\n",E53_IA1_Data.Lux); //打印光强

printf("Humidity:%f\r\n",E53_IA1_Data.Humidity); //打印湿度

printf("Temperature:%f\r\n",E53_IA1_Data.Temperature); //打印温度

motor_control(1); //启动马达 0:关闭 1:启动

light_control(1); //打开灯光 0:关闭 1:打开

问题1:浮点类型:交叉编译器对(float)浮点类型的支持

在显示数据的过程中,我发现节点数据是浮点型,但是打印时却看不到数据!代码节选如下:

void e53_ia1_demo(void)
{
    Init_E53_IA1();
    while (1)
    {
        E53_IA1_Read_Data();
        printf("Lux \t\t%%f:(%f)\t\t(int):(%d)\r\n",
               E53_IA1_Data.Lux,
               (int)E53_IA1_Data.Lux
              );

        printf("Humidity \t%%f:(%f)\t\t(int):(%d)\r\n",
               E53_IA1_Data.Humidity,
               (int)E53_IA1_Data.Humidity
              );

        printf("Temperature \t%%f:(%f)\t\t(int):(%d)\r\n\r\n",
               E53_IA1_Data.Temperature,
               (int)E53_IA1_Data.Temperature
              );

        osDelay(1000);
    }
}

打印截图:

在这里插入图片描述

这个就很神奇了,之前在Linux上我并没有见过这种事情,于是搜索相关的资料,终于发现,这是跟交叉编译器的参数有关,默认没有使用浮点型!

于是在Makefile中添加参数 -u _printf_float 即可,重新编译运行后截图:

在这里插入图片描述

一切正常了。

4、esp8266联网

以上基础功能都熟悉之后,就准备进行联网了。本来想直接使用MQTT,后来想着路要一步一步走,所以我们先来跑一个UDP收发的Demo。

examples/udp_through_module下有UDP的Demo,我们就使用这个来进行测试。

01 使用方式

board/TencentOS_tiny_EVB_MX/GCC文件夹下创建 udp_through_module 文件夹;

board/TencentOS_tiny_EVB_MX/GCC/hello_world内容全部拷贝的到udp_through_module中;

打开 udp_through_module/Makefile 参考 board/TencentOS_tiny_EVB_MX/KEIL/udp_through_module/TencentOS_tiny.uvprojx 将对应的头文件和文件包含关系更新;

编译make,将编译好的bin下载到板子上。

02 结果

顺利的话,此时esp8266模块就可以正常运行和连接WIFI了,不过对应的WIFI名称和密码需要替换成自己可用的。
电脑端监听的端口也可以正常收到数据,不过给开发板发送数据时,需要注意查看开发板发送时用的哪个UDP端口,然后向对应的这个UDP端口发送数据即可。

问题2:AT指令:相关命令的执行与反馈

其实在调试网络这部分时,卡住了我很久,一直没有正常运行。后来在群友的指导下,我将板载串口跳线进行了调整。开发板上的插针图如下:

LP_RXLP_TX
AT_RXAT_TX
PC_RXPC_TX
U2_TXU2_RX

默认连接方式是:

LP_RX - AT_RX

PC_RX - U2_TX

LP_TX - AT_TX

PC_TX - U2_RX

这样我将电脑串口与esp8266的串口接起来进行了测试,即 AT_RX - PC_RX , AT_TX - PC_TX 。这样可以通过电脑端的串口工具直接通信。

但是我发现给串口发数据,不知怎地,最开始是什么数据都没有,又换了串口工具,发送 AT 有反应,但是发啥回啥,后来又换了个串口工具,忽然看到有个选项:NL和CR。瞬间想起来,很可能是因为回车和换行导致的数据不对。

经过查询,确实通过AT指令,每条指令后边必须要跟上 \r\n 命令,即 :先回车 再换行,需要确保正确的进行了回车和换行。

不过,经过测试,发现AT指令都正常工作的,esp8266模块可以正常使用。可是程序依然没有正确运行,又一度陷入困境。

问题3:代码包含问题:函数的声明与实现差异

模块是正常的,电脑直接接收板子发出的命令也是正常的,为什么他们直接连上就不行了呢?

困扰了我许久之后,突然想到,板子的串口接收我并没有测试到!

如果是板子的串口接收有问题,收不到数据呢?!

为了验证这个问题,我又新创建了一个项目(原项目是参考例程手工写的),然后编译运行了新项目,好使!

于是我将两个项目进行了对比,终于在Makefile中发现了不同:

board/TencentOS_tiny_EVB_MX/BSP/Src/stm32l4xx_it.c

board/TencentOS_tiny_EVB_MX/BSP/Src/stm32l4xx_it_module.c

包含文件进行编译的地方,原项目是包含的stm32l4xx_it.c;新项目包含的是stm32l4xx_it_module.c!

这两个文件的主要不同:

void LPUART1_IRQHandler(void)
{
    tos_knl_irq_enter();
    HAL_UART_IRQHandler(&hlpuart1);
    tos_knl_irq_leave();
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    extern uint8_t data;
    if (huart->Instance == LPUART1) {
        HAL_UART_Receive_IT(&hlpuart1, &data, 1);
        tos_at_uart_write_byte(data);
    }
}

原项目包含的 stm32l4xx_it.c 没有实现 HAL_UART_RxCpltCallback() 这个回调函数。怪不得怎么给esp8266模块发送AT指令都没有反应,原来是自己压根就没有开接收!

冷静下来想想,当时手敲代码时可能搜索包含头文件,没有注意到同一个函数名在不同的模块都有实现,而且实现的还不太一样导致的。

提醒我今后对于函数封装与调用需要仔细审查了,防止再出现这样的问题。

5、MQTT使用

因为现在申请的腾讯云还没有给我通过权限,暂时无法测试上云功能,所以我这先使用自己的MQTT服务器。

这里,我们通过官方Demo:examples/tencent_os_mqtt进行测试

01 使用方式

同esp8266联网的Demoudp_through_module一样,需要先将对应的文件创建和拷贝;

将对应的文件头文件包含进行更新;

编译、下载、运行。

02 结果

同样的,在对应代码的基础上,将 WIFI、MQTT服务器的IP、端口、topic等等信息更新为自己可用的之后,就可以顺利的看到订阅的topic收到了对应的温度、湿度、光强、灯光和马达状态数据,并且,可以下发控制数据,控制E53_IA1上的马达和灯光的运行状态。
整个流程下来非常顺畅,感觉非常舒服。

6、代码洁癖:对几个编译时发现的warning的修复

01 二维数组的{}

在编译Demo的时候,发现编译器会有这样的Warning:

在这里插入图片描述

missing braces around initializer

这里告诉我们缺少{},所以,我们找到对应的文件:board/TencentOS_tiny_EVB_MX/BSP/Hardware/OLED/oledfont.h 并将对应的大括号给添加上。

在这里插入图片描述

那么为什么会出现这个警告呢?因为这里实际是定义了一个不定长的二维数组,也就是说,行数是不确定,但是列必须确定,这里列就是6。但是,原来的代码并没有将每一列都用{}包含起来,有时候编译器不能够很聪明的识别出来,就警告我们:最好老实点加上大括号让我舒服的编译,要不非得吓唬吓唬你!

02 char和unsigned char

在编译E53_IA1的时候,看到了这么个warning:

在这里插入图片描述

array subscript has type char

这个问题则是因为在数组下标中用了char类型,但是在有的平台上默认的char是有符号的,也就是说,会是负数,这不符合数组的特性,所以,这里我们把 byteCtrl类型更改为unsigned char 即可。

在这里插入图片描述

03 for的{}

还有这样一处:

在这里插入图片描述

this ‘for’ clause does not guard…

到源码处看一下:vim board/TencentOS_tiny_EVB_MX/BSP/Hardware/OLED/oled.c +181

在这里插入图片描述

这个地方的排版看着有点奇怪啊?原来是因为缺少了{}的加成。也许原来这个地方是为了简洁,只有一行代码,省略了大括号,但后来加上新的一行代码,不自觉的进行了缩进吧。所以,这里我们更改一下:

在这里插入图片描述

加上大括号,改一下缩进,这样就明晰多了嘛!

三、结语

至此,开发板基本入门算是结束了,现在我对板载的一些资源都有了一定的认识,并且今后可以在Demo的基础上,做更多的功能和业务逻辑。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值