• 欢迎大家分享资料!前往留言板评论即可!

19、RDA8910(4GCAT1)CSDK二次开发:CSDK也能用触摸屏了–电阻屏适配(XPT2046采集ADC)

合宙 模组资料网 2年前 (2021-05-15) 696次浏览 0个评论 扫描二维码

目录

点击这里查看所有博文

  本系列博客所述资料均来自合宙官方,并不是本人原创(只有博客是自己写的),csdk只是得到了口头的允许公开授权。出于热心,本人将自己的所学笔记整理并推出相对应的使用教程,方面其他人学习。为国内的物联网事业发展尽自己的一份绵薄之力,没有为自己谋取私利的想法。若出现侵权现象,请告知本人,本人会立即停止更新,并删除相应的文章和代码。

  本系列博客基于紫光展锐的RDA8910 LTE Cat 1 bis芯片平台开发。理论上适用于合宙的Air720U、Air724U、广和通L610以及安信可的cat-01模块。

  各个厂家的部分配置文件可能不一样,也许会导致设备出现奇怪的问题,其他的模块我也不确定能不能用,自行测试。但是有一点编译下载和监视流程基本一样,可供参考。

  先不管支不支持,如果你用的模块是是紫光展锐的RDA8910,那都不妨一试,也许会有意外收获(也有可能变砖,慎重!!!)。

  我使用的是Air724UG开发板,如果在其他模块上不能用,那也不要强怼,也许是开发包不兼容吧。这里的代码是没有问题的。例程仅供参考!

一、前言

  上篇讲到了一个简单的LCD驱动库,这里就继续上篇的内容。先折腾一下触摸屏,我使用的LCD屏幕自带一个电阻式触摸屏,使用XPT2046芯片进行触摸采样。

  XPT2046是一个逐次逼近式的多路ADC采集芯片,一般情况下都是当作电阻触摸屏的驱动芯片来使用。当然你想用它单纯的采集ADC也不是不可以(成本有点高)。

在这里插入图片描述

  关于XPT2046芯片的介绍和电阻式触摸屏幕的工作原理我这里不再赘述,网上资料有很多。

1、XPT2046的使用

2、四线电阻触摸屏原理

  这个触摸屏的驱动还是个半成品,随手写的,支持多种驱动芯片也比较困难。就没有整理了,随便看看就行了。没有太大的参考价值,后面也不打算继续维护了。如果你正好在Air724上使用到了这种驱动芯片,那可以直接使用。

二、硬件连接

  屏幕上的触摸部分由XPT2046驱动,该元件可以使用SPI通信方式进行读取。

在这里插入图片描述

  从上图可以看到,负责触摸功能的引脚有T_IRQ(采集中断输出)、T_DO(spi输出)、T_DIN(spi输入)、T_CS(片选)、T_CLK(时钟)五根线。

xpt2046 724开发板
T_IRQ IO_23
T_DO SPI_IN
T_DIN SPI_OUT
T_CS SPI_CS0
T_CLK SPI_CLK

  XPT2046的工作电压范围为 2.2V~5.25V。而724的SPI引脚电压域是V_GLOBAL_1V8,最高输出V_GLOBAL_1V8*0.7V,显然不能满足工作电压最低需要。直接驱动是驱动不了的。

在这里插入图片描述

  这里为了节省时间我使用了一个8位的跟随器YF08E(又称双向电压电平转换器)进行点平转化。

在这里插入图片描述

  连接效果如图.

在这里插入图片描述

三、了解本例程所涉及到的函数

  使用该触摸屏驱动文件需要包含#include “res_touch.h”头文件,我们这里的驱动文件包含4个函数,分别是:

读取屏幕的校准参数

  • BOOL TP_Read_Adjdata(void);

读取屏幕的上实时点击的坐标

  • BOOL TP_Read_Screen_XY(u16 *x, u16 *y);

进行屏幕校准,校准成功后会自动保存校准参数

  • BOOL Touch_Adjust(void);

