极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 12111|回复: 4

紧急求助!STM32移植Arduino UTouch触屏库失败!

[复制链接]
发表于 2014-1-17 23:28:26 | 显示全部楼层 |阅读模式
我想在STM32上使用触屏,想到Arduino的UTouch库可以把校准数据通过程序直接写入单片机而不是要单片机访问存储器,使用我决定移植UTouch库到STM32上面去。但是当我调试好各个函数后,STM32虽然可以获得触摸的中断,但是无法获得触摸的数据,导致数据永远是(0,239)(我的液晶屏是320*240的),无法使用。想想应该是SPI的时序问题,就调整了时序和延迟,还是不行,甚至使用了硬件SPI,故障依旧。现在我实在想不出有什么办法驱动触屏了,总不能把触屏连到Arduino上(触屏在Arduino上可以工作)然后再与STM32通信吧。
回复

使用道具 举报

 楼主| 发表于 2014-1-17 23:28:47 | 显示全部楼层
求高手帮忙看看代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-1-17 23:30:01 | 显示全部楼层
这是原版Arduino的UTouch:
UTouch.h:

/*
  UTouch.h - Arduino/chipKit library support for Color TFT LCD Touch screens
  Copyright (C)2010-2013 Henning Karlsen. All right reserved
  
  Basic functionality of this library are based on the demo-code provided by
  ITead studio. You can find the latest version of the library at
  http://www.henningkarlsen.com/electronics

  If you make any modifications or improvements to the code, I would appreciate
  that you share the code with me so that I might include it in the next release.
  I can be contacted through http://www.henningkarlsen.com/electronics/contact.php

  This library is free software; you can redistribute it and/or
  modify it under the terms of the CC BY-NC-SA 3.0 license.
  Please see the included documents for further information.
*/

#ifndef UTouch_h
#define UTouch_h

#if defined(ARDUINO) && ARDUINO >= 100
        #include "Arduino.h"
#else
        #include "WProgram.h"
#endif

#define PORTRAIT                        0
#define LANDSCAPE                        1

#define PREC_LOW                        1
#define PREC_MEDIUM                        2
#define PREC_HI                                3
#define PREC_EXTREME                4

class UTouch
{
        public:
                word        TP_X ,TP_Y;

                                UTouch(byte tclk, byte tcs, byte tdin, byte dout, byte irq);

                void        InitTouch(byte orientation = LANDSCAPE);
                void        read();
                bool        dataAvailable();
                int                getX();
                int                getY();
                void        setPrecision(byte precision);
   
    private:
                byte        T_CLK, T_CS, T_DIN, T_DOUT, T_IRQ;
                long        _default_orientation;
                byte        orient;
                byte        prec;
                byte        display_model;
                long        disp_x_size, disp_y_size, default_orientation;
                long        touch_x_left, touch_x_right, touch_y_top, touch_y_bottom;

                void        touch_WriteData(byte data);
                word        touch_ReadData();
};

#endif




UTouch.cpp


/*
  UTouch.cpp - Arduino/chipKit library support for Color TFT LCD Touch screens
  Copyright (C)2010-2013 Henning Karlsen. All right reserved
  
  Basic functionality of this library are based on the demo-code provided by
  ITead studio. You can find the latest version of the library at
  http://www.henningkarlsen.com/electronics

  If you make any modifications or improvements to the code, I would appreciate
  that you share the code with me so that I might include it in the next release.
  I can be contacted through http://www.henningkarlsen.com/electronics/contact.php

  This library is free software; you can redistribute it and/or
  modify it under the terms of the CC BY-NC-SA 3.0 license.
  Please see the included documents for further information.
*/

#include "UTouch.h"
#include "UTouchCD.h"

UTouch::UTouch(byte tclk, byte tcs, byte din, byte dout, byte irq)
{
    T_CLK        = tclk;
    T_CS         = tcs;
    T_DIN        = din;
    T_DOUT       = dout;
    T_IRQ        = irq;
}

