刚接触LPC5411芯片,想用来驱动彩屏是2.4寸TFT LCD屏初始化没问题,已经可以点亮了。但是触摸屏配置出错,触摸管脚TP_SCL、TP_SDA 、TP_RESET 、TP_INT对应的PIO0_23、PIO0_24、PIO0_25、PIO0_26,调试程序卡在 i2c_xfer_poll(&xfer)函数。请问是不是管脚有没有配置错误,还是IIC出错。
触摸模块部分代码:
#include "board.h"
#include "string.h"
#include "stdlib.h"
TouchPtStructure touch_point = {0};
I2CM_XFER_T xfer;
#define FT6236_RES(val) (LPC_GPIO->B[0][25]=val)
#define SLAVE_ADDR (0x70>>1)
#define I2C0_FLEXCOMM 4
#define I2C_BITRATE 400000
#define LPC_I2C_PORT LPC_I2C0
const uint16_t FT6236_TPX_TBL[5] =
{
FT_TP1_REG,
FT_TP2_REG,
FT_TP3_REG,
FT_TP4_REG,
FT_TP5_REG
};
static void Init_I2C_PinMux(void)
{
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 23, (IOCON_FUNC1 | IOCON_FASTI2C_EN | IOCON_DIGITAL_EN));
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 24, (IOCON_FUNC1 | IOCON_FASTI2C_EN | IOCON_DIGITAL_EN));
}
/* Setup I2C */
static void setupI2CMaster(void)
{
xfer.slaveAddr = SLAVE_ADDR;
/* Enable pin muxing */
Init_I2C_PinMux();
/* Enable I2C clock and reset I2C peripheral */
Chip_I2C_Init(LPC_I2C_PORT);
/* Setup I2CM transfer rate */
Chip_I2CM_SetBusSpeed(LPC_I2C_PORT, I2C_BITRATE);
/* Enable I2C master interface */
Chip_I2CM_Enable(LPC_I2C_PORT);
}
static void i2c_error(bool abbr, uint32_t i2c_error)
{
if (abbr == false) {
DEBUGOUT("I2C error: ");
}
switch (i2c_error) {
case I2CM_STATUS_ERROR:
DEBUGOUT((abbr == true) ? " er" : "Unknown error\r\n");
break;
case I2CM_STATUS_NAK_ADR:
DEBUGOUT((abbr == true) ? " na" : "NAK address\r\n");
break;
case I2CM_STATUS_BUS_ERROR:
DEBUGOUT((abbr == true) ? " be" : "Bus error\r\n");
break;
case I2CM_STATUS_NAK_DAT:
DEBUGOUT((abbr == true) ? " nd" : "NAK data\r\n");
break;
case I2CM_STATUS_ARBLOST:
DEBUGOUT((abbr == true) ? " al" : "Arbitration lost\r\n");
break;
case I2CM_STATUS_BUSY:
DEBUGOUT((abbr == true) ? " bs" : "Busy\r\n");
break;
default:
DEBUGOUT(" --");
}
}
/* I2C Polled mode transfers */
static void i2c_xfer_poll(I2CM_XFER_T *i2cmXferRec)
{
Chip_I2CM_XferBlocking(LPC_I2C_PORT, i2cmXferRec);
if (i2cmXferRec->status != I2CM_STATUS_OK) {
i2c_error(false, i2cmXferRec->status);
}
DEBUGOUT("i2c_out_poll\r\n");
}
void touch_wr_reg(uint8_t addr, uint8_t *buf, uint32_t length)
{
uint8_t *tmp_buf;
tmp_buf = (uint8_t *)malloc(1+length);
if(tmp_buf == NULL)
return;
tmp_buf[0] = addr;
memcpy(&tmp_buf[1], buf, length);
xfer.rxSz = 0;
xfer.rxBuff = 0;
xfer.txSz = length+1;
xfer.txBuff = tmp_buf;
xfer.status = 0;
i2c_xfer_poll(&xfer);
free(tmp_buf);
}
void touch_rd_reg(uint8_t addr, uint8_t *buf, uint32_t length)
{
xfer.txSz = 1;
xfer.txBuff = &addr;
xfer.rxSz = length;
xfer.rxBuff = buf;
xfer.status = 0;
i2c_xfer_poll(&xfer);
}
void touch_init(void)
{
uint32_t dlyms_cnt = 0;
uint8_t data;
// FT6236_RES(1);
/* RST引脚初始化为高电平 */
setupI2CMaster();
Chip_GPIO_SetPortDIRInput(LPC_GPIO, 0, 26);
dlyms_cnt = Chip_Clock_GetSystemClockRate()/3000;
FT6236_RES(0);
sysSoftlDly(dlyms_cnt*50);
FT6236_RES(1);
sysSoftlDly(dlyms_cnt*100);
data = 0;
touch_wr_reg(FT_DEVIDE_MODE,&data,1); /* 进入正常操作模式 */
data=8; /* 触摸有效值,越小越灵敏 */
touch_wr_reg(FT_ID_G_THGROUP,&data,1); /* 设置触摸有效值 */
data=14; /* 激活周期,不能小于12,最大14 */
touch_wr_reg(FT_ID_G_PERIODACTIVE,&data,1);
FT6236_RES(1);
}
void touch_scan(void)
{
uint8_t i=0;
uint8_t sta = 0;
uint8_t buf[4] = {0};
touch_rd_reg(0x02,&sta,1); //读取触摸点的状态
if(sta & 0x0f) //判断是否有触摸点按下,0x02寄存器的低4位表示有效触点个数
{
touch_point.touch_sta = ~(0xFF << (sta & 0x0F)); //~(0xFF << (sta & 0x0F))将点的个数转换为触摸点按下有效标志
for(i=0;i<5;i++) //分别判断触摸点1-5是否被按下
{
if(touch_point.touch_sta & (1<
{ //被按下则读取对应触摸点坐标数据
touch_rd_reg(FT6236_TPX_TBL[i],buf,4); //读取XY坐标值
touch_point.x[i]=((uint16_t)(buf[0]&0X0F)<<8)+buf[1];
touch_point.y[i]=((uint16_t)(buf[2]&0X0F)<<8)+buf[3];
if((buf[0]&0xC0)!=0X80)
{
touch_point.x[i]=touch_point.y[i]=-1; //必须是contact事件,才认为有效
return;
}
}
}
touch_point.touch_sta |= TP_PRES_DOWN; //触摸按下标记
}
else
{
if(touch_point.touch_sta &TP_PRES_DOWN) //之前是被按下的
touch_point.touch_sta &= ~0x80; //触摸松开标记
else
{
touch_point.x[0] = -1;
touch_point.y[0] = -1;
touch_point.touch_sta &=0xe0; //清楚触摸点有效标记
}
}
}
#ifndef __FT6236_H
#define __FT6236_H
#include "stdint.h"
#define TP_PRES_DOWN 0x80 //触屏被按下
#define TP_PRES_UP 0x00 //触摸松开
//触摸点相关数据结构体定义
typedef struct
{
uint8_t touch_sta; //触摸情况,b7:按下1/松开0;b6:5:保留;b4-b0触摸点按下有效标志,有效为1,分别对应触摸点5-1;
uint16_t x[5]; //支持5点触摸,需要使用5组坐标存储触摸点数据
uint16_t y[5];
}TouchPtStructure;
extern TouchPtStructure touch_point;
//FT6236 部分寄存器定义
#define FT_DEVIDE_MODE 0x00 //FT6236模式控制寄存器
#define FT_REG_NUM_FINGER 0x02 //触摸状态寄存器
#define FT_TP1_REG 0X03 //第一个触摸点数据地址
#define FT_TP2_REG 0X09 //第二个触摸点数据地址
#define FT_TP3_REG 0X0F //第三个触摸点数据地址
#define FT_TP4_REG 0X15 //第四个触摸点数据地址
#define FT_TP5_REG 0X1B //第五个触摸点数据地址
#define FT_ID_G_LIB_VERSION 0xA1 //版本
#define FT_ID_G_MODE 0xA4 //FT6236中断模式控制寄存器
#define FT_ID_G_THGROUP 0x80 //触摸有效值设置寄存器
#define FT_ID_G_PERIODACTIVE 0x88 //激活状态周期设置寄存器
#define Chip_Vendor_ID 0xA3 //芯片ID(0x36)
#define ID_G_FT6236ID 0xA8 //0x11
void touch_init(void);
void touch_scan(void);
#endif