触摸屏初始化

  • void Touch_init(void);

四、编写程序

  编写初始化代码,由于触摸屏需要进行校准,在触摸屏内部使用到了LCD的相关函数,所以和上篇一样,需要完成初始化LCD。最后初始化完成后创建一个res_touch_test进行触摸屏的相关初始化。

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(res_touch_test, NULL, 2048, 1, OPENAT_OS_CREATE_DEFAULT, "res_touch_test");

    return 0;
}

  res_touch_test函数中首先尝试读取校准参数。如果校准参数读取失败,就会调用校准函数触发触摸屏的校准流程。确认校准有效后,会自动将校准参数存储到文件系统中,以供下次开机加载使用。

  注意:第一次下载文件系统内肯定没有相关的记录,所以必须校准。校准成功后,后续的启动都不需要校准,可以直接使用。

  获取校准参数完成后,会创建一个任务,用于刷屏。最后在死循环中,循环读取触摸屏的实时触摸位置,并写入到LCD的缓存,10ms读取一次。

static void res_touch_test(PVOID pParameter)
{
    LCD_Clear(); //清屏
    LCD_Refresh_Gram();
    Touch_init();
    if (TP_Read_Adjdata() == FALSE)
    {
        while (Touch_Adjust() == FALSE)
            iot_os_sleep(1000);
    }

    iot_os_create_task(res_touch_test2, NULL, 2048, 1, OPENAT_OS_CREATE_DEFAULT, "res_touch_test");
    while (1)
    {
        u16 x, y;
        if(!TP_Read_Screen_XY(&x, &y))
            continue;

        LCD_Draw_Big_Point(x, y);
        iot_os_sleep(10);
    }
}

  创建res_touch_test2时也就是校准成功的时候,进行清屏,然后在死循环中循环刷屏,更新显存中的内容。100ms刷新一次屏幕。

static void res_touch_test2(PVOID pParameter)
{
    LCD_Clear(); //清屏
    LCD_Refresh_Gram();
    while (1)
    {
        LCD_Refresh_Gram();
        iot_os_sleep(100);
    }
}

五、编译并下载程序

  完整代码在这,自取。

/***************
    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"
#include "res_touch.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(&param);
    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);
    }
}


static void res_touch_test2(PVOID pParameter)
{
    LCD_Clear(); //清屏
    LCD_Refresh_Gram();
    while (1)
    {
        LCD_Refresh_Gram();
        iot_os_sleep(100);
    }
}

static void res_touch_test(PVOID pParameter)
{
    LCD_Clear(); //清屏
    LCD_Refresh_Gram();
    Touch_init();
    if (TP_Read_Adjdata() == FALSE)
    {
        while (Touch_Adjust() == FALSE)
            iot_os_sleep(1000);
    }

    iot_os_create_task(res_touch_test2, NULL, 2048, 1, OPENAT_OS_CREATE_DEFAULT, "res_touch_test");
    while (1)
    {
        u16 x, y;
        if(!TP_Read_Screen_XY(&x, &y))
            continue;

        LCD_Draw_Big_Point(x, y);
        iot_os_sleep(10);
    }
}


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");

    iot_os_create_task(res_touch_test, NULL, 2048, 1, OPENAT_OS_CREATE_DEFAULT, "res_touch_test");

    return 0;
}

void appimg_exit(void)
{
    iot_debug_print("[hello]appimg_exit");
}

六、下载验证

  实验效果如下,显示正常。出现了两个点了误测,可能是过滤算法有问题。多加几次采样过滤就行了。

19、RDA8910(4GCAT1)CSDK二次开发:CSDK也能用触摸屏了--电阻屏适配(XPT2046采集ADC)

不会下载的点击这里,进去查看我的RDA8910 CSDK二次开发入门教程专题第一篇博文1、RDA8910CSDK二次开发:环境搭建里面讲了怎么下载
这里只是我的学习笔记,拿出来给大家分享,欢迎大家批评指正,本篇教程到此结束


喜欢 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址