基于SOPC的触摸屏操作

mian.c

//-----------------------------------------------------------------------------------------------------------

 

#include <stdio.h>
#include <sys/unistd.h>
#include <io.h>
#include <string.h>

#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
#include "sys/alt_irq.h"
#include "lcd.h"
#include "tsp.h"
/*************************************************/
 
/*************************************************/
alt_u8 myButton, mLED;
int main(void)
{
  int i;
  alt_u16 *pPic;
  alt_u16 temp, color;
  printf("Exp14 TouchScreen Test!\n");
  LCD_IO_Init();
  LCD_On_Off(1);
  TS_GetXY(&temp, &temp);
  TSP_Test();          
 
 
    return 0;
}


 //----------------------------------------------------------------------------

lcd.c

//--------------------------------------------------------------------------

#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
#include "lcd.h"

/************************************************/

void LCD_IO_Init(void)
{
  IOWR_ALTERA_AVALON_PIO_DATA(LCD_RD_BASE, 1);  //rd = 1
  IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 1);  //wr = 1
  IOWR_ALTERA_AVALON_PIO_DATA(LCD_CS_BASE, 1);  //cs = 1
  IOWR_ALTERA_AVALON_PIO_DIRECTION(LCD_DATA_BASE, OUT);
}

void LCD_Write(alt_u8 addr, alt_u16 dat)
{
  IOWR_ALTERA_AVALON_PIO_DATA(LCD_ADDR_BASE, addr);  //output addr
  IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE, dat);  //output dat
  IOWR_ALTERA_AVALON_PIO_DATA(LCD_CS_BASE, 0);  //cs = 0
  IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 0);  //wr = 0
  IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 1);  //wr = 1
  IOWR_ALTERA_AVALON_PIO_DATA(LCD_CS_BASE, 1);  //cs = 1
}

void LCD_On_Off(alt_u8 on_off)
{
  LCD_Write(LCD_DISP, on_off);
}

void FillScreen(alt_u8 ad_mode, alt_u16 color)
{
  alt_u32 i;
  LCD_Write(LCD_X, 0);
  LCD_Write(LCD_Y, 0);
  LCD_Write(LCD_AS, ad_mode);    //ad_mode为操作模式、M1M0=00为字节操作模式,M1M0=00为行操作模式,M1M0=10为列操作模式

  for(i=0; i<LCD_W*LCD_H;i++)
    LCD_Write(LCD_DAT, color); 
}

/*********************************************************************/
/*************************************************************/
void Draw_Pixel(alt_u16 x, alt_u16 y, alt_u16 color)    //在(x,y)位置画点
{
  LCD_Write(LCD_X, x);
  LCD_Write(LCD_Y, y);
  LCD_Write(LCD_DAT, color);
}

void DrawLine(alt_u16 x1, alt_u16 y1, alt_u16 x2, alt_u16 y2, alt_u16 color) //从(x1,y1)到(x2,y2)的线段
{
  int Lx, Ly, Cx, Cy, XER = 0,YER = 0, DTC;
  alt_u16 i = 0;
 
  Lx = x2 - x1;
  Ly = y2 - y1;

  if(Lx > 0)
    Cx = 1;
  else if(Lx < 0)
    Cx = -1;
 
  if(Ly > 0)
    Cy = 1;
  else if(Ly < 0)
    Cy = -1;
 
  if(Lx == 0) //Vertical Line
  {
    if(Ly == 0)
      Draw_Pixel(x1, y1, color);
    else
    {
      do
      {
        Draw_Pixel(x1, y1, color);
        y1 += Cy;    
      }
      while(y1 != y2);
      Draw_Pixel(x1, y1, color);
    }
    return;
  }
  else if(Ly == 0)  //Horizontal Line
  {
    do
    {
      Draw_Pixel(x1, y1, color);
      x1 += Cx;    
    }
    while(x1 != x2);
    Draw_Pixel(x1, y1, color);
    return;
  }
 
  Lx = fabs(Lx);
  Ly = fabs(Ly);
 
  if(Ly>Lx)
    DTC = Ly;
  else 
    DTC = Lx;
 
  for(i=0; i<=DTC+1; i++)
  {
    Draw_Pixel(x1, y1, color);
    XER += Lx;
    YER += Ly;
    if(XER>DTC)
    {
       XER -= DTC;
       x1 += Cx;
    }
    if(YER>DTC)
    {
       YER -= DTC;
       y1 += Cy;
    }
  }
}

