目录
本系列博客所述资料均来自合宙官方
,并不是本人原创(只有博客是自己写的),csdk只是得到了口头的允许公开授权
。出于热心,本人将自己的所学笔记整理并推出相对应的使用教程,方面其他人学习。为国内的物联网事业发展尽自己的一份绵薄之力,没有为自己谋取私利的想法
。若出现侵权现象,请告知本人,本人会立即停止更新,并删除相应的文章和代码。
本系列博客基于紫光展锐的RDA8910 LTE Cat 1
bis芯片平台开发。理论上适用于合宙的Air720U、Air724U、广和通L610以及安信可的cat-01模块。
各个厂家的部分配置文件可能不一样,也许会导致设备出现奇怪的问题,其他的模块我也不确定能不能用,自行测试。但是有一点编译下载和监视流程基本一样
,可供参考。
先不管支不支持,如果你用的模块是是紫光展锐的RDA8910,那都不妨一试,也许会有意外收获(也有可能变砖,慎重!!!
)。
我使用的是Air724UG
开发板,如果在其他模块上不能用,那也不要强怼,也许是开发包不兼容吧。这里的代码是没有问题的。例程仅供参考!
一、前言
有几个月没写文章了,有点手生,拿起键盘都不知道要说点啥。其实这篇文章对应的代码去年就写好了,只是最近几个月实在是太忙了,一直没时间写一下教程(实际是忘了)。
看到群里最近几天又有小伙伴问724支不支持触摸屏啊,突然就想到了去年闲的时候适配一个电阻屏,翻了半天垃圾堆可算是找到了屏幕,幸好没有被当作垃圾卖掉。于是赶在5月1号前把代码整理了一下,抽点时间把这篇文章写了出来。好让好伙伴们在劳动节好好在家学习,别天天打游戏,影响我上分。
咱们小时候玩过的手机如果支持触摸屏的话,基本上用的都是电阻屏。而电阻屏都是需要校准才能使用的。手机一般情况下啊在出厂的时候都会进行一次校准将校准参数保存起来后面直接读取就行。但是使用的时间长了之后,多多少少都会出现触摸不灵敏的情况。这时候就需要重新校准,拿一枝笔对着准星点几下就OK。
这样就需要画一些简单的界面,虽然说CSDK现在支持了LVGL。但是,我研究了半天也没画出来,实在是麻烦。想着干脆弄一个简单的GUI库算了,画画圆、直线、点、矩形、简单的颜色填充、显示文字,也就够用了,于是在适配触摸屏之前,就先花了点时间弄了个简单的GUI库。这边文章主要就是讲GUI相关的内容。
二、硬件连接
ILI9341本文所选用的LCD是由ILI9341
进行驱动的,当然你也可以选择其他的LCD,只要改下对应的初始化序列就行了,其他的都不用动,先简单说下LCD与724之间的硬件连接。
屏幕上LCD显示和触摸功能是分开的,两者之间没有必然的联系。其中SDO(spi输出)、LED(背光)、SCK(时钟)、SDI(spi输入)、DC(数据/指令切换)、RESET(复位)、CS(片选)、GND、VCC是LCD显示所用到的。
我们这边没有用到背光控制,所以直接把LED和VCC接在一起,SDO直接浮空,不用接。连线对应的是:
ILI9341 | 724开发板 |
---|---|
LED&VCC | V_LCD |
GND | GND |
SCK | LCD_CLK |
CS | LCD_CS |
DC | LCD_RS |
SDI | LCD_DIO |
三、了解本例程所涉及到的函数
使用该GUI需要包含#include "lcd.h"头文件,我们这里的库函数包含14个函数,分别是:
/**//设置一些必要的函数以及参数,可以理解为初始化函数
**/
- void
LCD_Setup
(APP_LCD_DATA *lcd_data);
/**刷屏调用这个函数
**/
- void
LCD_Refresh_Gram
();
//在指定位置画一个指定大小的圆
//(x,y):中心点
//r :半径
- void
LCD_Draw_Circle
(u16 x0, u16 y0, u8 r);
//画矩形
//(x1,y1),(x2,y2):矩形的对角坐标
- void
LCD_DrawRectangle
(u16 x1, u16 y1, u16 x2, u16 y2);
//两点间画线功能
//x1:直线的起始x坐标
//y1:直线的起始y坐标
//x2:直线的结束x坐标
//y2:直线的结束y坐标
- void
LCD_DrawLine
(u16 x1, u16 y1, u16 x2, u16 y2);
//设置画笔颜色
- void
LCD_SetPointColor
(APP_LCD_PIXEL_2BYTES_COLOR color);
//设置背景颜色
- void
LCD_SetBackColor
(APP_LCD_PIXEL_2BYTES_COLOR color);
//画点
//x:0~240
//y:0~320
//t:1 填充 0,清空
- void
LCD_DrawPoint
(int x, int y, uint8_t t);
//画一个大点(2*2的点)
//x,y:坐标
- void
LCD_Draw_Big_Point
(u16 x, u16 y);
//在指定区域内填充颜色
- void
LCD_Fill
(T_AMOPENAT_LCD_RECT_T *rect, uint8_t mode);
//清屏函数,按照背景颜色清屏
- void
LCD_Clear
(void);
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//size:选择字体 12/16/24
//mode:0,反白显示;1,正常显示
- void
LCD_ShowChar
(int x, int y, uint8_t chr, uint8_t size, uint8_t mode);
//显示字符串
//x,y:起点坐标
//*p:字符串起始地址
//size:字体大小
- void
LCD_ShowString
(int x, int y, const uint8_t *p, uint8_t size);
//显示数字
//x,y :起点坐标
//num:数值(0~4294967295);
//len :数字的位数
//size:字体大小
- void
LCD_ShowNum
(int x, int y, uint32_t num, uint8_t len, uint8_t size);
四、编写程序
编写初始化代码,本GUI库剥离了硬件限制,在库中不包含硬件的相关操作。在初始化代码中需要传入LCD的宽(240)
、LCD的高(320)
、LCD的像素位深(2字节,16位色深)
、画笔颜色(2字节黑色)
、背景颜色(2字节白色)
、LCD的初始化代码
、LCD的刷屏代码
,最后初始化完成后创建一个测试的task循环刷屏。
int appimg_enter(void *param)
{
iot_debug_set_fault_mode(OPENAT_FAULT_HANG);
//打开调试信息,默认关闭
iot_vat_send_cmd((UINT8 *)"AT^TRACECTRL=0,1,1\r\n", sizeof("AT^TRACECTRL=0,1,1\r\n"));
iot_debug_print("[hello]appimg_enter");
APP_LCD_DATA lcd_data;
lcd_data.lcd_width = LCD_WIDTH;
lcd_data.lcd_heigh = LCD_HEIGH;
lcd_data.lcd_pixel_bytes = LCD_PIXEL_BYTES;
lcd_data.lcd_point_color = PIXEL_2BYTES_BLACK;
lcd_data.lcd_back_color = PIXEL_2BYTES_WHITE;
lcd_data.lcd_init = lcdInit;
lcd_data.lcd_screen = lcdScreen;
LCD_Setup(&lcd_data);
iot_os_create_task(app_lcd_test, NULL, 1024, 1, OPENAT_OS_CREATE_DEFAULT, "app_lcd_test");
return 0;
}
LCD的init直接在里面填入合宙的LCD初始化函数即可,lcdRegTable代表的是LCD的初始化序列。
BOOL lcdInit(void)
{
iot_pmd_poweron_ldo(OPENAT_LDO_POWER_VLCD, 15);
T_AMOPENAT_COLOR_LCD_PARAM param = {0};
param.width = LCD_WIDTH;
param.height = LCD_HEIGH;
param.msgCallback = NULL;
param.bus = OPENAT_LCD_SPI4LINE;
param.lcdItf.spi.frequence = 50000000;
iot_lcd_color_init(¶m);
write_command_table(lcdRegTable, sizeof(lcdRegTable) / sizeof(int));
return TRUE;
}
初始化序列如下,不同的屏幕初始化序列不一样。我这里使用的屏幕LCD驱动芯片是ILI9341
,初始化序列在芯片的驱动手册上都会有的,视情况而定。
const UINT32 lcdRegTable[] =
{
0x00010090,
0x11,
0x00010090,
0xCF,
0x00030000,
0x00030099,
0x00030030,
0xED,
0x00030064,
0x00030003,
0x00030012,
0x00030081,
0xCB,
0x00030039,
0x0003002C,
0x00030000,
0x00030034,
0x00030002,
0xEA,
0x00030000,
0x00030000,
0xE8,
0x00030085,
0x00030000,
0x00030078,
0xC0,
0x00030023,
0xC1,
0x00030012,
0xC2,
0x00030011,
0xC5,
0x00030040,
0x00030030,
0xC7,
0x000300A9,
0x3A,
0x00030055,
0x36,
0x00030008,
0xB1,
0x00030000,
0x00030018,
0xB6,
0x0003000A,
0x000300A2,
0xF2,
0x00030000,
0xF7,
0x00030020,
0x26,
0x00030001,
0xE0,
0x0003001F,
0x00030024,
0x00030023,
0x0003000B,
0x0003000F,
0x00030008,
0x00030050,
0x000300D8,
0x0003003B,
0x00030008,
0x0003000A,
0x00030000,
0x00030000,
0x00030000,
0x00030000,
0xE1,
0x00030000,
0x0003001B,
0x0003001C,
0x00030004,
0x00030010,
0x00030007,
0x0003002F,
0x00030027,
0x00030044,
0x00030007,
0x00030015,
0x0003000F,
0x0003003F,
0x0003003F,
0x0003001F,
0x29,
};
调用write_command_table
函数写入初始化序列。
static void write_command_table(const UINT32 *table, UINT16 size)
{
UINT16 flag;
UINT16 value;
UINT16 index;
for (index = 0; index < size && table[index] != (UINT32)-1; index++)
{
flag = table[index] >> 16;
value = table[index] & 0xffff;
switch (flag)
{
case 1:
iot_os_sleep(value);
break;
case 0:
case 2:
iot_lcd_write_cmd(value & 0x00ff);
break;
case 3:
iot_lcd_write_data(value & 0x00ff);
break;
default:
break;
}
}
}
刷屏代码一句话,填上去,直接刷就行。
BOOL lcdScreen(T_AMOPENAT_LCD_RECT_T *rect, UINT16 *pDisplayBuffer)
{
iot_lcd_update_color_screen(rect, pDisplayBuffer);
}
刷屏函数编写。依次执行,清屏、设置画笔颜色为黑色、在10,0处以24号字体显示一个字符“1”、设置画笔颜色为蓝色、在10,30处以24号字体显示一个字符串“hello”、设置画笔颜色为红色、在10,60处以24号字体显示一个数字123、设置画笔颜色为黄色、在某一个区域画一个矩形最后刷屏,一秒钟刷一次。
void app_lcd_test()
{
while (1)
{
LCD_Clear(); //清屏
LCD_SetPointColor(PIXEL_2BYTES_BLACK);
LCD_ShowChar(10, 0, '1', 24, 1);
LCD_SetPointColor(PIXEL_2BYTES_BLUE);
LCD_ShowString(10, 30, "hello", 24);
LCD_SetPointColor(PIXEL_2BYTES_RED);
LCD_ShowNum(10, 60, 123, 3, 24);
LCD_SetPointColor(PIXEL_2BYTES_YELLOW);
T_AMOPENAT_LCD_RECT_T rect = {0};
rect.ltX = 50;
rect.ltY = 150;
rect.rbX = rect.ltX + 50;
rect.rbY = rect.ltY + 50;
LCD_Fill(&rect, 1);
LCD_Refresh_Gram();
iot_os_sleep(1000);
}
}
五、编译并下载程序
完整代码在这,自取。
/***************
demo_hello
****************/
#include <string.h>
#include "iot_debug.h"
#include "iot_os.h"
#include "iot_lcd.h"
#include "iot_pmd.h"
#include "am_openat_drv.h"
#include "lcd.h"
#define LCD_WIDTH 240
#define LCD_HEIGH 320
#define LCD_PIXEL_BYTES 2 //两字节16色
const UINT32 lcdRegTable[] =
{
0x00010090,
0x11,
0x00010090,
0xCF,
0x00030000,
0x00030099,
0x00030030,
0xED,
0x00030064,
0x00030003,
0x00030012,
0x00030081,
0xCB,
0x00030039,
0x0003002C,
0x00030000,
0x00030034,
0x00030002,
0xEA,
0x00030000,
0x00030000,
0xE8,
0x00030085,
0x00030000,
0x00030078,
0xC0,
0x00030023,
0xC1,
0x00030012,
0xC2,
0x00030011,
0xC5,
0x00030040,
0x00030030,
0xC7,
0x000300A9,
0x3A,
0x00030055,
0x36,
0x00030008,
0xB1,
0x00030000,
0x00030018,
0xB6,
0x0003000A,
0x000300A2,
0xF2,
0x00030000,
0xF7,
0x00030020,
0x26,
0x00030001,
0xE0,
0x0003001F,
0x00030024,
0x00030023,
0x0003000B,
0x0003000F,
0x00030008,
0x00030050,
0x000300D8,
0x0003003B,
0x00030008,
0x0003000A,
0x00030000,
0x00030000,
0x00030000,
0x00030000,
0xE1,
0x00030000,
0x0003001B,
0x0003001C,
0x00030004,
0x00030010,
0x00030007,
0x0003002F,
0x00030027,
0x00030044,
0x00030007,
0x00030015,
0x0003000F,
0x0003003F,
0x0003003F,
0x0003001F,
0x29,
};
static void write_command_table(const UINT32 *table, UINT16 size)
{
UINT16 flag;
UINT16 value;
UINT16 index;
for (index = 0; index < size && table[index] != (UINT32)-1; index++)
{
flag = table[index] >> 16;
value = table[index] & 0xffff;
switch (flag)
{
case 1:
iot_os_sleep(value);
break;
case 0:
case 2:
iot_lcd_write_cmd(value & 0x00ff);
break;
case 3:
iot_lcd_write_data(value & 0x00ff);
break;
default:
break;
}
}
}
BOOL lcdInit(void)
{
iot_pmd_poweron_ldo(OPENAT_LDO_POWER_VLCD, 15);
T_AMOPENAT_COLOR_LCD_PARAM param = {0};
param.width = LCD_WIDTH;
param.height = LCD_HEIGH;
param.msgCallback = NULL;
param.bus = OPENAT_LCD_SPI4LINE;
param.lcdItf.spi.frequence = 50000000;
iot_lcd_color_init(¶m);
write_command_table(lcdRegTable, sizeof(lcdRegTable) / sizeof(int));
return TRUE;
}
BOOL lcdScreen(T_AMOPENAT_LCD_RECT_T *rect, UINT16 *pDisplayBuffer)
{
iot_lcd_update_color_screen(rect, pDisplayBuffer);
}
void app_lcd_test()
{
while (1)
{
LCD_Clear(); //清屏
LCD_SetPointColor(PIXEL_2BYTES_BLACK);
LCD_ShowChar(10, 0, '1', 24, 1);
LCD_SetPointColor(PIXEL_2BYTES_BLUE);
LCD_ShowString(10, 30, "hello", 24);
LCD_SetPointColor(PIXEL_2BYTES_RED);
LCD_ShowNum(10, 60, 123, 3, 24);
LCD_SetPointColor(PIXEL_2BYTES_YELLOW);
T_AMOPENAT_LCD_RECT_T rect = {0};
rect.ltX = 50;
rect.ltY = 150;
rect.rbX = rect.ltX + 50;
rect.rbY = rect.ltY + 50;
LCD_Fill(&rect, 1);
LCD_Refresh_Gram();
iot_os_sleep(1000);
}
}
int appimg_enter(void *param)
{
iot_debug_set_fault_mode(OPENAT_FAULT_HANG);
//打开调试信息,默认关闭
iot_vat_send_cmd((UINT8 *)"AT^TRACECTRL=0,1,1\r\n", sizeof("AT^TRACECTRL=0,1,1\r\n"));
iot_debug_print("[hello]appimg_enter");
APP_LCD_DATA lcd_data;
lcd_data.lcd_width = LCD_WIDTH;
lcd_data.lcd_heigh = LCD_HEIGH;
lcd_data.lcd_pixel_bytes = LCD_PIXEL_BYTES;
lcd_data.lcd_point_color = PIXEL_2BYTES_BLACK;
lcd_data.lcd_back_color = PIXEL_2BYTES_WHITE;
lcd_data.lcd_init = lcdInit;
lcd_data.lcd_screen = lcdScreen;
LCD_Setup(&lcd_data);
iot_os_create_task(app_lcd_test, NULL, 1024, 1, OPENAT_OS_CREATE_DEFAULT, "app_lcd_test");
return 0;
}
void appimg_exit(void)
{
iot_debug_print("[hello]appimg_exit");
}
六、下载验证
实验效果如下,显示正常。
不会下载的点击这里,进去查看我的
RDA8910 CSDK二次开发入门教程
专题第一篇博文1、RDA8910CSDK二次开发:环境搭建
里面讲了怎么下载
这里只是我的学习笔记,拿出来给大家分享,欢迎大家批评指正,本篇教程到此结束