久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網(wǎng) >> MCU設計實例 >> 瀏覽文章

觸控屏的控制電路制作小記(附STM32的驅動)

作者:佚名   來源:本站原創(chuàng)   點擊數(shù):  更新時間:2010年11月20日   【字體:

  觸控屏已經(jīng)不是什么新鮮的東西,現(xiàn)在的電子產(chǎn)品基本上都帶有一個大大的彩色液晶,加上一個輕觸式的觸控屏。使用起來非常方便,可以完全取代以往那種固定式的按鍵。

  下面就介紹一種觸控屏的驅動電路,我也是一個小時前才把這個小板子做出來,測試成功后馬上發(fā)表這篇日志,新鮮熱辣的哦!

  首先,介紹以下觸控屏幕的構造,它是由一塊觸控屏幕和一塊液晶顯示屏幕粘合在一起的。液晶顯示屏幕按色彩、材料、成像原理等多種方式分類,種類繁多,這里對液晶屏幕不做詳細介紹,本文圖片中所使用的是16Bit半透明反射式TFT液晶點陣顯示屏。而觸摸屏幕主要分為兩大類,分別是電容式和電阻式。

電容式觸控屏利用人體的電流感應進行工作,優(yōu)點是使用壽命長,觸摸時不需用力,面板堅硬耐磨;缺點是觸摸精度低,必須使用特定的介質(zhì)觸控(如人體皮膚),受溫度濕度影響很大,外界有較強磁場電場時,觸控屏會失靈,簡單來說就是抗干擾性較差。

電阻式觸控屏是利用按壓時縱軸和橫軸的電阻值來定位的,優(yōu)點是抗干擾性好,觸摸精度高,可以用任何物體來觸摸,缺點是表面是塑料薄膜,易磨損,觸摸是需要稍加一點力度按壓。本文中使用的就是電阻式觸控屏。

  接下來介紹一些幾個觸控屏控制IC:ADS7846、ADS7843和TSC2046,它們是最常見的四線觸摸屏控制芯片,均為BURR-BROWN(已經(jīng)被TI收購,找封裝庫的時候去TI那里找)公司的產(chǎn)品,三者引腳相互兼容,但片內(nèi)的功能是有區(qū)別的,例如7846內(nèi)集成溫度傳感、可檢測觸摸壓力等功能,具體請參考DataSheet。TSC2046是新出的控制芯片,由于其國產(chǎn)片價錢便宜(零售約1元/片),廣泛應用于國產(chǎn)的具有觸摸屏幕的MP3、手機等電子產(chǎn)品。

  我這次制作采用的是ADS7846。

ADS7846引腳圖:


引腳功能介紹:

DCLK:時鐘輸入端口

CS:片選信號

DIN:串行數(shù)據(jù)輸入端,CS為低時數(shù)據(jù)在DCLK上升沿鎖存

BUSY:忙時信號輸出,CS為高時其為高阻態(tài)

DOUT:串行數(shù)據(jù)輸出端,CS為高時其為高阻態(tài)

PENIRQ:筆中斷(當屏幕被觸壓時,產(chǎn)生中斷信號)

Vref:參考電壓(一般直接接VCC)

Vbat:電源檢測輸入端(一般不使用)

AUX:備選輸入端(一般不使用)

X+、Y+、X-、Y- :四線觸控屏位置輸入端

 

  程序思路是參考一位網(wǎng)友的,我把它移植過來了。  

  工作原理:每次按下觸摸屏,ADS7846的PEN腳會拉低,觸發(fā)STM32中斷,然后在中斷服務程序里面處理要執(zhí)行功能。畫圖的原理是通過在中斷里對X、Y坐標連續(xù)采樣十次,若不夠十次,不做任何操作。得到十次數(shù)據(jù)后,進行排序,最后取中間三次的數(shù)據(jù)計算均值,便得到需要的X、Y坐標。得到觸屏的點以后,接著就是在屏幕上對應的這個點上畫點。

 

下面是電路的原理圖:



 

用感光法做的板子(未裁剪):

 

裁剪出中間那部分后和一元硬幣小一點,右側為硫酸紙打印出來的負片。
寫了一個可選畫筆和背景顏色的畫板:

 