void DrawRect(alt_u16 x, alt_u16 y, alt_u16 xl, alt_u16 yl, alt_u16 color)  //画矩形框
{
  alt_u16 i;
  LCD_Write(LCD_AS, 1);
  //横线顶端
  LCD_Write(LCD_X, x);
  LCD_Write(LCD_Y, y);
    for(i=0; i<xl; i++)
      LCD_Write(LCD_DAT, color);
  //横线低端
  LCD_Write(LCD_X, x);
  LCD_Write(LCD_Y, y+yl-1);
    for(i=0; i<xl; i++)
      LCD_Write(LCD_DAT, color);
  //横线左端
  LCD_Write(LCD_AS, 2);
  LCD_Write(LCD_X, x);
  LCD_Write(LCD_Y, y);
    for(i=0; i<yl; i++)
      LCD_Write(LCD_DAT, color);
  //横线低端
  LCD_Write(LCD_X, x+xl-1);
  LCD_Write(LCD_Y, y);
    for(i=0; i<yl; i++)
      LCD_Write(LCD_DAT, color);
}

void DrawFillRect(alt_u16 x, alt_u16 y, alt_u16 xl, alt_u16 yl, alt_u16 color)  //(x,y),(x1,y1),画实心矩形框
{
  alt_u16 i, j;
  LCD_Write(LCD_AS, 1);
  for(j=y; j<y+yl;j++)
  {
    LCD_Write(LCD_X, x);
    LCD_Write(LCD_Y, j);
    for(i=0; i<xl; i++)
      LCD_Write(LCD_DAT, color);
  }
}

void DrawEllipse(alt_u16 xp, alt_u16 yp, alt_u16 a, alt_u16 b, alt_u16 color) //画椭圆
{                           //----(xp,yp)和(a,b)分别为两焦点坐标
  alt_u16 x, y;
  float tmp;
 
  for(x=0; x<=a; x++)
  {
    tmp = x;
    tmp /= a;
    y = b * sqrt(1 - tmp * tmp) + 0.5;
   
    Draw_Pixel(xp + x, yp + y, color);
    Draw_Pixel(xp + x, yp - y, color);
    Draw_Pixel(xp - x, yp + y, color);
    Draw_Pixel(xp - x, yp - y, color);
  }
  for(y=0; y<=b; y++)
  {
    tmp = y;
    tmp /= b;
    x = a * sqrt(1 - tmp * tmp) + 0.5;
   
    Draw_Pixel(xp + x, yp + y, color);
    Draw_Pixel(xp + x, yp - y, color);
    Draw_Pixel(xp - x, yp + y, color);
    Draw_Pixel(xp - x, yp - y, color);
  }
}