void UTouch::InitTouch(byte orientation)
{
        orient                                        = orientation;
        _default_orientation        = CAL_S>>31;
        touch_x_left                        = (CAL_X>>14) & 0x3FFF;
        touch_x_right                        = CAL_X & 0x3FFF;
        touch_y_top                                = (CAL_Y>>14) & 0x3FFF;
        touch_y_bottom                        = CAL_Y & 0x3FFF;
        disp_x_size                                = (CAL_S>>12) & 0x0FFF;
        disp_y_size                                = CAL_S & 0x0FFF;
        prec                                        = 10;

        pinMode(T_CLK,  OUTPUT);
    pinMode(T_CS,   OUTPUT);
    pinMode(T_DIN,  OUTPUT);
    pinMode(T_DOUT, INPUT);
    pinMode(T_IRQ,  OUTPUT);

        digitalWrite(T_CS,  HIGH);
        digitalWrite(T_CLK, HIGH);
        digitalWrite(T_DIN, HIGH);
        digitalWrite(T_CLK, HIGH);
}

void UTouch::touch_WriteData(byte data)
{
        byte temp;
        byte nop;

        temp=data;
        digitalWrite(T_CLK,LOW);

        for(byte count=0; count<8; count++)
        {
                if(temp & 0x80)
                        digitalWrite(T_DIN, HIGH);
                else
                        digitalWrite(T_DIN, LOW);
                temp = temp << 1;
                digitalWrite(T_CLK, LOW);               
                nop++;
                digitalWrite(T_CLK, HIGH);
                nop++;
        }
}

word UTouch::touch_ReadData()
{
        byte nop;
        word data = 0;
        for(byte count=0; count<12; count++)
        {
                data <<= 1;
                digitalWrite(T_CLK, HIGH);               
                nop++;
                digitalWrite(T_CLK, LOW);
                nop++;
                if (digitalRead(T_DOUT))
                        data++;
        }
        return(data);
}

void UTouch::read()
{
        unsigned long tx=0, temp_x=0;
        unsigned long ty=0, temp_y=0;
        int datacount=0;

        digitalWrite(T_CS,LOW);                    

        for (int i=0; i<prec; i++)
        {
                touch_WriteData(0x90);        
                digitalWrite(T_CLK,HIGH);
                digitalWrite(T_CLK,LOW);
                temp_x=touch_ReadData();

                touch_WriteData(0xD0);      
                digitalWrite(T_CLK,HIGH);
                digitalWrite(T_CLK,LOW);
                temp_y=touch_ReadData();

                if (!((temp_x>max(touch_x_left, touch_x_right)) or (temp_x==0) or (temp_y>max(touch_y_top, touch_y_bottom)) or (temp_y==0)))
                {
                        ty+=temp_x;
                        tx+=temp_y;
                        datacount++;
                }
        }

        digitalWrite(T_CS,HIGH);
        if (datacount>0)
        {
                if (orient == _default_orientation)
                {
                        TP_X=tx/datacount;
                        TP_Y=ty/datacount;
                }
                else
                {
                        TP_X=ty/datacount;
                        TP_Y=tx/datacount;
                }
        }
        else
        {
                TP_X=-1;
                TP_Y=-1;
        }
}

bool UTouch::dataAvailable()
{
        bool avail;
        pinMode(T_IRQ,  INPUT);
        avail = !digitalRead(T_IRQ);
        pinMode(T_IRQ,  OUTPUT);
        return avail;
}

