Appearance
电阻触摸屏XPT2046
实现
一边链接电阻屏, 另一边链接stm32, PENDIRQ, 有信号之后产生信号, AUX电压辅助通道不使用,PENIRQ 变低并作为处理器的中断信号
控制原理
4线触摸屏控制器, 使用SPi接口, 内部有一个12位分辨率的ADC, 125KHz, 是一个逐步逼近性的AD转换器
实际上是一个十二位的ADC, 最大为4096, 通过比例获得位置, 使用内部电压源, 通过发送命令获得数据
7: 准备开始检测
6-4:
3: 检测的模式
2: 设置为0, 1的时候使用AUX引脚
1-0: 节省电源, 设置为00的时候会在获取数据的时候再去产生电场
设置为0x90, 获取X通道数字, 0xD0获取Y的数字
使用软件SPI
首先发送一个命令, 之后会获得对应的数据, 在实际接受的时候使用16位进行接收
首选的是差分工作模式, 这时候找到对应的A2-A0的表
选择00, 在两次测量之间会进行自动断电
实际使用的是001和101
c#define XPT2046_CHANNEL_X 0x90 //通道Y+的选择控制字 #define XPT2046_CHANNEL_Y 0xd0 //通道X+的选择控制字
在读取X轴坐标的时候打开Y驱动, 把X轴的驱动关闭0x90=>10010000
读取Y轴坐标的时候打开X轴的驱动, 0xd0 =>11010000
c
//发送命令
void XPT2046_SendCMD(uint8_t cmd)
{
uint8_t i;
/*设置引脚的初始状态*/
XPT2046_CS_ENABLE();//片选引脚设置为低电平
XPT2046_CLK_LOW();//时钟为低电平
XPT2046_MOSI_0();
/*片选选中*/
XPT2046_DelayUS(10);
XPT2046_CS_DISABLE();
/*产生8个时钟,发送数据*/
for(i=0;i<8;i++)
{
if( (cmd & (0x80>>i)) == 0 )
{
XPT2046_MOSI_0();
}
else
{
XPT2046_MOSI_1();
}
XPT2046_CLK_HIGH();
XPT2046_DelayUS(5);
XPT2046_CLK_LOW();
XPT2046_DelayUS(5);
}
// /*片选取消*/
// XPT2046_CS_ENABLE();
}
在上升沿的时候采样, 高数据位先行
c
//读取数据
uint16_t XPT2046_ReceiveData(void)
{
uint8_t i;
uint16_t receive_temp=0;
// /*设置引脚的初始状态*/
// XPT2046_CS_ENABLE();
// XPT2046_CLK_LOW();
// XPT2046_MOSI_0();
//
// /*片选选中*/
// XPT2046_DelayUS(10);
// XPT2046_CS_DISABLE();
XPT2046_CLK_HIGH();
XPT2046_DelayUS(5);
XPT2046_CLK_LOW();
XPT2046_DelayUS(5);
/*产生12个时钟,读取数据*/
for(i=0;i < 12;i++)
{
receive_temp = receive_temp << 1;
XPT2046_CLK_HIGH();
XPT2046_DelayUS(5);
if( XPT2046_MISO() == Bit_SET)
{
receive_temp |= 0x01;
}
else
{
receive_temp |= 0x00;
}
XPT2046_CLK_LOW();
XPT2046_DelayUS(5);
}
/*片选取消*/
XPT2046_CS_ENABLE();
return receive_temp;
}
高电平的时候数据是稳定的
在发送命令到接收时序直接片选不能中断, 且两个中间有一个时钟间隔, 可以使用一直片选
触摸校准
出现误差的原因是由于两块屏幕并不是完全贴合的, 所以会导致出现误差, 校准就是将逻辑平面映射到物理平面
主要就是要算出来比例缩放系数
y=kx+b
主要就是通过获取5个点的ADC的值, 之后使用这几个值进行计算