• [原创][连载].基于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触摸屏驱动测试

  • 相关阅读:
    压缩命令
    u盘挂载
    三种不同的空格
    打出圆圈数字①的快捷方法
    循环使用的一个坑
    Python&R:警告信息管理
    Matlab的基本矩阵运算
    R语言-程序执行时间
    Python:n个点的费马问题
    Python网络数据采集(1):博客访问量统计
  • 原文地址:https://www.cnblogs.com/yuphone/p/1920440.html
Copyright © 2020-2023  润新知