int UTouch::getX()
{
        long c;

        if (orient == _default_orientation)
        {
                c = long(long(TP_X - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
                if (c<0)
                        c = 0;
                if (c>disp_x_size)
                        c = disp_x_size;
        }
        else
        {
                if (_default_orientation == PORTRAIT)
                        c = long(long(TP_X - touch_y_top) * (-disp_y_size)) / long(touch_y_bottom - touch_y_top) + long(disp_y_size);
                else
                        c = long(long(TP_X - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
                if (c<0)
                        c = 0;
                if (c>disp_y_size)
                        c = disp_y_size;
        }
        return c;
}

int UTouch::getY()
{
        int c;

        if (orient == _default_orientation)
        {
                c = long(long(TP_Y - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
                if (c<0)
                        c = 0;
                if (c>disp_y_size)
                        c = disp_y_size;
        }
        else
        {
                if (_default_orientation == PORTRAIT)
                        c = long(long(TP_Y - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
                else
                        c = long(long(TP_Y - touch_x_left) * (-disp_x_size)) / long(touch_x_right - touch_x_left) + long(disp_x_size);
                if (c<0)
                        c = 0;
                if (c>disp_x_size)
                        c = disp_x_size;
        }
        return c;
}

void UTouch::setPrecision(byte precision)
{
        switch (precision)
        {
                case PREC_LOW:
                        prec=1;
                        break;
                case PREC_MEDIUM:
                        prec=10;
                        break;
                case PREC_HI:
                        prec=25;
                        break;
                case PREC_EXTREME:
                        prec=100;
                        break;
                default:
                        prec=10;
                        break;
        }
}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-1-17 23:31:12 | 显示全部楼层
这是我移植到STM32的程序:
Touch.h

#include "stm32f10x.h" //声明STM32 ARM单片机核心库
#include "stm32f10x_easy.h"


//设定模拟SPI的GPIO端口(可以自行改动)
#define tport PB
#define trcc  RCC_PB

#define tclk  _10
#define tcs          _11
#define din          _8
#define dout  _7
#define irq          _5

//触摸校准数据(重要!请将触摸屏校准以后填入数据)
#define CAL_X 0x03AB80EDUL
#define CAL_Y 0x03B1C0A2UL
#define CAL_S 0x000EF13FUL

//触摸屏制式和精度声明(使用时自行选择)
#define PORTRAIT                        0
#define LANDSCAPE                        1

#define PREC_LOW                        1
#define PREC_MEDIUM                        2        //默认
#define PREC_HI                                3
#define PREC_EXTREME                4

void touch_Init(u8 orientation);                //初始化触摸
void touch_WriteData(u8 data);                        //写数据至触摸芯片
int touch_ReadData(void);                                //从触摸芯片读数据
void touch_Read(void);                                        //读取一次触摸数据
u8 touch_DataAvailable(void);                        //检测数据有效性(可以开始读取的标志)
int touch_getX(void);                                        //读取触摸X坐标
int touch_getY(void);                                        //读取触摸Y坐标
void touch_setPrecision(int precision);        //设置触摸精度

#define tmax(a,b)  (((a) > (b)) ? (a) : (b))        //数学函数
#define tmin(a,b)  (((a) < (b)) ? (a) : (b))



Touch.c


#include "stm32f10x.h" //声明STM32 ARM单片机核心库
#include "stm32f10x_easy.h"
#include "touch.h"

//触摸专用变量
long        _default_orientation;
u8                orient;
u8                prec;
u8                display_model;
long        disp_x_size, disp_y_size, default_orientation;
long        touch_x_left, touch_x_right, touch_y_top, touch_y_bottom;

int                TP_X ,TP_Y;        //最终获得的触摸数据

void touch_Init(u8 orientation)
{
        //设定模拟SPI总线
        APB2_Clock_On(trcc);        //打开GPIO.PORTx的时钟
        GPIOSet(tport,tclk | tcs | din | irq,O_PP,S_10M);        //配置模拟SPI的GPIO
        GPIOSet(tport,dout,INFLOAT,S_50M);

        //触摸方向、位置和校准初始化计算
        orient                                        = orientation;
        _default_orientation        = CAL_S>>31;
        touch_x_left                        = (CAL_X>>14) & 0x3FFF;
        touch_x_right                        = CAL_X & 0x3FFF;
        touch_y_top                                = (CAL_Y>>14) & 0x3FFF;
        touch_y_bottom                        = CAL_Y & 0x3FFF;
        disp_x_size                                = (CAL_S>>12) & 0x0FFF;
        disp_y_size                                = CAL_S & 0x0FFF;
        prec                                        = 10;

        GPIO_H(tport,tclk | tcs | din | irq);        //设定上拉信号线(SPI低电平有效)
}

void touch_WriteData(u8 data)
{
        int count = 0;

        u8 temp;

        temp=data;
        GPIO_L(tport,tclk);

        for(count=0; count<8; count++)
        {
                if(temp & 0x80)
                        GPIO_H(tport,din);
                else
                        GPIO_L(tport,din);
                temp = temp << 1;
                GPIO_L(tport,tclk);               
                delay_us(1);
                GPIO_H(tport,tclk);
                delay_us(1);
        }
}

int touch_ReadData(void)
{
        int count = 0;
        int data = 0;
        for(count=0; count<12; count++)
        {
                data <<= 1;
                GPIO_H(tport,tclk);               
                delay_us(1);
                GPIO_L(tport,tclk);
                delay_us(1);
                if (PinRead(tport,dout))
                        data++;
        }
        return(data);
}

void touch_Read(void)
{
        int i = 0;
        unsigned long tx=0, temp_x=0;
        unsigned long ty=0, temp_y=0;
        int datacount=0;
        GPIO_L(tport,tcs);                    

        for (i=0; i<prec; i++)
        {
                touch_WriteData(0x90);        
                GPIO_H(tport,tclk);
                delay_us(1);
                GPIO_L(tport,tclk);
                delay_us(1);
                temp_x=touch_ReadData();

                touch_WriteData(0xD0);      
                GPIO_H(tport,tclk);
                delay_us(1);
                GPIO_L(tport,tclk);
                delay_us(1);
                temp_y=touch_ReadData();

                if (!((temp_x>tmax(touch_x_left, touch_x_right)) || (temp_x==0) || (temp_y>tmax(touch_y_top, touch_y_bottom)) || (temp_y==0)))
                {
                        ty+=temp_x;
                        tx+=temp_y;
                        datacount++;
                }
        }

        GPIO_H(tport,tcs);
        if (datacount>0)
        {
                if (orient == _default_orientation)
                {
                        TP_X=tx/datacount;
                        TP_Y=ty/datacount;
                }
                else
                {
                        TP_X=ty/datacount;
                        TP_Y=tx/datacount;
                }
        }
        else
        {
                TP_X=-1;
                TP_Y=-1;
        }
}

u8 touch_DataAvailable(void)
{
        u8 avail;
        GPIOSet(tport,irq,INFLOAT,S_10M);
        avail = !PinRead(tport,irq);
        GPIOSet(tport,irq,O_PP,S_10M);
        return avail;
}

int touch_getX(void)
{
        long c;

        if (orient == _default_orientation)
        {
                c = (long)((long)(TP_X - touch_x_left) * (disp_x_size)) / (long)(touch_x_right - touch_x_left);
                if (c<0)
                        c = 0;
                if (c>disp_x_size)
                        c = disp_x_size;
        }
        else
        {
                if (_default_orientation == PORTRAIT)
                        c = (long)((long)(TP_X - touch_y_top) * (-disp_y_size)) / (long)(touch_y_bottom - touch_y_top) + (long)(disp_y_size);
                else
                        c = (long)((long)(TP_X - touch_y_top) * (disp_y_size)) / (long)(touch_y_bottom - touch_y_top);
                if (c<0)
                        c = 0;
                if (c>disp_y_size)
                        c = disp_y_size;
        }
        return c;
}

int touch_getY(void)
{
        int c;

        if (orient == _default_orientation)
        {
                c = (long)((long)(TP_Y - touch_y_top) * (disp_y_size)) / (long)(touch_y_bottom - touch_y_top);
                if (c<0)
                        c = 0;
                if (c>disp_y_size)
                        c = disp_y_size;
        }
        else
        {
                if (_default_orientation == PORTRAIT)
                        c = (long)((long)(TP_Y - touch_x_left) * (disp_x_size)) / (long)(touch_x_right - touch_x_left);
                else
                        c = (long)((long)(TP_Y - touch_x_left) * (-disp_x_size)) / (long)(touch_x_right - touch_x_left) + (long)(disp_x_size);
                if (c<0)
                        c = 0;
                if (c>disp_x_size)
                        c = disp_x_size;
        }
        return c;
}

void touch_setPrecision(int precision)
{
        switch (precision)
        {
                case PREC_LOW:
                        prec=1;
                        break;
                case PREC_MEDIUM:
                        prec=10;
                        break;
                case PREC_HI:
                        prec=25;
                        break;
                case PREC_EXTREME:
                        prec=100;
                        break;
                default:
                        prec=10;
                        break;
        }
}
回复 支持 反对

使用道具 举报

发表于 2014-3-20 18:31:22 | 显示全部楼层
FoieDEEEE_仲敬 发表于 2014-1-17 23:31
这是我移植到STM32的程序:
Touch.h

stm32可以直接用c++写吧,不一定非得写成C,直接加入C++的库里面试验下
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-5 13:53 , Processed in 0.041107 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表