前言
前面记录了 ART-PI点亮OLED显示屏,我就发现,只能通过shell命令点亮OLED显示屏,那么如果说让OLED显示屏像创建一个线程那样,就会涉及到很多问题。这里我使用的开发工具是studio。
1.重新创建display.cpp文件
为什么要创建Cpp文件呢,基于OLED软件包,我发现软件包的以下代码在.c文件是识别不出来的,会报错,具体为什么还不清楚。
static U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0,\
/* clock=*/ OLED_I2C_PIN_SCL,\
/* data=*/ OLED_I2C_PIN_SDA,\
/* reset=*/ U8X8_PIN_NONE);
// All Boards without Reset of the Display
为什么要重新创建cpp文件呢,也是因为要重新写一个函数,看软件包中实例代码,需要传两个参数,参数具体是什么不清楚,但是如果想调用的话还需要传参,太麻烦!直接重新改。
static void u8g2_ssd1306_12864_sw_i2c_example(int argc,char * argv[])
在applications中使用创建display.cpp文件,将软件包sample代码复制过来,修改得到如下:
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <U8g2lib.h>
/*#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <U8g2lib.h>
#include <stdio.h>
#include <drv_soft_i2c.h>*/
#include "drv_common.h"
// You may reference Drivers/drv_gpio.c for pinout
// In u8x8.h #define U8X8_USE_PINS
#define OLED_I2C_PIN_SCL GET_PIN(H, 11)
#define OLED_I2C_PIN_SDA GET_PIN(H, 12)
// Check https://github.com/olikraus/u8g2/wiki/u8g2setupcpp for all supported devices
static U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0,\
/* clock=*/ OLED_I2C_PIN_SCL,\
/* data=*/ OLED_I2C_PIN_SDA,\
/* reset=*/ U8X8_PIN_NONE);
// All Boards without Reset of the Display
void oled_display()
{
while(1){
rt_kprintf("123");
u8g2.begin();
u8g2.clearBuffer(); // clear the internal memory
u8g2.setFont(u8g2_font_6x13_tr); // choose a suitable font
u8g2.drawStr(0, 18, "Welcome2018!"); // write something to the internal memory
u8g2.sendBuffer(); // transfer internal memory to the display
u8g2.setFont(u8g2_font_unifont_t_symbols);
u8g2.drawGlyph(112, 56, 0x2603 );
u8g2.sendBuffer();
rt_thread_mdelay(500);
u8g2.clearBuffer(); // clear the internal memory
u8g2.setFont(u8g2_font_6x13_tr); // choose a suitable font
u8g2.drawStr(0, 18, "Welcome2019!"); // write something to the internal memory
u8g2.sendBuffer(); // transfer internal memory to the display
u8g2.setFont(u8g2_font_unifont_t_symbols);
u8g2.drawGlyph(112, 56, 0x2603 );
u8g2.sendBuffer();
rt_thread_mdelay(500);
}
}
后来发现,这个函数在软件包的示例代码里面写也是没问题的!
那么问题来了,在main.c中调用cpp文件中的函数是行不通的,会报错。
2.解决.c中调用.cpp中函数的方法
在.cpp中需要调用的函数前面加上extern “C” 即可,在.c中调用这个方法也不需要包含头文件,直接调用,干就完了,第一次编译会有一个warning(隐式声明),第二次就不会报错了。
实例:
在.cpp
extern "C" void oled_display(){
......................
}
在其他.c文件中直接调用
oled_display();
3. 创建OLED线程
在applactions中创建oled.c和oled.h文件,代码如下:
oled.h文件
#ifndef APPLICATIONS_OLED_H_
#define APPLICATIONS_OLED_H_
static void thread2_entry(void *param);
int thread_sample(void);
#endif /* APPLICATIONS_OLED_H_ */
oled.c文件
#include <rtthread.h>
#define THREAD_PRIORITY 25
#define THREAD_STACK_SIZE 512
#define THREAD_TIMESLICE 5
ALIGN(RT_ALIGN_SIZE)
static char thread2_stack[1024];
static struct rt_thread thread2;
/* 线程 2 入口 */
static void thread2_entry(void *param)
{
oled_display();
}
int thread_oled(void)
{
/* 初始化线程 2,名称是 thread2,入口是 thread2_entry */
rt_thread_init(&thread2,
"thread2",
thread2_entry,
RT_NULL,
&thread2_stack[0],
sizeof(thread2_stack),
THREAD_PRIORITY - 1, THREAD_TIMESLICE);
rt_thread_startup(&thread2);//启动线程
return 0;
}
在main.c中启动oled线程函数
#include "
void mian(){
thread_oled(void);
}
注:需要在构建配置里面设置包含的头文件路径!