【ARM 裸机开发 (IMX6ULL-mini)】PWM 背光调节与 GT9147 多点触摸驱动

文章目录

    • 前言
    • 一、PWM控制LCD亮度
      • [1.1 PWM](#1.1 PWM)
      • [1.2 PWM引脚配置](#1.2 PWM引脚配置)
      • [1.3 PWM寄存器配置](#1.3 PWM寄存器配置)
      • [1.4 PWM控制亮度具体实现](#1.4 PWM控制亮度具体实现)
    • 二、GT9147触控芯片
      • [2.1 触控屏种类](#2.1 触控屏种类)
      • [2.2 GT9147](#2.2 GT9147)
        • [2.2.1 I2C](#2.2.1 I2C)
        • [2.2.2 中断与复位引脚配置](#2.2.2 中断与复位引脚配置)
        • [2.2.3 芯片的地址](#2.2.3 芯片的地址)
        • [2.2.4 芯片复位及参数获取](#2.2.4 芯片复位及参数获取)
        • [2.2.5 点坐标的获取](#2.2.5 点坐标的获取)

前言

在上篇【ARM 裸机开发 (IMX6ULL-mini)】RGB-LCD 驱动与时序详解文章中,对LCD屏进行了一定的了解与基本使用;在上篇文章中提到有一个引脚PWM是决定屏幕显示亮度的,在本片文章中会对其具体使用进行解释;除此之外,在现代的显示器使用中,屏幕的作用并不单单只是显示图像了,还能够根据触摸做出应答。因此,本篇文章还会详细讲解触控芯片gt1148。

一、PWM控制LCD亮度

1.1 PWM

在昨天的LCD代码中:

我们将PWM输出的引脚直接设置为高电平,使LCD屏幕满亮度显示。在这篇文章中我们将通过这个引脚输出PWM来实现亮度的控制。我们重新创建一个PWM的文件来放关于这个PWM输出引脚的代码,将之前关于这个引脚的代码全部注释掉。

IMX6ULL中PWM的原理框图:

FIFO 深度 = 4,可以预先缓存 4 组占空比样本。写 PWMSAR 就是往 FIFO 压入占空比数值。

1.2 PWM引脚配置

在IMX6ULL原理图中,这个PWM引脚为GPIO8的复用功能。

在参考手册中,我们需要找到这个引脚使用的为PWM1。

我们需要先将其引脚复用功能配置为PWM输出功能,并配置电气属性:

1.3 PWM寄存器配置

接下来就是对PWM相关的寄存器进行配置:

寄存器名 英文全称 中文名称 核心功能
PWMx_PWMCR PWM Control Register PWM 控制寄存器 最核心寄存器:PWM 模块使能、时钟源选择、预分频、输出极性、FIFO 水位、休眠控制、重载模式等
PWMx_PWMSR PWM Status Register PWM 状态寄存器 状态标志位:FIFO 满 / 空、中断标志、错误状态,用来查询 PWM 运行状态
PWMx_PWMIR PWM Interrupt Register PWM 中断寄存器 中断使能配置,开启 / 关闭各类 PWM 中断(FIFO 中断、比较中断等)
PWMx_PWMSAR PWM Sample Register PWM 采样寄存器(FIFO 数据寄存器) 存放 PWM 占空比计数值,写这个寄存器把占空比送入硬件 FIFO
PWMx_PWMPR PWM Period Register PWM 周期寄存器 设置 PWM 输出周期,决定 PWM 频率 公式:PWM 频率 = PWM 时钟 / (PWMPR + 2)
PWMx_PWMCNR PWM Counter Register PWM 计数寄存器 只读,PWM 内部当前计数值,可以读取计数器实时数值

PWMx_PWMCR

PWMx_PWMSR

PWMx_PWMIR

PWMx_PWMSAR

PWMx_PWMPR

1.4 PWM控制亮度具体实现

c 复制代码
float global_ratio = 1.0;

//设置占空比
void set_ratio(void)
{
    int i = 0;
    for (i = 0; i < 4; i++)
    {
        PWM1->PWMSAR = PWM1->PWMPR * global_ratio;
    }    
}

//FIFO空中断服务函数
void pwm1_interrupt_handler(void)
{
    if((PWM1->PWMSR & (1 << 3)) != 0)
    {
        set_ratio();
        PWM1->PWMSR |= (1 << 3);
    }
}

void pwm1_init(void) 
{
    //引脚复用
    IOMUXC_SetPinMux(IOMUXC_GPIO1_IO08_PWM1_OUT, 0);
    //引脚电气配置
    IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO08_PWM1_OUT, 0xB9); 

    PWM1->PWMCR = 0;
    PWM1->PWMCR |= (1 << 26) | (1 << 16) | (65 << 4) | (3 << 1);
    PWM1->PWMIR |= (1 << 0);
    PWM1->PWMPR = 998;
    set_ratio();

    //注册PWM1中断
    system_interrupt_register(PWM1_IRQn, pwm1_interrupt_handler);

    // 设置PWM1中断优先级
    GIC_SetPriority(PWM1_IRQn, 0);

    // GIC使能PWM1中断
    GIC_EnableIRQ(PWM1_IRQn);

    //使能 PWM1
    PWM1->PWMCR |= (1 << 0);
}

通过改变global_ratio就可以达到改变亮度的效果。

二、GT9147触控芯片

2.1 触控屏种类

项目 电容触控屏 四线电阻触摸屏
检测对象 感应电压变化量(mV级),检测电场耦合变化 触摸点分压电压,电压值直接对应位置
电压来源 TX电极输出交流驱动,RX电极感应得到微弱感应电压 在ITO导电层两端施加直流参考电压,按压触点产生分压
触发条件 导电物体(手指/电容笔),不需要压力 需要按压,使两层ITO膜接触,指甲、塑料笔均可触摸
多点触摸 支持多点触摸 只支持单点触摸
校准需求 一般出厂校准,用户基本无需重新校准 装配、温度会带来偏差,嵌入式产品需要开机5点校准

在正点原子IMX6ULL这块上我们使用的使GT9147触控芯片。

2.2 GT9147

2.2.1 I2C

显而易见,这个触控芯片采用I2C协议通信,因此我们需要先将I2C2进行初始化:

在【ARM 裸机开发 (IMX6ULL-mini)】I2C协议详解这篇文章中有对I2C协议的详细解释,我们只需要将I2C1改为I2C2就可以应用到触控芯片中使用。

这里,为了方便I2C的使用,我们定义了一个关于I2C信息的结构体,以及一个读写的复用函数:

这样就可以实现GT9147的读写函数了:

2.2.2 中断与复位引脚配置

除此以外,我们还需要对中断与复位两个引脚进行配置:

2.2.3 芯片的地址

在这个屏幕提供的芯片编程指南中,有两种触控芯片:GT1158和GT9147;

因此,它们作为从机的地址也不同:

GT9147 与主机通信采用标准 I2C 通信,最高速率可以支持至 400Kbps。当主机采用 200 Kbps 以上的通信速率时,需要特别注意 I2C 的外部上拉电阻阻值,以保证SCL、SDA边沿足够陡峭。其2C设备地址由7位设备地址加1位读写控制位组成,高7位为地址,bit0为读写控制位。

2.2.4 芯片复位及参数获取

每次上电或复位时需要使用INT脚进行C地址设置。经过测试发现,两种芯片的复位方式是一样的。

代码实现:

要使用触控功能,首先我们需要确认它的ID型号,通过I2C协议读取0x8140的四个字节,就可以得到它的ID以及INT引脚的中断触发方式:

得到INT中断触发方式后,我们需要对IMX6ULL上的INT引脚寄存器进行配置:

然后就是注册中断服务函数,设置优先级,使能中断这一套老招数了:

这样,我们的GT9147初始化就完成了。

2.2.5 点坐标的获取

接下来,就是对GT9147触控芯片的简单使用了,所有的触控操作肯定都是建立在知道你触摸的点在哪里的前提下,因此,在这篇文章中我们就来实现触摸点坐标的获取。

我们定义这样一个结构体来存储触摸时的数据。

在芯片的编程手册中,给出了坐标信息:

这里编程手册写错了,五个触控点存储的位置分别为:0x8150, 0x8158, 0x8160, 0x8168, 0x8170;

根据地址特性,我们这样定义一个数组来存储地址:

实现代码:

  1. I2C 读0x814E → 获取触摸点个数
  2. 根据点数,依次读取每个触摸点 4 字节,拼接 X、Y 原始坐标
  3. 设置 available 标记,告诉主程序有无触摸
  4. 写 0 到 0x814E ,清除中断 / 就绪标志,GT9147 准备下一轮检测

    我们将其显示在LCD屏幕上:

    这样就完成了触控芯片的简单使用了,更多的使用等待后面分享吧!
相关推荐
凉、介20 小时前
深入理解 ARM SCP Firmware 的 Event 与 Notification 机制
学习·scp·嵌入式·arm
susplus21 小时前
【ARM 裸机开发 (IMX6ULL-mini)】SPI 协议与ADXL345 三轴加速度传感器
arm·spi·adxl345加速度传感器
susplus1 天前
【ARM 裸机开发 (IMX6ULL-mini)】RGB-LCD 驱动与时序详解
arm·rgb_lcd
额额额对了1 天前
嵌入式 ADC 从入门到实战:基于 i.MX6ULL 的裸机驱动开发
驱动开发·嵌入式硬件·arm
幼儿园蛋小黑2 天前
ARM 中断机制详解
arm
嵌入式分享2 天前
嵌入式分#49:浅 8080,RGB,LVDS 与 MIPI 显口
嵌入式硬件·lcd
晊晌_h2 天前
IMX6ULL裸机开发:定时器(GPT/EPIT)与UART串口
arm·定时器·arm裸机开发
幼儿园蛋小黑8 天前
ARM 时钟与定时器详解:从原理到实践
arm
幼儿园蛋小黄8 天前
从定时器到时钟:ARM 嵌入式学习总结
arm