[连载].基于SOPC的简易数码相框 - Nios II SBTE部分(软件部分)- ADS7843触摸屏驱动测试

准备资料

1 触摸屏控制芯片ADS7843中文资料[1]_百度文库

2 触摸屏原理与分类_百度文库

3 [原创].触摸屏滤波的一点心得

4 [笔记].如何使用Nios II的中断:PIO中断与定时器中断

操作步骤

步骤1 将ADS7843的驱动文件夹加入APP路径中

image image

步骤2 编写ADS7843的驱动

我们先看下触摸屏芯片采样的坐标与TFT-LCD显示的坐标的区别和联系。图中的TFT-LCD方向为所定义方向,亦即

#define ID_AM    110

其XY坐标与ADS7843采样之坐标翻了。故ADS7843采样及滤波之后,需要把XY坐标翻回来。此外我们可以看到TFT-LCD显示区域是触摸屏采样芯片采样区域的子集,因此如若将程序移植到你的平台上,请坐相应的坐标校准动作。这和我们的触摸屏手机的校准功能是类似的的。

image

废话不多说,直接贴代码,有什么不明白的地方,请给我留言。

代码2.1 ads7843.h

#ifndef ADS7843_H_

#define ADS7843_H_



#include "my_types.h"

#include "my_regs.h"





#define CHX 0x90

#define CHY 0xD0





void ads_SPIStart(void);

void ads_SPIWrite(u8 cmd);

u16 ads_SPIRead(void);

bool ads_ReadXY(void);

bool ads_GetXY(void);

u8 *intostr(u16 n);



#endif /* ADS7843_H_ */

代码2.2 ads7843.c

#include "ads7843.h"

#include <unistd.h>





// 全局变量,用以储存坐标信息

u16 X=0, Y=0;





// SPI开始状态

void ads_SPIStart(void)

{

  ads_CLK=0;

  ads_nCS=1;

  ads_DIN=1;

  ads_CLK=1;

  ads_nCS=0;

}





// SPI写一个byte

void ads_SPIWrite(u8 cmd)

{

  u8 i;

  ads_CLK=0;

  for(i=0; i<8; i++) // 上升沿有效

  {

    ads_DIN = (cmd >> (7-i)) & 0x1; // MSB在前,LSB在后

    ads_CLK=0; usleep(1);

    ads_CLK=1; usleep(1);

  }

}





// SPI读12个bit

u16 ads_SPIRead(void)

{

  u8 i;

  u16 temp=0;

  for(i=0; i<12; i++) // 下降沿有效

  {

    temp<<=1;

    ads_CLK=1; usleep(1);

    ads_CLK=0; usleep(1);

    if(ads_DOUT) temp++;

  }

  return temp;

}





// 读取ADS7843采集到X、Y值

// 返回:超出屏幕范围,则返回0

bool ads_ReadXY(void)

{

  ads_SPIStart();

  ads_SPIWrite(CHX);

  ads_CLK=1; usleep(1);

  ads_CLK=0; usleep(1);

  X = ads_SPIRead();

  ads_SPIWrite(CHY);

  ads_CLK=1; usleep(1);

  ads_CLK=0; usleep(1);

  Y = ads_SPIRead();

  ads_nCS=1;

  if((X>350 && X<3800) && (Y>300 && Y<3800)) // 根据自己的屏自行矫正

    return 1; // 读数成功(范围限制)

  else

    return 0; // 读数失败

}





// 处理从ADS7843读取的X、Y值,然后互换

#define SAMP_CNT      4

#define SAMP_CNT_DIV2 2

bool ads_GetXY(void)

{

  u8 i, j, k, min;

  u16 temp;

  u16 tempXY[2][SAMP_CNT], XY[2];

  // 采样

  for(i=0; i<SAMP_CNT; i++)

  {

    if(ads_ReadXY())

    {

      tempXY[0][i] = X;

      tempXY[1][i] = Y;

    }

  }

  // 滤波

  for(k=0; k<2; k++)

  { // 降序排列

    for(i=0; i<SAMP_CNT-1; i++)

    {

      min=i;

      for (j=i+1; j<SAMP_CNT; j++)

      {

        if (tempXY[k][min] > tempXY[k][j]) min=j;

      }

      temp = tempXY[k][i];

      tempXY[k][i] = tempXY[k][min];

      tempXY[k][min] = temp;

    }

    // 设定阈值

    if((tempXY[k][SAMP_CNT_DIV2]-tempXY[k][SAMP_CNT_DIV2-1]) > 5)

      return 0;

    // 求中间值的均值

    XY[k] = (tempXY[k][SAMP_CNT_DIV2]+tempXY[k][SAMP_CNT_DIV2-1]) / 2;

  }

  // 矫正坐标

  Y = ((XY[0]-350)/11);

  X = ((XY[1]-400)/14);

  return 1;

}





