基于嵌入式Lbob综合体育官方入口inux系统的触摸屏

2022-05-15 07:19 胡八一

本文介绍了一个在嵌入式Linux平台上编写触摸屏驱动程序的实例。该平台基于摩托罗拉Powerpc823eCPU芯片,采用个性化的Linux2.4.4内核作为其微操作系统。介绍了如何通过操作823e的SPI接口实现与触摸屏控制芯片ADS7846的通信。在构建硬件的基础上,阐述了触摸屏驱动程序的C语言实现。

本文引用地址:http://www.eepw.com.cn/article/149056.htm

关键词:Linux内核;PowerPC823eSPI接口;ADS7846触摸屏驱动程序

介绍

触摸屏作为嵌入式系统的输入设备,因其方便、灵活、省空时间和直观,越来越受到各终端产品厂商的青睐。Linux操作系统是嵌入式系统的一个流行选择,因为它具有开放源代码和易于裁减的优点。在构建硬件的基础上,本文将深入探讨如何在linux操作系统下编写触摸屏驱动程序。

SPI接口简介

串行外设接口SPI总线技术是摩托罗拉推出的全双工同步串行接口,提供了强大的四线接口(接收线、传输线、时钟线和从线选择)。

SPI的从机和主机共用一条时钟线,时钟始终由主机发送。当823e处于主模式时,片选信号线被禁用,如果处于从模式,其从片选线在低电平被使能。在这个例子中,823e是主设备,所以我们也选择了823e的GPIO(通用输入输出端口)作为从设备的片选信号。大多数同步串行数据转换器很容易与该接口连接,其硬件功能非常强大。所以SPI相关的软件相当简单,让CPU有更多的时间处理其他事务。

触摸屏硬件

触摸屏输入系统由触摸屏、触摸屏控制芯片和数据处理器组成。触摸屏按其技术原理可分为五大类:矢量压力感应式、电阻式、电容式、红外式、声表面波式,其中电阻式触摸屏广泛应用于嵌入式系统。

我们选择的触摸屏是AMD的电阻式触摸屏AMT9502。触摸屏控制芯片是TI公司的模数转换芯片ADS7846。芯片支持SPI通信协议,所以我们使用823e的SPI接口与ADS7846芯片进行通信。来自触摸屏的模拟信号经过模数转换器后输入823e作为数据处理器。

软件程序

823e通过SPI接口与触摸屏控制器通信,所以触摸屏的控制就是SPI接口的操作。写入SPI接口驱动程序后,它可以与触摸屏控制器建立通信。linux内核运行后,SPI接口应该是打开的,已经分配了一部分内存供其使用。与此同时,SPI的中断程序也加入了等待队列。一旦SPI接口中断,SPI的中断服务程序就会被唤醒并开始运行。这部分工作由系统启动时运行的初始化函数完成。下面将结合源代码讨论初始化函数的编译,其中将强调两点。

微码的使用

因为SCCx的网络参数空和SPI的参数空有冲突,所以如果要同时使用SCCx作为网络端口和SPI驱动,就要加载微码,重新定位SPI的参数空。Micropatch是加载了微码的文件,这个文件中的微码可以从摩托罗拉官网下载。

包括CPM的双向ram端口的一部分,称为参数RAM,包含USB、SCC、SMC、SPI、I2C和IDMA通道操作。其中,SPI和I2C参数区可以重新定位到另一个32位参数区。仔细阅读下面的代码后,您可以很好地理解这个过程是如何工作的:

SPI =(SPI _ t *)CP-& gt;CP _ d param[PROFF _ SPI];

printk(thespiadris % pn,SPI);

if((reloc = SPI-& gt;spi_rpbase))

{

SPI =(SPI _ t *)CP-& gt;CP _ DP mem[SPI-& gt;SPI _ rpbase];

printk(microcoderelationpatchn);

}

上面代码的作用是先查询微码是否被使用过,然后获取重定位指针(加载微码和重定位都在微码. c中完成)。

RAM中的SPI描述符

SPI接口的描述符存储在缓冲器中,缓冲器的地址由双向RAM中的SPI缓冲器描述符指定。要发送的数据在发送缓冲区,接收到的数据会存储在发送缓冲区。缓冲区描述符循环(Buffer descriptor loop)形成一个循环,帮助一步一步地发送(接收)你要发送(接收)的数据。由于这些缓冲区描述符,通信处理模块可以完成通信,并解释和处理错误。