最后貼上STM32的觸摸屏驅動程序(已添加畫板功能),用C語言寫的,很容易移植,有興趣的同學可以將它移到51或其他單片機上面跑一下。完整的代碼從這里下載http://www.zg4o1577.cn/ziliao/file/chumo1.rar ,下面貼出一部分來:

程序:
 

//程序來源于 www.zg4o1577.cn
#include"hx8347.h"   //自己編寫的液晶屏頭文件,此頭文件只定義了一些基本變量,不涉及驅動相關函數(shù)

//定義引腳高低電平
#define  ADS_DCLK_H() GPIO_SetBits(GPIOB,GPIO_Pin_6)//ADS7846時鐘信號
#define  ADS_DCLK_L() GPIO_ResetBits(GPIOB,GPIO_Pin_6)

#define  ADS_CS_H() GPIO_SetBits(GPIOB,GPIO_Pin_7)//ADS7846片選信號
#define  ADS_CS_L() GPIO_ResetBits(GPIOB,GPIO_Pin_7)

#define  ADS_DIN_H() GPIO_SetBits(GPIOB,GPIO_Pin_8)
#define  ADS_DIN_L() GPIO_ResetBits(GPIOB,GPIO_Pin_8)

#define  ADS_DOUT  GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)
#define  ADS_PEN GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)////ADS7846響應信號   

//初始化I/O口
void ADS_GPIO_Config()
{
 GPIO_InitTypeDef GPIO_InitStructure;
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
 GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOB, &GPIO_InitStructure);

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
 GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9|GPIO_Pin_10;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void ADS_Spi_Start()//初始信號
{
 ADS_CS_H();
 ADS_DCLK_H();
    ADS_DIN_H();
}

void ADS_Write_Byte(u8 num)
{
 u8 count=0;
 ADS_DCLK_L();
 for(count=0;count<8;count++)
 {
  if(num&0x80)
   ADS_DIN_H();
  else 
   ADS_DIN_L();
  num<<=1;
  ADS_DCLK_L();
  ADS_DCLK_H();  //上升沿有效    
 }
}
u16 ADS_Readdata()
{
 u16  num;
 u8 count;
 for(count=0;count<12;count++)
 {
  num<<=1;
  ADS_DCLK_H();
  ADS_DCLK_L();
  if(ADS_DOUT)
   num++;
 }
 return num;
}

#define CMD_RDX  0X90 //0B10010000即用差分方式讀X坐標
#define CMD_RDY  0XD0 //0B11010000即用差分方式讀Y坐標 

u16  X=0,Y=0;//當前觸控坐標

u8 Readonce()
{
 ADS_Spi_Start();
 ADS_CS_L();
 ADS_Write_Byte(CMD_RDX);
 ADS_DCLK_H();
 delay_us(3);
 ADS_DCLK_L();
 delay_us(3);
 Y=ADS_Readdata();

    ADS_Write_Byte(CMD_RDY);
 ADS_DCLK_H();
 delay_us(1);
 ADS_DCLK_L();
 delay_us(1);
 X=ADS_Readdata();
 ADS_CS_H();
 if(X>100&&Y>100&&X<3800&&Y<3800)return 1;//讀取成功(范圍限制)
 else return 0;//讀取失敗
}

void drawbigpoint(u8 x,u16 y,u16 col)
{
 if(x>220&&y<9)
 {
  LCD_DrawBlock(0,0,239,319,0x0000);//清屏 
  LCD_write_english_string(210,0,"CLR",0xFFE0,0x001F);//清屏按鍵區(qū)域
 }
 else 
 {
  LCD_Set_Point(x,y,col);//中心點 
  LCD_Set_Point((x+1),y,col);
  LCD_Set_Point(x,(y+1),col);
  LCD_Set_Point((x+1),(y+1),col); 
 }     
} 

