历史上的今天
返回首页

历史上的今天

今天是:2024年12月19日(星期四)

正在发生

2020年12月19日 | 神舟IV学习笔记-触摸控制XPT2046(十五)

2020-12-19 来源:eefocus

IAR5.4编译环境 ,看了很多XPT2046的驱动,都是软件模拟SPI接口来驱动,偶用硬件SPI接口驱动成功。


触摸控制器芯片介绍:

XPT2046内部有 2.5V的参考电压源,可以作为辅助输入、电池电压测量和片内温度测量的参考电压。当不使用时,参考电压源可以处于省电模式。内部参考电压源在电源电压低至2.7V时仍可正常工作。当不使用时,参考电压还可以处于省电模式。内部参考电压在电源电压低于2.7V时仍可正常工作,并且监测着在 0V~6V范围内的电源电压。XPT2046在 125KHz转换速率和 2.7V电压下的功耗仅为750 µW。XPT2046以其低功耗和高速率等特性,被广泛应用在采用电池供电的小型手持设备上,比如 PDA、手机等。


XPT2046 是一种典型的逐次逼近型模数转换器(SAR ADC),包含了采样/保持、模数转换、串口数据输出等功能。同时芯片集成有一个 2.5V的内部参考电压源、温度检测电路,工作时使用外部时钟。XPT2046 可以单电源供电,电源电压范围为 2.7V~5.5V。参考电压值直接决定ADC的输入范围,参考电压可以使内部参考电压,也可以从外部直接输入1V~VCC范围内的参考电压(要求外部参考电压源输出阻抗低)。X、Y、Z、VBAT、Temp和AUX模拟信号经过片内的控制寄存器选择后进入ADC,ADC可以配置为单端或差分模式。选择VBAT、Temp和AUX时可以配置为单端模式;作为触摸屏应用时,可以配置为差分模式,这可有效消除由于驱动开关的寄生电阻及外部的干扰带来的测量误差,提高转换准确度。

 

XPT2046_SPI.H

#ifndef __XPT2046_SPI_H
#define __XPT2046_SPI_H
#include "stm32f10x_conf.h"
//XPT2046 与STM32107VCT6的连线方式
//MISO          PC11/SPI3_MISO REMAP
//MOSI          PC12/SPI3_MISO
//SCK          PC10/SPI3_SCK
//TP_CS         PC9
//INT          PC5

// A/D 通道选择命令字和工作寄存器
#define CMD_RDX  0x90
#define CMD_RDY  0xD0
#define READ_TIMES 15 //读取次数
#define LOST_VAL    5    //丢弃值
#define ERR_RANGE 50 //误差范围
#define TPCS_L  GPIO_ResetBits(GPIOC, GPIO_Pin_9)
#define TPCS_H  GPIO_SetBits(GPIOC, GPIO_Pin_9)
//extern u16 X_Addata,Y_Addata;
//extern void delay_ms(u16 Nms);好像不延时也可以用哦
void XPT2046_Configuration(void);//配置GPIO/SPI3/EXTI中断
u16 ADS_Read_AD(u8 CMD);
//void XPT2046_Rd_Addata(void);//读位置,村到全局变量X_Addata,Y_Addata
//读取一个坐标值
//连续读取READ_TIMES次数据,对这些数据升序排列,
//然后去掉最低和最高LOST_VAL个数,取平均值
u16 ADS_Read_XY(u8 xy);//
u8 Read_ADS(u16 *x,u16 *y);////最小值不能少于100.
u8 Read_ADS2(u16 *x,u16 *y);//2次读取ADS7846,连续读取2次有效的AD值,且这两次的偏差不能超过ERR_RANGE


#endif

XPT2046_SPI.C

#include "xpt2046_spi.h"
u16 X_Addata=0,Y_Addata=0;
static void XPT2046_INT_EXIT_Init(void)//中断设置下降沿
{
    EXTI_InitTypeDef EXTI_InitStructure;

    /* Connect Button EXTI Line to Button GPIO Pin */
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource5); 

    /* Configure Button EXTI line */
    EXTI_InitStructure.EXTI_Line = EXTI_Line5;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; 
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

}