void DrawCross(alt_u16 xp, alt_u16 yp, alt_u16 len, alt_u16 color)    //画十字光标
{                                                      //--(xp,yp)光标中心位置,len光标长度
    if( xp < len  ) xp = len;
    if( xp >= LCD_W - len ) xp = LCD_W - len - 1;
    if( yp < len  ) yp = len;
    if( yp >= LCD_H - len ) yp = LCD_H - len - 1;

    DrawLine(xp-len,  yp-1, xp+len,   yp-1,   color);
    DrawLine(xp-len,  yp,   xp+len,   yp,     color);
    DrawLine(xp-len,  yp+1, xp+len,   yp+1,   color);

    DrawLine(xp-1,  yp-len, xp-1,  yp+len,    color);
    DrawLine(xp,    yp-len, xp,    yp+len,    color);
    DrawLine(xp+1,  yp-len, xp+1,  yp+len,    color);
}
/****************【基本显示字符、汉字函数】**********/
void DisplayChar(char Char, alt_u16 xp, alt_u16 yp, alt_u16 fcolor, alt_u16 bcolor)  //显示任意字符
{
  alt_u8 i,j;
  alt_u8 *Font_Addr = (alt_u8 *)(NOR_FLASH_BASE + 0x7c0000 + ((Char)<<4));
  alt_u8 ft = 0;
 
  LCD_Write(LCD_AS, 1);
  for(i=0; i<16; i++)
  {
    LCD_Write(LCD_X, xp);
    LCD_Write(LCD_Y, yp+i);
    ft = Font_Addr[i];
    for(j=0; j<8; j++)
    {
      if(ft & 0x80)
        LCD_Write(LCD_DAT, fcolor);
      else
        LCD_Write(LCD_DAT, bcolor);
      ft <<= 1;
    }
  }
}

void DisplayHanzi(alt_u16 Unicode, alt_u16 xp, alt_u16 yp, alt_u16 fcolor, alt_u16 bcolor) //显示任意汉字
{
  alt_u8 i,j;
  alt_u16 ft;
  alt_u16 *Font_Addr = (alt_u16 *)(NOR_FLASH_BASE + 0x7c0000 + ((Unicode-0x3bbf-(Unicode>>8)*0xa2)<<5) + 0x01000);
  LCD_Write(LCD_AS, 1);
  for(i=0; i<16; i++)
  {
    LCD_Write(LCD_X, xp);
    LCD_Write(LCD_Y, yp+i);
    ft = SWAP16(Font_Addr[i]);
    for(j=0; j<16; j++)
    {
      if(ft & 0x8000)
        LCD_Write(LCD_DAT, fcolor);
      else
        LCD_Write(LCD_DAT, bcolor);
      ft <<= 1;
    }
  }
}


alt_u16 SizeofString(alt_u8 *str) //求取字符串长度
{
  alt_u16 len = 0;
  while(str[len++]);
  return len-1;
}

//显示任意字符串(中文为宋体,英文为8×16点阵)
void DisplayAnyString(alt_u8 *Str, alt_u16 xp, alt_u16 yp, alt_u16 fcolor, alt_u16 bcolor)
{                             //--Str为指针,指向带显示字符;(xp,yp)为显示坐标,fcolor为字体颜色,bcolor为背景颜色
  alt_u16 i;
  alt_u16 str_len = SizeofString(Str);
 
  for(i=0; i<str_len; i++)
  {
    if(Str[i] < 0x80)
    {
      if(xp > LCD_W - 8)
      {
        xp = 0;
        yp += 16;
      }
      if(Str[i] == 0x0d)      //回车
        xp = 0;
      else if(Str[i] == 0x0a)   //换行
        yp += 16;
      else
      {
        DisplayChar(Str[i], xp, yp, fcolor, bcolor);
        xp += 8;
      }
    }
    else
    {
      if(xp > LCD_W - 16)
      {
        xp = 0;
        yp += 16;
      }
      DisplayHanzi((Str[i]<<8)|Str[i+1], xp, yp, fcolor, bcolor);
      xp += 16;
      i++;
    }
  }
}

void Display_Pic(alt_u16 *pic, alt_u16 xp, alt_u16 yp, alt_u16 w, alt_u16 h)
{                             //Pic指向带显示码,(xp,yp)为初始坐标,w、h为宽度和高度,依次向左向下
  alt_u16 i, j;
  LCD_Write(LCD_AS, 1);
  for(i=0; i<h; i++)
  {
    LCD_Write(LCD_X, xp);
    LCD_Write(LCD_Y, yp+i);
    for(j=0; j<w; j++)
      LCD_Write(LCD_DAT, *pic++);
  }
}


 

//----------------------------------------------------------------

LCD.h

