250 lines
5.0 KiB
C
250 lines
5.0 KiB
C
#include "BoardCfg.h"
|
||
/**********************************************************
|
||
行注释
|
||
内容:HAL层
|
||
|
||
DOUT MISO C7
|
||
DIN MOSI A10
|
||
CS M20
|
||
CLK A9
|
||
|
||
|
||
|
||
**********************************************************/
|
||
void XPY2046Init()
|
||
{
|
||
GPIO_Init(GPIOA, PIN10, 1, 0, 0);
|
||
GPIO_Init(GPIOA, PIN9, 1, 0, 0);
|
||
GPIO_Init(GPIOM, PIN20, 1, 0, 0);
|
||
GPIO_Init(GPIOC, PIN7, 0, 1, 0);
|
||
}
|
||
/**
|
||
* @brief XTP DOUT线操作
|
||
*
|
||
* @param val 0/1
|
||
*/
|
||
static void XPT2046_DOUT_Write(u8 val)
|
||
{
|
||
if (val)
|
||
{
|
||
GPIO_SetBit(GPIOA, PIN10);
|
||
}
|
||
else
|
||
{
|
||
GPIO_ClrBit(GPIOA, PIN10);
|
||
}
|
||
}
|
||
/**
|
||
* @brief XTP CLK线操作
|
||
*
|
||
* @param val 0/1
|
||
*/
|
||
static void XPT2046_CLK_Write(u8 val)
|
||
{
|
||
if (val)
|
||
{
|
||
GPIO_SetBit(GPIOA, PIN9);
|
||
}
|
||
else
|
||
{
|
||
GPIO_ClrBit(GPIOA, PIN9);
|
||
}
|
||
}
|
||
/**
|
||
* @brief XTP DIN线操作
|
||
*
|
||
* @param val 0/1
|
||
*/
|
||
static u8 XPT2046_DIN_Read()
|
||
{
|
||
return GPIO_GetBit(GPIOC, PIN7);
|
||
}
|
||
/**
|
||
* @brief XTP CS线操作
|
||
*
|
||
* @param val 0/1
|
||
*/
|
||
static void XPT2046_CS_Write(u8 val)
|
||
{
|
||
if (val)
|
||
{
|
||
GPIO_SetBit(GPIOM, PIN20);
|
||
}
|
||
else
|
||
{
|
||
GPIO_ClrBit(GPIOM, PIN20);
|
||
}
|
||
}
|
||
/**
|
||
* @brief 延迟1us
|
||
* interface
|
||
* @param time
|
||
*/
|
||
static void DelayUs(u32 time)
|
||
{
|
||
for (u32 i = 0; i < time; i++)
|
||
{
|
||
for (u32 j = 0; j < 1000; j++)
|
||
{
|
||
__ASM("nop");
|
||
}
|
||
}
|
||
}
|
||
|
||
u8 CMD_RDX = 0XD0;
|
||
u8 CMD_RDY = 0X90;
|
||
/**********************************************************
|
||
行注释
|
||
内容:
|
||
**********************************************************/
|
||
static void TP_Write_Byte(u8 num)
|
||
{
|
||
u8 count = 0;
|
||
for (count = 0; count < 8; count++)
|
||
{
|
||
if (num & 0x80)
|
||
XPT2046_DOUT_Write(1);
|
||
else
|
||
XPT2046_DOUT_Write(0);
|
||
num <<= 1;
|
||
XPT2046_CLK_Write(0);
|
||
DelayUs(1);
|
||
XPT2046_CLK_Write(1);
|
||
}
|
||
}
|
||
|
||
u16 TP_Read_AD(u8 CMD)
|
||
{
|
||
u8 count = 0;
|
||
u16 Num = 0;
|
||
XPT2046_CLK_Write(0); //先拉低时钟
|
||
XPT2046_DOUT_Write(0); //拉低数据线
|
||
XPT2046_CS_Write(0); //选中触摸屏IC
|
||
TP_Write_Byte(CMD); //发送命令字
|
||
DelayUs(6); // ADS7846的转换时间最长为6us
|
||
XPT2046_CLK_Write(0);
|
||
DelayUs(1);
|
||
XPT2046_CLK_Write(1); //给1个时钟,清除BUSY
|
||
DelayUs(1);
|
||
XPT2046_CLK_Write(0);
|
||
for (count = 0; count < 16; count++) //读出16位数据,只有高12位有效
|
||
{
|
||
Num <<= 1;
|
||
XPT2046_CLK_Write(0); //下降沿有效
|
||
DelayUs(1);
|
||
XPT2046_CLK_Write(1);
|
||
if (XPT2046_DIN_Read())
|
||
Num++;
|
||
}
|
||
Num >>= 4; //只有高12位有效.
|
||
XPT2046_CS_Write(1); //释放片选
|
||
return (Num);
|
||
}
|
||
#define READ_TIMES 1 //读取次数
|
||
#define LOST_VAL 0 //丢弃值
|
||
u16 TP_Read_XOY(u8 xy)
|
||
{
|
||
u16 i, j;
|
||
u16 buf[READ_TIMES];
|
||
u16 sum = 0;
|
||
u16 temp;
|
||
for (i = 0; i < READ_TIMES; i++)
|
||
buf[i] = TP_Read_AD(xy);
|
||
for (i = 0; i < READ_TIMES - 1; i++) //排序
|
||
{
|
||
for (j = i + 1; j < READ_TIMES; j++)
|
||
{
|
||
if (buf[i] > buf[j]) //升序排列
|
||
{
|
||
temp = buf[i];
|
||
buf[i] = buf[j];
|
||
buf[j] = temp;
|
||
}
|
||
}
|
||
}
|
||
sum = 0;
|
||
for (i = LOST_VAL; i < READ_TIMES - LOST_VAL; i++)
|
||
sum += buf[i];
|
||
temp = sum / (READ_TIMES - 2 * LOST_VAL);
|
||
return temp;
|
||
}
|
||
/**
|
||
* @brief XPT2046读取X,Y
|
||
* (interface)
|
||
* @param x x坐标
|
||
* @param y y坐标
|
||
* @return u8
|
||
*/
|
||
u8 TP_Read_XY(u16 *x, u16 *y)
|
||
{
|
||
u16 xtemp, ytemp;
|
||
xtemp = TP_Read_XOY(CMD_RDX);
|
||
ytemp = TP_Read_XOY(CMD_RDY);
|
||
// if(xtemp<100||ytemp<100)return 0;//读数失败
|
||
*x = xtemp;
|
||
*y = ytemp;
|
||
return 1; //读数成功
|
||
}
|
||
|
||
/**
|
||
* @brief 二次函数拟合
|
||
* y = kx +b
|
||
* y1 = kx1+b
|
||
* y2 = kx2+b
|
||
* y1-y2 = k(x1-x2)
|
||
* k = (y1-y2)/(x1-x2)
|
||
* b = y1-kx1
|
||
* @param iniput
|
||
* @param x1
|
||
* @param y1
|
||
* @param x2
|
||
* @param y2
|
||
* @return u16
|
||
*/
|
||
static u16 ChangeCoordinate(u16 input, float x1, float y1, float x2, float y2)
|
||
{
|
||
float k = (y1 - y2) / (x2 - x1);
|
||
float b = y1 - k * x1;
|
||
float result = k * (float)input + b;
|
||
return (u16)result;
|
||
}
|
||
#define AVG_XOY 5
|
||
/**
|
||
* @brief 获取电阻屏的坐标
|
||
* interface out
|
||
* @param x x坐标
|
||
* @param y y坐标
|
||
* @return u8 0:没有触摸,1:按下
|
||
* (0,0)->(3970,3780)
|
||
* (800,480)->(100,200)
|
||
* (3870/800)
|
||
*
|
||
*/
|
||
u8 GetXY(u16 *x, u16 *y)
|
||
{
|
||
u16 tempX = 0, tempY = 0;
|
||
static u16 lastX,lastY;
|
||
TP_Read_XY(&tempX,&tempY);
|
||
// if(tempX-lastX>50||tempY-lastY>50){
|
||
// lastX = tempX;
|
||
// lastY = tempY;
|
||
// return 0;
|
||
// }
|
||
|
||
// for(u16 i=0;i<AVG_XOY;i++){
|
||
// u16 ttx,tty;
|
||
// TP_Read_XY(&ttx,&tty);
|
||
// tempX+=ttx;
|
||
// tempY+=tty;
|
||
// }
|
||
// tempX = tempX/AVG_XOY;
|
||
// tempY = tempY/AVG_XOY;
|
||
if (tempX == 0)
|
||
{
|
||
return 0;
|
||
}
|
||
*x = ChangeCoordinate(tempX, 3970.0, 0.0, 100.0, 800.0);
|
||
*y = ChangeCoordinate(tempY, 3780.0, 0.0, 200.0, 480.0);
|
||
// Printf("tempX:%d,tempY:%d\n", *x, *y);
|
||
return 1;
|
||
} |