/*******************************************************************************
* Function Name  : InterruptConfig
* Description    : Configures the used IRQ Channels and sets their priority.NVIC_Configuration
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
static void XPT2046_InterruptConfig(void)//NVIC
{
  NVIC_InitTypeDef NVIC_InitStructure;
 
  /* Set the Vector Table base address at 0x08000000 */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000);
 
  /* Configure the Priority Group to 2 bits */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

  /* Enable the EXTI5 Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}
void XPT2046_Configuration(void)
{
  SPI_InitTypeDef  SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  /* Enable SPI3and GPIO clocks */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
 
  GPIO_PinRemapConfig(GPIO_Remap_SPI3,ENABLE);//SPI3 REMAP
 
 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  TPCS_H;
  //GPIO_SetBits(GPIOC, GPIO_Pin_9); /* Disable TP CS PC9  */
  // Set as Output AF push-pull - SCK and MOSI PC10 PC12//SPI3_MISO PC11   
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
 
  //中断端口GPIO设置 PC5
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//设置输入
  //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  //SPI3 设置
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;//由于说明书最高速率2M //72/256=
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI3, &SPI_InitStructure);
  /* Enable SPI3  */
  SPI_Cmd(SPI3, ENABLE);
  //中断设置
  XPT2046_INT_EXIT_Init();
  XPT2046_InterruptConfig();
  //GPIO_SetBits(GPIOC, GPIO_Pin_12);//mosi=1
  //clk=0

u8 XPT2046_SendByte(u8 byte)
{
  /* Loop while DR register in not emplty */
  while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET);

  /* Send Half Word through the SPI3 peripheral */
  SPI_I2S_SendData(SPI3, byte);

  /* Wait to receive a Half Word */
  while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET);

  /* Return the Half Word read from the SPI bus */
  return SPI_I2S_ReceiveData(SPI3);
}
u8 XPT2046_ReadByte(void)
{
  return (XPT2046_SendByte(0x00));
}
/*
void XPT2046_Rd_Addata(void)
{
    u16 temp;
    TPCS_L;
    //GPIO_ResetBits(GPIOC, GPIO_Pin_9);//CS=0
    //delay_ms(1);
    XPT2046_SendByte( CHX ) ;
    //delay_ms(1);
    temp=0;//相当于简短的延时啦
    temp= XPT2046_ReadByte() ;
    Y_Addata =temp<<8;
    temp= XPT2046_ReadByte() ;
    Y_Addata |=temp;
    Y_Addata >>=3;
    Y_Addata &=0XFFF;
    //GPIO_SetBits(GPIOC, GPIO_Pin_9);
   
    //GPIO_ResetBits(GPIOC, GPIO_Pin_9);
    //delay_ms(1);
    XPT2046_SendByte( CHY) ;
    temp=0;
    //delay_ms(1);
    temp= XPT2046_ReadByte();
    X_Addata=temp<<8;
    temp= XPT2046_ReadByte();
    X_Addata |=temp;
    X_Addata >>=3;
    X_Addata &=0XFFF;
    TPCS_H;
    //GPIO_SetBits(GPIOC, GPIO_Pin_9);
}*/
u16 ADS_Read_AD(u8 CMD)
{
  u16 temp,Addata;
  TPCS_L;//使能
  XPT2046_SendByte(CMD) ;
  temp=0;//相当于简短的延时啦
  temp= XPT2046_ReadByte() ;
  Addata =temp<<8;
  temp= XPT2046_ReadByte() ;
  Addata |=temp;
  Addata >>=3;//SPI读数由于第8位为0
  Addata &=0XFFF;
  return Addata; 
}
//读取一个坐标值
//连续读取READ_TIMES次数据,对这些数据升序排列,
//然后去掉最低和最高LOST_VAL个数,取平均值