//--------------------------------------------------------------------

#ifndef __LCD_H__
#define __LCD_H__

/************************************************/
#define   LCD_W       800
#define   LCD_H       600

#define   OUT     0xffff
#define   IN      0x0000

#define   LCD_X     0     //-----列地址低位寄存器X
#define   LCD_Y     1     //-----行地址高位寄存器Y
#define   LCD_AS    2     //-----操作模式寄存器
#define   LCD_DISP  3      //----LCD显示控制器
#define   LCD_RDY   4     //----
#define   LCD_DAT   7       //----读/写LCD显示数据

#define   COLOR_BLACK   0x0000
#define   COLOR_WHITE   0xFFFF
#define   COLOR_RED     0xF800
#define   COLOR_GREEN   0x07E0
#define   COLOR_BLUE    0x001F
#define   COLOR_YELLOW  0xFFE0
#define   COLOR_PURPLE  0x8010
#define   COLOR_ORANGE  0xFC00
#define   COLOR_CYAN    0x87FF  //---cyan蓝绿色


#define   SWAP16(x)     ((x<<8) | (x>>8))
/************************************************/
void LCD_IO_Init(void);
void LCD_Write(alt_u8 addr, alt_u16 dat);
void LCD_On_Off(alt_u8 on_off);
void FillScreen(alt_u8 ad_mode, alt_u16 color);
void Draw_Pixel(alt_u16 x, alt_u16 y, alt_u16 color);
void DrawLine(alt_u16 x1, alt_u16 y1, alt_u16 x2, alt_u16 y2, alt_u16 color);
void DrawRect(alt_u16 x, alt_u16 y, alt_u16 xl, alt_u16 yl, alt_u16 color);
void DrawFillRect(alt_u16 x, alt_u16 y, alt_u16 xl, alt_u16 yl, alt_u16 color);
void DrawEllipse(alt_u16 xp, alt_u16 yp, alt_u16 a, alt_u16 b, alt_u16 color);
void DrawCross(alt_u16 xp, alt_u16 yp, alt_u16 len, alt_u16 color);
void DisplayChar(char Char, alt_u16 xp, alt_u16 yp, alt_u16 fcolor, alt_u16 bcolor);
void DisplayHanzi(alt_u16 Unicode, alt_u16 xp, alt_u16 yp, alt_u16 fcolor, alt_u16 bcolor);
void DisplayAnyString(alt_u8 *Str, alt_u16 xp, alt_u16 yp, alt_u16 fcolor, alt_u16 bcolor);
void Display_Pic(alt_u16 *pic, alt_u16 xp, alt_u16 yp, alt_u16 w, alt_u16 h);
/************************************************/
#endif

 

//-------------------------------------------------------------------

TSP.c

//-------------------------------------------------------------------

#include <sys/unistd.h>
#include <io.h>

#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "tsp.h"
#include "lcd.h"

/**************************************/
alt_u16 Min_X_Ad, Max_X_Ad;
alt_u16 Min_Y_Ad, Max_Y_Ad;

/**************************************/
void TS_GetXY(alt_u16 *x, alt_u16 *y) //获取当前触摸点坐标
{
  int i;
  alt_u16 TS_X_Ad, TS_Y_Ad;
  for(i=0; i<2; i++)
    TS_X_Ad = TS_Read_X_Ad(0xd3);
  TS_X_Ad = 0;
  for(i=0; i<4; i++)
    TS_X_Ad += TS_Read_X_Ad(0xd3);
  TS_X_Ad >>= 2;
 
  for(i=0; i<2; i++)
    TS_Y_Ad = TS_Read_Y_Ad(0x93);
  TS_Y_Ad = 0;
  for(i=0; i<4; i++)
    TS_Y_Ad += TS_Read_Y_Ad(0x93);
  TS_Y_Ad >>= 2;
 
  ADC_to_XY(TS_X_Ad, TS_Y_Ad, x, y);
  TS_Read_X_Ad(0xd0);
}