你可以通过一段代码看到上面原理图的过程是如何在初始化函数中实现的:

SPI-& gt;spi _ rbase = r _ rbase = dp _ addr

SPI-& gt;SPI _ tbase = r _ tbase = DP _ addr+sizeof(CBD _ t);

/*将RXBDRING的地址写入POINTERTOSPIRXRING。

将TXBDRINT的地址写入POINTERTOSPITXRING*/

SPI-& gt;SPI _ rbptr = SPI-& gt;spi _ rbase

SPI-& gt;SPI _ tbptr = SPI-& gt;spi _ tbase

/*以上两个代码一定要写,不然就是读写霓虹灯?/

tbdf =(CBD _ t *)CP-& gt;CP _ DP mem[r _ tbase];

rbdf =(CBD _ t *)CP-& gt;CP _ DP mem[r _ r base];

/*从这段代码可以看出,RXBDRING的地址在双向RAM中*/

tbdf-& gt;cbd _ sc = ~ BD _ SC _ READY

rbdf-& gt;cbd _ sc = ~ BD _ SC _ EMPTY

/*设置振铃的状态,发送的振铃被设置为非准备发送状态,

接受振铃被设置为非准备接受状态*/

rx buffer = m8xx _ CPM _ host alloc(2);

tx buffer = m8xx _ CPM _ host alloc(2);/*在两者之间获取空 */

tbdf-& gt;CBD _ buf addr = _ _ pa(tx buffer);

rbdf-& gt;CBD _ buf addr = _ _ pa(rx buffer);

/*内存映射;并将数据指针设置为RXDATABUFFER的地址*/

以上代码是在初始化函数中完成的。一旦初始化功能正常工作,就可以对SPI端口通信采取正确的步骤。以上初始化完成后,调用cpm_install_handler函数,用于将中断函数注册到内核中。一旦SPI端口产生硬件中断,调用中断函数。中断函数可以根据不同系统的不同需求来编写。在本例中,一旦调用中断函数,我们将读取SPI接收的数据。

接下来以如何发送数据为例,分析如何操作SPI口通信。

发送数据

本例中,SPI接口设置为主模式。为了启动数据传输过程,内核将要传输的数据写入数据缓冲区,然后配置缓冲区描述符以达到传输的目的。下面是发送数据的代码,通过代码解释传输的过程。

memset((void*)txbuffer,0,2);/*清除空缓冲区*/

tbdf-& gt;CBD _ SC = BD _ SC _ READY | BD _ SC _ LAST | BD _ SC _ WRAP;

tbdf-& gt;CBD _ datlen = 2;

/*设置发送缓冲器的状态控制寄存器的值和发送数据的数量*/

rbdf-& gt;cbd _ sc = BD _ SC _ EMPTY | BD _ SC _ WRAP

rbdf-& gt;CBD _ datlen = 0;

/*数字是0*/

CP-& gt;cp _ spmode = 0x777f

CP-& gt;cp _ spie = 0xff

CP-& gt;CP _ spim = 0x 37;

/*设置SPI接口寄存器的值以发送数据,并设置SPI接口的

必须在发送功能中设置主机或从机模式,否则无法发送数据*/

CP-& gt;cp _ spcom | = 0x80/*开始发送数据*/

udelay(1000);/*必须等待,否则无法正确读取缓冲状态控制寄存器的值*/

if((tbdf-& gt;cbd_sc0x8000))

printk(spiwriteerror!);

memset((void*)rxbuffer,0,2);

在数据通信的过程中,最重要的是定时,正确的定时只有通过反复实验才能得到。图3是实验过程中得到的逻辑图(安捷伦1672G逻辑分析仪的测试结果)。其中CS是片选信号,CK是时钟信号,DO是823e发送的数据。逻辑分析仪可用于读取获得的数据是否与设备发送的数据一致。正确的通信必须经过长时间的调试才能获得。

ADS7846的操作

根据ADS7846的用户手册,驱动器必须在初始化期间与ADS7846建立通信。所以823e必须先向ADS7846发送命令,收到ADS7846的回复后建立通信。驱动程序调用SPI的读写功能来实现ADS7846的操作。