u16 ADS_Read_XY(u8 xy)
{
 u16 i, j;
 u16 buf[READ_TIMES];
 u16 sum=0;
 u16 temp;
 for(i=0;i {    
  buf[i]=ADS_Read_AD(xy);    
 }       
 for(i=0;i {
  for(j=i+1;j  {
   if(buf[i]>buf[j])//升序排列
   {
    temp=buf[i];
    buf[i]=buf[j];
    buf[j]=temp;
   }
  }
 }  
 sum=0;
 for(i=LOST_VAL;i temp=sum/(READ_TIMES-2*LOST_VAL);
 return temp;  
}
//带滤波的坐标读取
//最小值不能少于100.
u8 Read_ADS(u16 *x,u16 *y)
{
 u16 xtemp,ytemp;         
 xtemp=ADS_Read_XY(CMD_RDX);
 ytemp=ADS_Read_XY(CMD_RDY);                 
 if(xtemp<100||ytemp<100)return 0;//读数失败
 *x=xtemp;
 *y=ytemp;
 return 1;//读数成功
}
//2次读取ADS7846,连续读取2次有效的AD值,且这两次的偏差不能超过
//50,满足条件,则认为读数正确,否则读数错误.   
//该函数能大大提高准确度

u8 Read_ADS2(u16 *x,u16 *y)
{
    u16 x1,y1;
    u16 x2,y2;
    u8 flag;   
    flag=Read_ADS(&x1,&y1);  
    if(flag==0)return(0);
    flag=Read_ADS(&x2,&y2);   
    if(flag==0)return(0);  
    if(((x2<=x1&&x1    &&((y2<=y1&&y1    {
        *x=(x1+x2)/2;
        *y=(y1+y2)/2;
        return 1;
    }else return 0;  
}


推荐阅读

史海拾趣

ELNA(依娜)公司的发展小趣事

进入电子领域后,ELNA迅速在电子元件领域取得了突破。公司凭借其在材料科学和制造工艺方面的专长,成功开发出了一系列高性能的电子元件产品。这些产品广泛应用于通信、计算机、消费电子等领域,为ELNA赢得了广泛的客户群。

为了保持技术领先,ELNA不断投入研发资源,加强技术创新。公司积极引进国际先进的生产设备和检测手段,提升产品品质和可靠性。同时,ELNA还加强了与国内外科研机构和高校的合作,共同推动电子元件技术的发展。

Astro Tool Corp公司的发展小趣事

随着技术的不断成熟和市场的逐步认可,Astro Tool Corp公司开始积极拓展海外市场。通过与国际知名电子制造商建立合作伙伴关系,公司成功将产品打入国际市场。同时,公司还积极参与国际行业展会和交流活动,不断提升品牌知名度和影响力。这些努力不仅为公司带来了更多的订单和合作伙伴,也进一步巩固了其在全球电子制造工具市场的地位。

CLARE公司的发展小趣事

为了进一步拓展市场,CLARE公司积极开拓国内市场,并与多家知名企业建立了战略合作关系。同时,公司还积极进军国际市场,通过参加国际展会、设立海外分支机构等方式,加强与国际客户的交流与合作。这些举措不仅为CLARE公司带来了更多的商业机会,也进一步提升了其在全球电子行业中的地位和影响力。

FTCAP Fischer & Tausche Capacitor Group公司的发展小趣事

CLARE公司的创业之路始于对电子行业深厚的技术积累和敏锐的市场洞察力。公司的创始人凭借其深厚的专业知识和经验,准确把握了行业的发展趋势,成功开发了一系列具有竞争力的电子产品。这些产品在市场上获得了良好的反响,为CLARE公司奠定了坚实的技术和市场基础。

FARNELL公司的发展小趣事

FARNELL公司成立于1937年,由创始人在英国利兹创建。起初,公司专注于电子元器件的分销,凭借其优质的产品和可靠的供货能力,逐渐在电子行业中崭露头角。在那个时代,电子产品正处于快速发展阶段,FARNELL公司凭借其前瞻性的市场洞察力和灵活的供应策略,赢得了众多客户的信赖。

台湾晶豪(ESMT)公司的发展小趣事

晶豪科技一直积极寻求与国内外企业的合作机会。通过与合作伙伴的紧密合作,公司不断拓展业务领域,进入了模拟及混合讯号IC领域。目前,公司提供的产品包括音讯转换器(ADC/DAC)及D类音频放大器等IC。这些新产品的推出不仅丰富了公司的产品线,还为客户提供了更多样化的选择。同时,通过与合作伙伴的资源共享和优势互补,晶豪科技在技术研发和市场拓展方面取得了更多突破。

问答坊 | AI 解惑

工程勾通,友好交流、扩大共识,相互借鉴

有归属、没宗派,有尊重、没辈分,有针对、没争竞,有奉献、没名利 相互尊重、友好交流、扩大共识,倡导不同文化间增进了解、相互借鉴 电子工程师,结构工程师,软件工程师,硬件工程师,FPGA研发。另有数码产品,影音视听产品,手机,微型硬盘播放机,R ...…

查看全部问答>

阿牛哥系列故事大嘴歪评世界杯

阿牛哥冒着七月的艳阳酷暑,晚上听完国际广播电台的新闻,西瓜荔枝,要看世界杯球赛了。晚上的这场要看,凌晨的那场要听。电视电脑收音机都需要,就是不能影响白天的工作。先说说世界杯比赛,不能在家里看,太影响家人.去哥们马六家看;啤酒不喝 ...…

查看全部问答>

PC104设备在纯DOS下跑程序的问题,虚拟软驱引导的纯DOS和实际安装的DOS有区别不?

如题。 现在程序跑在虚拟软驱引导的纯DOS里面,2000里面用bc31写的程序在2000下跑很流畅,但是到DOS下却非常卡。 想在DOS里面再编译,链接模式选small能通过,但是程序一跑就死,选large能通过,一跑连画面都没有,选其他linker都不成功。何解? ...…

查看全部问答>

wince 是否支持"微软雅黑"字体?

wince 是否支持\"微软雅黑\"字体? 看到linux下显示的字体比较漂亮,font文件下看到msyh.ttf,也就是雅黑字体了,EVC下显示的字效果比较一般,要是wince支持msyh.ttf的话,应该怎样添加呢? …

查看全部问答>

紧急求救!!用c开发手机或PDA需要看什么方面的书籍资料!!谢谢各位拉

本人用vc写过应用程序,用c写过mp3的程式,但是c++不太好,在vc里面基本用的都是c,现在想转做手机或pda方面,请教需要看哪些书啊?我看些资料,一般都是在用WinCE或在Linux下开发,哪个发展更好些?不知道这方面薪水待遇怎么样?敢请各位不啬赐教 ...…

查看全部问答>

晶振问题

请各位帮忙分析一下: 晶振工作不正常,第一次不起振,然后用烙铁点了一下,工作正常了一会,然后又不振了,再用烙铁点一下,又能正常工作,挂上仿真器,只能正常工作一会,如此反复。。。 请大家帮忙分析下。先谢了…

查看全部问答>

MSP430FG461X系列的20位地址指针在C语言中如何实现?

我把一个20位的地址0x10000,赋值给一个指针变量时,总是提示超出了0~0xFFFF的范围。 在汇编中这是可以做到的,因为MSP430X提供了MOVA等带A的指令,且工作寄存器都是20位的,可以用于20位的地址传输。就是不知道C语言中怎么实现。 不知是不是有 ...…

查看全部问答>

请教定时器中断的问题(一直都查不到资料,麻烦高手指点)

问题1:一般在主函数中装定时器初值,有必要吗?我好像试了,不装也能正常运行。 问题2:如果在定时器1中关闭了定时器0,用TR0=1再次打开定时器0时,需要重新装定时器0的初值吗?还是TR0=1直接就进入定时器0的中断函数从头开始执行。我试过两次不 ...…

查看全部问答>

跪求MSP430的开发实例

小弟初来乍到,是MSP430的初学者,跪求适合初学者做的案例来作参考,请各位大神多多照顾 …

查看全部问答>

ADS8332疑问之二:这是哪儿带来的干扰

使用C2000的SPI驱动ADS8332,过去曾成功过,是不同的PCB。然而再次搞它时,却问题多多。 现象:采样转换的通道,采样(转换)时,输入端悬空或稍大的旁路电阻(>10K,再小没试),就有有1V左右的电压。而未采样的通道,采样通道未采样时,没有这个 ...…

查看全部问答>