void ADC_to_XY(alt_u16 xad, alt_u16 yad, alt_u16 *x, alt_u16 *y)  //AD值转换成XY坐标
{
  alt_u16 tmp;
  if(xad < Min_X_Ad)
    xad = Min_X_Ad;
  else if(xad > Max_X_Ad)
    xad = Max_X_Ad;
 
  tmp = Max_X_Ad - Min_X_Ad;
  if(tmp == 0)
    tmp = 1;
  *x = (xad - Min_X_Ad) * LCD_W / tmp;

  if(yad < Min_Y_Ad)
    yad = Min_Y_Ad;
  else if(yad > Max_Y_Ad)
    yad = Max_Y_Ad;
  
  tmp = Max_Y_Ad - Min_Y_Ad;
  if(tmp == 0)
    tmp = 1;
  *y = (yad - Min_Y_Ad) * LCD_H / tmp;
}

#define TS_Delay1()   usleep(5)
#define TS_Delay2()   usleep(5)
#define TS_Delay3()   usleep(25)
alt_u16 TS_Read_X_Ad(alt_u8 cmd)    //读取触摸平控制器X方向AD值
{
  alt_u16 i;
  alt_u16 dat = 0;
  TS_CS_Low;
  TS_DCLK_Low;
  TS_Delay1();
  for(i=0; i<8; i++)
  {
    if(cmd & 0x80)
      TS_DOUT_High;
    else
      TS_DOUT_Low;
    TS_Delay1();
    TS_DCLK_High;
    cmd <<= 1;
    TS_Delay1();
    TS_DCLK_Low;
  }
  TS_Delay3();
  for(i=0; i<13; i++)
  {
    TS_DCLK_High;
    dat <<= 1;
    if(TS_DIN)
      dat |= 1;
    TS_Delay2();
    TS_DCLK_Low;
    TS_Delay2();
  }
  TS_CS_High;
 
  return dat & 0xfff;
}

alt_u16 TS_Read_Y_Ad(alt_u8 cmd)    //读取触摸平控制器Y方向AD值
{
  alt_u16 i;
  alt_u16 dat = 0;
  TS_CS_Low;
  TS_DCLK_Low;
  TS_Delay2();
  for(i=0; i<8; i++)
  {
    if(cmd & 0x80)
      TS_DOUT_High;
    else
      TS_DOUT_Low;
    TS_Delay1();
    TS_DCLK_High;
    cmd <<= 1;
    TS_Delay1();
    TS_DCLK_Low;
  }
  TS_Delay3();
  for(i=0; i<13; i++)
  {
    TS_DCLK_High;
    dat <<= 1;
    if(TS_DIN)
      dat |= 1;
    TS_Delay2();;
    TS_DCLK_Low;
    TS_Delay2();
  }
  TS_CS_High;
 
  return (0xfff - (dat & 0xfff));
}

