XPT2046デバッグ

要約すると、ハードウェアSPIを使用してタッチデータを読み取ります。

デバッグしなかった主な理由は、SDIとSDOが間違っていたためです。

データにラダーレベルがあることを確認します。将来ラダーレベルを見つけた場合は、送受信が逆になっていないか検討してください。

抵抗膜方式のタッチは比較的簡単です。対応するコマンド0xD00x90を直接送信して、タッチデータの水平線と垂直線を読み取ります。

最大エッジ値と最小エッジ値を見つけます。スケールを計算します。

/**
 * @file XPT2046.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "at32f4xx.h"
#include "XPT2046.h"
#if USE_XPT2046

#include <stddef.h>
#include LV_DRV_INDEV_INCLUDE
#include LV_DRV_DELAY_INCLUDE

/*********************
 *      DEFINES
 *********************/
//#define CMD_X_READ  0b10010000
//#define CMD_Y_READ  0b11010000

#define CMD_X_READ  0x90
#define CMD_Y_READ  0xD0

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void xpt2046_corr(int16_t * x, int16_t * y);
static void xpt2046_avg(int16_t * x, int16_t * y);

/**********************
 *  STATIC VARIABLES
 **********************/
int16_t avg_buf_x[XPT2046_AVG];
int16_t avg_buf_y[XPT2046_AVG];
uint8_t avg_last;

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

/**
 * Initialize the XPT2046
 */
void xpt2046_init(void)
{

	 时钟初始化
	// 切换JTAG-SPI3 不然主功能是JTAG
	RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_AFIO, ENABLE);
	GPIO_PinsRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
	
	RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOB|RCC_APB2PERIPH_SPI1,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_SPI3,ENABLE);
	// SPI3 
	
	GPIO_InitType GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pins = SPI3_PIN_SCK | SPI3_PIN_MOSI;
	GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pins = SPI3_PIN_MISO;
	GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pins = SPI3_PIN_CS;
	GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
    GPIO_InitStructure.GPIO_Pins = SPI3_PIN_IRQ;
	GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	SPI_InitType SPI_InitStructure;
	/* SPI_MASTER configuration ------------------------------------------------------*/
	SPI_InitStructure.SPI_TransMode = SPI_TRANSMODE_FULLDUPLEX;
	SPI_InitStructure.SPI_Mode = SPI_MODE_MASTER;
	SPI_InitStructure.SPI_FrameSize = SPI_FRAMESIZE_8BIT;
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_HIGH;
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2EDGE;
	SPI_InitStructure.SPI_NSSSEL = SPI_NSSSEL_SOFT;
	SPI_InitStructure.SPI_MCLKP = SPI_MCLKP_64;//SPI_MCLKP_2
	SPI_InitStructure.SPI_FirstBit = SPI_FIRSTBIT_MSB;
	SPI_InitStructure.SPI_CPOLY = 7;
	SPI_Init(SPI3, &SPI_InitStructure);

	/* Enable SPI_MASTER NSS output for master mode */
	SPI_NSSHardwareOutputEnable(SPI3, DISABLE);

	/* Enable SPI_MASTER */
	SPI_Enable(SPI3, ENABLE);
}

uint8_t spi_read_data(uint8_t data)
{
	SPI_I2S_TxData(SPI3,data);
	while(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TE) == RESET);
	while(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_BUSY) == SET);
	return SPI_I2S_RxData(SPI3);
}


static uint16_t volatile ad_x = 0;
static uint16_t volatile ad_y = 0;
/**
 * Get the current position and state of the touchpad
 * @param data store the read data here
 * @return false: because no ore data to be read
 */
bool xpt2046_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
    static int16_t last_x = 0;
    static int16_t last_y = 0;
    uint8_t buf;

    int16_t x = 0;
    int16_t y = 0;

    uint8_t irq = LV_DRV_INDEV_IRQ_READ;

    if(irq == 0) {
        LV_DRV_INDEV_SPI_CS(0);

        LV_DRV_INDEV_SPI_XCHG_BYTE(CMD_X_READ);         /*Start x read*/

        buf = LV_DRV_INDEV_SPI_XCHG_BYTE(0);           /*Read x MSB*/
        x = buf << 8;
        buf = LV_DRV_INDEV_SPI_XCHG_BYTE(CMD_Y_READ);  /*Until x LSB converted y command can be sent*/
        x += buf;

        buf =  LV_DRV_INDEV_SPI_XCHG_BYTE(0);   /*Read y MSB*/
        y = buf << 8;

        buf =  LV_DRV_INDEV_SPI_XCHG_BYTE(0);   /*Read y LSB*/
        y += buf;

		ad_x = x;
		ad_y = y;
        /*Normalize Data*/
        x = x >> 3;
        y = y >> 3;
        xpt2046_corr(&x, &y);
        xpt2046_avg(&x, &y);

        last_x = x;
        last_y = y;
		data->state = LV_INDEV_STATE_PR;

        LV_DRV_INDEV_SPI_CS(1);
    } else {
        x = last_x;
        y = last_y;
        avg_last = 0;
		data->state = LV_INDEV_STATE_REL;
    }

    data->point.x = x;
    data->point.y = y;

    return false;
}

/**********************
 *   STATIC FUNCTIONS
 **********************/
static void xpt2046_corr(int16_t * x, int16_t * y)
{
#define XPT2046_XY_SWAP 1
#if XPT2046_XY_SWAP != 0
    int16_t swap_tmp;
    swap_tmp = *x;
    *x = *y;
    *y = swap_tmp;
#endif

    if((*x) > XPT2046_X_MIN)(*x) -= XPT2046_X_MIN;
    else(*x) = 0;

    if((*y) > XPT2046_Y_MIN)(*y) -= XPT2046_Y_MIN;
    else(*y) = 0;

    (*x) = (uint32_t)((uint32_t)(*x) * XPT2046_HOR_RES) /
           (XPT2046_X_MAX - XPT2046_X_MIN);

    (*y) = (uint32_t)((uint32_t)(*y) * XPT2046_VER_RES) /
           (XPT2046_Y_MAX - XPT2046_Y_MIN);

#define XPT2046_X_INV  1
#if XPT2046_X_INV != 0
    (*x) =  XPT2046_HOR_RES - (*x);
#endif
#define XPT2046_Y_INV 0  
#if XPT2046_Y_INV != 0
    (*y) =  XPT2046_VER_RES - (*y);
#endif


}


static void xpt2046_avg(int16_t * x, int16_t * y)
{
    /*Shift out the oldest data*/
    uint8_t i;
    for(i = XPT2046_AVG - 1; i > 0 ; i--) {
        avg_buf_x[i] = avg_buf_x[i - 1];
        avg_buf_y[i] = avg_buf_y[i - 1];
    }

    /*Insert the new point*/
    avg_buf_x[0] = *x;
    avg_buf_y[0] = *y;
    if(avg_last < XPT2046_AVG) avg_last++;

    /*Sum the x and y coordinates*/
    int32_t x_sum = 0;
    int32_t y_sum = 0;
    for(i = 0; i < avg_last ; i++) {
        x_sum += avg_buf_x[i];
        y_sum += avg_buf_y[i];
    }

    /*Normalize the sums*/
    (*x) = (int32_t)x_sum / avg_last;
    (*y) = (int32_t)y_sum / avg_last;
}

#endif

重要な点は、ICのIRQが押されたときに低レベルであるかどうかを確認することです。

XPT2046の伝送速度

 

おすすめ

転載: blog.csdn.net/C_ROOKIES/article/details/107234508