// 整型转字符串(显示X、Y坐标,3个ASCII码)

u8 *intostr(u16 n)

{

  u8 *p;

  static u8 buf[3];

  p = &buf[3];

  *p     = (n/100) - ((n/1000)*10)+48;

  *(p+1) = (n/10) - ((n/100)*10) +48;

  *(p+2) = n- ((n/10) *10) +48;

  *(p+3) = 0;

  return  p;

}

步骤3 触摸屏驱动测试

代码 main.c

#include <unistd.h>                   // usleep()

#include "my_types.h"                 // 数据类型

#include "my_regs.h"                  // 自定义引脚及寄存器映射

#include "debug.h"                    // debug

#include "ili932x.h"                  // ILI9325

#include "ads7843.h"                  // ADS7843

#include "sd_card.h"                  // SD Card

#include "system.h"                   // 系统

#include "altera_avalon_pio_regs.h"   // PIO,ads_nIRQ

#include "sys/alt_irq.h"              // 中断





// 变量申明

extern u16 X, Y;





// 函数申明

vu16 nirq_isr_context; // 定义全局变量以储存isr_context指针

void nIRQ_Initial(void);

void nIRQ_ISR(void* isr_context);

void ResetTouch(void);





// 调试信息显示开关

#define ENABLE_APP_DEBUG // turn on debug message

#ifdef ENABLE_APP_DEBUG

    #define APP_DEBUG(x)    DEBUG(x)

#else

    #define APP_DEBUG(x)

#endif





// nIRQ中断初始化

void nIRQ_Initial(void)

{

  // 改写timer_isr_context指针以匹配alt_irq_register()函数原型

  void* isr_context_ptr = (void*) &nirq_isr_context;

  IOWR_ALTERA_AVALON_PIO_IRQ_MASK(ADS_NIRQ_BASE, 1); // 使能中断

  IOWR_ALTERA_AVALON_PIO_EDGE_CAP(ADS_NIRQ_BASE, 1); // 清中断边沿捕获寄存器

  // 注册ISR

  alt_ic_isr_register(

      ADS_NIRQ_IRQ_INTERRUPT_CONTROLLER_ID, // 中断控制器标号,从system.h复制

      ADS_NIRQ_IRQ,     // 硬件中断号,从system.h复制

      nIRQ_ISR,         // 中断服务子函数

      isr_context_ptr,  // 指向与设备驱动实例相关的数据结构体

      0x0);             // flags,保留未用

}





// 中断服务子函数

void nIRQ_ISR(void* isr_context)

{

  IOWR_ALTERA_AVALON_PIO_EDGE_CAP(ADS_NIRQ_BASE, 1); // 清中断边沿捕获寄存器



  if(ads_GetXY())

  {

    if((X>190 && X<240 && Y>300 && Y<320)) ResetTouch();

    else

    {

      ili_PutString(34, 289, intostr(X), Blue, White);

      ili_PutString(34, 305, intostr(Y), Blue, White);

      ili_PlotBigPoint(X, Y, Red);

    }

  }

}





//

void ResetTouch(void)

{

  ili_ClearScreen(White);

  ili_PutString(190, 305, (u8 *)("Clear"), Blue, White);

  ili_PutString(10, 289, (u8 *)("X:   0"), Blue, White);

  ili_PutString(10, 305, (u8 *)("Y:   0"), Blue, White);

}





int main(void)

{

  ili_Initial();

  nIRQ_Initial();

  ResetTouch();

  while(1);

  return 0;

}

第34~47行,初始化nIRQ引脚下降沿中断;第51~65行,编写nIRQ中断函数。其他就不多说了。

测试效果如下:

源码下载

lcd_at_nios_nii_part.zip

目录

1 [原创][连载].基于SOPC的简易数码相框 -  Quartus II部分(硬件部分)

2 [原创][连载].基于SOPC的简易数码相框 -  Nios II SBTE部分(软件部分)-  配置工作

3 [原创][连载].基于SOPC的简易数码相框 -  Nios II SBTE部分(软件部分)-  SD卡(SPI模式)驱动

4 [原创][连载].基于SOPC的简易数码相框 -  Nios II SBTE部分(软件部分)-  TFT-LCD(控制器为ILI9325)驱动

5 [原创][连载].基于SOPC的简易数码相框 -  Nios II SBTE部分(软件部分)-  从SD卡内读取图片文件,然后显示在TFT-LCD上

6 [原创][连载].基于SOPC的简易数码相框 -  Nios II SBTE部分(软件部分)-  优化工作

7 [原创][连载].基于SOPC的简易数码相框 -  Nios II SBTE部分(软件部分)-  ADS7843触摸屏驱动测试

你可能感兴趣的:(ios)