//触摸屏校
void TS_Calibrate(void)
{
    alt_u8 PenTouchCount = 0;
    alt_u16 TchX[4], TchY[4];
    alt_u16 i, xp, yp, x, y;
    float min, max;
    alt_u32 AD_X, AD_Y;
    FillScreen(1, COLOR_WHITE);
    while(!TSP_State())
        usleep(50000);   
    while(PenTouchCount < 4)
    {
        switch(PenTouchCount)
        {
            case 0: { xp = 20;        yp = 20;        break; }
            case 1: { xp = 20;        yp = LCD_H-20;  break; }
            case 2: { xp = LCD_W-20;  yp = LCD_H-20;  break; }
            case 3: { xp = LCD_W-20;  yp = 20;        break; }
            default : break;
        }
        DrawCross(xp, yp, 20, COLOR_RED);
   
        if(!TSP_State())
        {
            for(i=0; i<2; i++)
            {
                TS_Read_X_Ad(0xd3);
                TS_Read_Y_Ad(0x93);
            }
     
        AD_X = AD_Y = 0;
        #define NN  16
        for(i=0; i<NN; i++)
            AD_X += TS_Read_X_Ad(0xd3);

        for(i=0; i<NN; i++)
            AD_Y += TS_Read_Y_Ad(0x93);
     
        TchX[PenTouchCount] = AD_X / NN;
        TchY[PenTouchCount] = AD_Y / NN;
        TS_GetXY(&x, &y);
        DrawCross(xp, yp, 20, COLOR_BLUE);
        while(!TSP_State())
            usleep(50000);   
        DrawCross(xp, yp, 20, COLOR_WHITE);
        PenTouchCount++;
        }
        usleep(10000);
    }
    //计算X方向最小值和最大值
    min = (TchX[0] + TchX[1]) / 2;
    max = (TchX[2] + TchX[3]) / 2;
    Min_X_Ad = min - (max - min) / 30;
    Max_X_Ad = max + (max - min) / 30;
 
    //计算Y方向最小值和最大值
    min = (TchY[0] + TchY[3]) / 2;
    max = (TchY[1] + TchY[2]) / 2;
    Min_Y_Ad = min - (max - min) / 22;
    Max_Y_Ad = max + (max - min) / 22;
}

//-------------------------------------------------
#define   XP_ERROR      5
#define   NO_ERR_TIMES  2
void TSP_Test(void)
{
    alt_u16 old_x, old_y, X_Pos, Y_Pos;
    old_x = old_y = 0;
    TS_Calibrate();
    while(1)
    {
        if(!TSP_State())
        {
            usleep(5000);
            old_x = X_Pos;
            old_y = Y_Pos;
            TS_GetXY(&X_Pos, &Y_Pos);
            DrawCross(old_x, old_y, 10, COLOR_WHITE);
            DrawCross(X_Pos, Y_Pos, 10, COLOR_BLUE);
        }
        usleep(10000);
    }
}

 

//----------------------------------------------------------------------------------

TSP.h

//----------------------------------------------------------------------------------

#ifndef _TSP_H_
#define _TSP_H_

#define   MAX_X_POSITION  639
#define   MAX_Y_POSITION  479

#define   TOUCHPEN_STATE  (rPDATG & 0x01)

#define   TS_CS_Low     IOWR_ALTERA_AVALON_PIO_DATA(TSP_CS_BASE, 0)
#define   TS_CS_High    IOWR_ALTERA_AVALON_PIO_DATA(TSP_CS_BASE, 1)
#define   TS_DCLK_Low   IOWR_ALTERA_AVALON_PIO_DATA(TSP_CLK_BASE, 0)
#define   TS_DCLK_High  IOWR_ALTERA_AVALON_PIO_DATA(TSP_CLK_BASE, 1)
#define   TS_DOUT_Low   IOWR_ALTERA_AVALON_PIO_DATA(TSP_DO_BASE, 0)
#define   TS_DOUT_High  IOWR_ALTERA_AVALON_PIO_DATA(TSP_DO_BASE, 1)
#define   TS_DIN        IORD_ALTERA_AVALON_PIO_DATA(TSP_DI_BASE)
#define   TSP_State()   IORD_ALTERA_AVALON_PIO_DATA(TSP_INT_BASE)
/*****************************************/
extern alt_u16 Min_X_Ad, Max_X_Ad;
extern alt_u16 Min_Y_Ad, Max_Y_Ad;

/*****************************************/
void TS_GetXY(alt_u16 *x, alt_u16 *y);    //获取当前触摸点坐标
void ADC_to_XY(alt_u16 xad, alt_u16 yad, alt_u16 *x, alt_u16 *y); //AD值转换成XY坐标
alt_u16 TS_Read_X_Ad(alt_u8 cmd);   //读取触摸平控制器X方向AD值
alt_u16 TS_Read_Y_Ad(alt_u8 cmd);   //读取触摸平控制器Y方向AD值
void TS_Calibrate(void);            //触摸屏校

void TSP_Test(void);

#endif //_TSP_H_

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值