首页 > 编程知识 正文

Linux开发stm32的优点(xpt2046历程)

时间:2023-05-05 17:23:39 阅读:74016 作者:442

针的功能说明

控制字的控制位指令

控制字节的各说明

单端模式输入配置

差分模式输入结构

时间序列

前8个时钟用于从DIN引脚输入控制字节,后12个时钟周期用于完成真正的模数转换,剩下的3个多时钟周期用于完成转换器忽略的最后一个字节(例如

举个例子

#define TOUCH_READ_TIMES 40 //读取次数

#define TOUCH_ERR_RANGE 20 //误差范围

#define TOUCH_X_CMD0xD0 //读取x轴

#define TOUCH_Y_CMD0x90 //读取y轴

#define TOUCH_Continue_Read0xFF

#define TOUCH_X_MAX 4000 //X最高值

#define TOUCH_X_MIN 100 //X最小值

#define TOUCH_Y_MAX 4000 //Y最高值

#define TOUCH_Y_MIN 100 //X最小值

#defineLCD_calx_min(10 ) /校准点最小值x

# define LCD _ calx _ max (tft LCD _ data.width-LCD _ calx _ min ) /校准点最大值x

#defineLCD_caly_min(10 ) /校准点最小值y

# define LCD _ caly _ max (tft LCD _ data.height-LCD _ caly _ min ) /校准点最大值y

# define LCD _ cal _ x (LCD _ calx _ max-LCD _ calx _ min ) /盒宽度

# define LCD _ cal _ y (LCD _ caly _ max-LCD _ caly _ min ) /盒高度

#define TOUCH_CAL_OK 'Y' //校准OK标志

#define TOUCH_CAL_ADDR 200 //将校准参数保存到at24c02

类型结构

{

u8标志;

短偏移;

短偏移;

浮动x因子;

浮动因子;

} calibrate_t;

calibrate_t calibrate={0};

u16托尔克斯;

u16托克丝;

void TOUCH_init (

{

GPIO_InitTypeDef gpioa=

{

gpio _ pin _5| gpio _ pin _6| gpio _ pin _ 7,

GPIO_Speed_50MHz,

GPIO_Mode_AF_PP

(;

GPIO_InitTypeDef gpiod6=

{

GPIO_Pin_6,

GPIO_Speed_50MHz,

GPIO_Mode_Out_PP

(;

GPIO_InitTypeDef gpiod7=

{

GPIO_Pin_7,

GPIO_Speed_50MHz,

GPIO_Mode_IPU

(;

SPI_InitTypeDef spi=

{

SPI _ direction _2lines _ full duplex,

SPI_Mode_Master,//0x0104

SPI_DataSize_8b,

SPI_CPOL_High,

SPI_CPHA_2Edge,

SPI_NSS_Soft,

SPI_BaudRatePrescaler_256,

SPI_FirstBit_MSB,

7

(;

RCC _ AP B2 periphclockcmd (RCC _ AP B2 per iph _ SPI1| RCC _ AP B2 per iph _ gpioa|RCC _ AP B2 per iph _ gpiod,ENABLE );

Gpio_init(gpioa,gpioa );

gpio_init(gp

IOD, &gpiod6);

GPIO_Init(GPIOD, &gpiod7);

SPI_Init(SPI1, &spi); //初始化SPI

SPI_Cmd(SPI1, ENABLE); //使能SPI

}

u16 TOUCH_read(u16 cmd)

{

u8 i = 0, j = 0;

u16 tmp;

u16 value[TOUCH_READ_TIMES] = {0};

u32 total_value = 0;

SPI1_SetSpeed(SPI_BaudRatePrescaler_32); //设置SPI速度

for(i = 0; i < TOUCH_READ_TIMES; i++) //读取次数

{

TOUCH_CS = 0;

SPI1_read_write(cmd);

value[i] = SPI1_read_write(TOUCH_Continue_Read) << 8; //详见时序

value[i] |= SPI1_read_write(TOUCH_Continue_Read);

value[i] >>= 3;

TOUCH_CS = 1;

}

for (i = 0; i < TOUCH_READ_TIMES; i++) //排序

{

for (j = i + 1; j < TOUCH_READ_TIMES; j++)

{

if (value[i] < value[j])

{

tmp = value[i];

value[i] = value[j];

value[j] = tmp;

}

}

}

for (i = 1; i < TOUCH_READ_TIMES - 1; i++) //去掉一个最大值,一个最小值

{

total_value += value[i];

}

total_value /= (TOUCH_READ_TIMES - 2); //求平均值

return total_value;

}

u8 TOUCH_readXY(u16 *x, u16 *y)

{

u16 valueX1, valueY1, valueX2, valueY2;

valueX1 = TOUCH_read(TOUCH_X_CMD); //读取触摸值

valueY1 = TOUCH_read(TOUCH_Y_CMD);

valueX2 = TOUCH_read(TOUCH_X_CMD);

valueY2 = TOUCH_read(TOUCH_Y_CMD);

*x = valueX1 > valueX2 ? (valueX1 - valueX2) : (valueX2 - valueX1);

*y = valueY1 > valueY2 ? (valueY1 - valueY2) : (valueY2 - valueY1);

if((*x > TOUCH_ERR_RANGE) || (*y > TOUCH_ERR_RANGE)) //判断容错范围

{

return 0xFF;

}

*x = (valueX1 + valueX2) / 2;

*y = (valueY1 + valueY2) / 2;

if((*x < TOUCH_X_MIN || *x > TOUCH_X_MAX) || //判断边界范围

(*y < TOUCH_Y_MIN || *y > TOUCH_Y_MAX))

{

return 0xFF;

}

return 0;

}

void TOUCH_start_calibrate(u16 x, u16 y, u16 *valueX,u16 *valueY) //开始校准

{

u8 i = 0;

LCD_Clear(BACK_COLOR); //清屏

LCD_DrowSign(x, y, BACK_COLOR); //画十字

while(1)

{

if(TOUCH_readXY(valueX, valueY) != 0xFF)

{

i++;

if(i > 10)

{

LCD_DrowSign(x, y, BACK_COLOR);

break;

}

}

}

}

void TOUCH_calibrate()

{

u16 px[2], py[2], valueX[4], valueY[4];

float xFactor = 0, yFactor = 0;

TOUCH_start_calibrate(LCD_CALx_MIN, LCD_CALy_MIN, &valueX[0], &valueY[0]); //第一次校准

delay_ms(500);

TOUCH_start_calibrate(LCD_CALx_MIN, LCD_CALy_MAX, &valueX[1], &valueY[1]);

delay_ms(500);

TOUCH_start_calibrate(LCD_CALx_MAX, LCD_CALy_MIN, &valueX[2], &valueY[2]);

delay_ms(500);

TOUCH_start_calibrate(LCD_CALx_MAX, LCD_CALy_MAX, &valueX[3], &valueY[3]);

delay_ms(500);

//整合成对角的两点

px[0] = (valueX[0] + valueX[1]) / 2;

py[0] = (valueY[0] + valueY[2]) / 2;

px[1] = (valueX[3] + valueX[2]) / 2;

py[1] = (valueY[3] + valueY[1]) / 2;

//求出比例因子

xFactor = (float)LCD_CAL_X / (px[1] - px[0]);

yFactor = (float)LCD_CAL_Y / (py[1] - py[0]);

//求出偏移量

calibrate.xoffset = (short)LCD_CALx_MAX - ((float)px[1] * xFactor);

calibrate.yoffset = (short)LCD_CALy_MAX - ((float)py[1] * yFactor);

calibrate.xFactor = xFactor ;

calibrate.yFactor = yFactor ;

printf("xoffset %dn", calibrate.xoffset);

printf("yoffset %dn", calibrate.yoffset);

printf("xFactor %fn", calibrate.xFactor);

printf("yFactor %fn", calibrate.yFactor);

//保存校准数据到at24c02

calibrate.flag = TOUCH_CAL_OK;

at24c02Write_buf((u8*)&calibrate, TOUCH_CAL_ADDR, sizeof(calibrate));

}

u8 TOUCH_scan() //查看是否触摸

{

u16 valueX;

u16 valueY;

if(TOUCH_readXY(&valueX, &valueY) == 0xFF)

{

return 0xFF;

}

//根据物理坐标,计算彩屏坐标

touchX = valueX * calibrate.xFactor + calibrate.xoffset;

touchY = valueY * calibrate.yFactor + calibrate.yoffset;

if((touchX > tftlcd_data.width) || (touchY > tftlcd_data.height))

{

return 0xFF;

}

return 0;

}

int main(void)

{

I2C_init();

TOUCH_init();

at24c02Read_buf((u8*)&calibrate, TOUCH_CAL_ADDR, sizeof(calibrate));

if(calibrate.flag != TOUCH_CAL_OK) //判断是否已经校准

{

TOUCH_calibrate();

}

LCD_ShowString(tftlcd_data.width-40,0,tftlcd_data.width,tftlcd_data.height,16,"clear");

while(1)

{

if(TOUCH_scan() == 0)

{

LCD_Fill(touchX-1, touchY-1, touchX+2, touchY+2, FRONT_COLOR); //画粗线

if((touchX > tftlcd_data.width-40) && (touchY < 20))

{

LCD_Fill(0, 0, tftlcd_data.width,tftlcd_data.height, BACK_COLOR); //清屏

LCD_ShowString(tftlcd_data.width-40,0,tftlcd_data.width,tftlcd_data.height,16,"clear");

}

}

}

}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。