//讀取ADS7846(畫線)
void Read_Ads7846(void)
{
 u8 t,t1,count=0;
 u16 databuffer[2][10]={{5,7,9,3,2,6,4,0,3,1},{5,7,9,3,2,6,4,0,3,1}};//數(shù)據(jù)組
 u16 temp=0;  
     //循環(huán)讀數(shù)10次
 do
 {
  t=ADS_PEN; //觸摸屏被按下,PEN為L
  if(Readonce()) //讀數(shù)成功
  {   
   databuffer[0][count]=X;
   databuffer[1][count]=Y;
   count++;  
  }
 }
 while(!t&&count<10);  
 if(count==10)//讀10次數(shù)據(jù)有效
 {  
  //X升序排列
  do
  { 
   t1=0;    
   for(t=0;t<count-1;t++)
   {
    if(databuffer[0][t]>databuffer[0][t+1])//升序排列
    {
     temp=databuffer[0][t+1];
     databuffer[0][t+1]=databuffer[0][t];
     databuffer[0][t]=temp;
     t1=1; 
    }
   }
  }
  while(t1);    
  do//Y升序排列
  { 
   t1=0;   
   for(t=0;t<count-1;t++)
   {
    if(databuffer[1][t]>databuffer[1][t+1])//升序排列
    {
     temp=databuffer[1][t+1];
     databuffer[1][t+1]=databuffer[1][t];
     databuffer[1][t]=temp;
     t1=1;  
    }  
   }
  }
  while(t1);              
  X=(databuffer[0][3]+databuffer[0][4]+databuffer[0][5])/3;
  Y=(databuffer[1][3]+databuffer[1][4]+databuffer[1][5])/3;
   
   //根據(jù)觸摸屏的具體參數(shù)設置
  if(X<=4000&&Y<=4000)
  {
   if(X>=240)
    X-=240;
   else X=0;
   if(Y>=320)
    Y-=320;
   else Y=0;  
   drawbigpoint(X/15,Y/11+10,BLUE);  
  }   
 }
} 
void EXTI1_IRQHandler(void)
{  
 u8 t=0;                         
 //消除抖動 
    do
 {
  delay_us(10);
  t=ADS_PEN;
  Read_Ads7846();             
 }
 while(t==0);        
 EXTI_ClearITPendingBit(EXTI_Line1);
}       

//中斷優(yōu)先級管理/開啟    
void NVIC_Configuration(void)
{
 NVIC_InitTypeDef NVIC_InitStructure;
 //存儲器映射   
#ifdef  VECT_TAB_RAM              
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); 
#else           
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
#endif        
 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//優(yōu)先級分到第0組 總共5組   
   NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQChannel; //使用外部中斷1
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//階級1
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);          
}

//外部中斷初始化
void EXTI_Configuration(void)//配置外部中斷
{
  EXTI_InitTypeDef  EXTI_InitStructure;  //聲明中斷庫函數(shù)結構體
  EXTI_InitStructure.EXTI_Line = EXTI_Line1; //外部中斷通道1
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  //中斷模式
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿觸發(fā)
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;   //使能
  EXTI_Init(&EXTI_InitStructure);
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource10);  //設置外部中斷通道1到PB10
}

//END
關閉窗口

相關文章

主站蜘蛛池模板: 国产精品成人一区二区 | 精品久久99 | 午夜精品视频一区 | 欧美在线一二三 | 欧美一二三四成人免费视频 | 国产一区免费 | 国产97在线视频 | 午夜精品一区二区三区在线播放 | 久久免费高清视频 | 91视频免费黄 | 成人一区二区三区在线观看 | 国产精品视频在线观看 | 国产片一区二区三区 | 亚洲av毛片| 亚洲一区二区三区久久 | 日韩免费高清视频 | 精品国产一区二区三区性色av | 成人精品毛片国产亚洲av十九禁 | 亚洲国产精品日韩av不卡在线 | 亚洲视频在线一区 | 一区二区三区免费 | 久久精品女人天堂av | 国内精品久久久久 | 国产免费福利在线 | 国产女人第一次做爰毛片 | www.狠狠操 | 日韩欧美高清 | 国产精品国产成人国产三级 | av黄色网 | 中文字幕一区二区三区四区五区 | 成人黄色电影在线观看 | 九九伦理电影 | 女人一区| 日本不卡免费新一二三区 | 午夜国产 | 亚洲国产成人精品在线 | 欧美性视频在线播放 | 久久激情网 | 久久亚洲精品久久国产一区二区 | 亚洲午夜小视频 | 国产欧美精品在线观看 |