微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 单片机直接操控读取触摸屏 秉承“单片”之本色

单片机直接操控读取触摸屏 秉承“单片”之本色

时间:10-02 整理:3721RD 点击:
   常规的电阻触摸屏应用时都惯用成熟的专用驱动芯片来做接口,而在大多数简单应用中却很嫌麻烦,俺以为当省就得省略。
STC单片机自有强上拉输出又有高速的ADC输入,原理上直接驱动和读取电阻触摸屏是足以胜任的。比其专用的芯片自然会多出些许问题,当真逐一个解决了即会成就一“牛X”的“不用驱动芯片的单片机直接操控读取触摸屏”之招式。从而节省驱动芯片、减免外围电路,践行咱“单片”之本色。
招式描述:
1、本实验用到4个I/O口直连4线触摸屏端口之超简易搞法。
2、其中单片机P36、P37(居然与彩屏数据口分时共享)兼用(分时)拉高电阻触摸屏的(x、y)对应端。
3、单片机P16、P17则专事交错的拉低(x、y)相应端与读取被触屏点的分压值。
4、由于P16、P17既要分时拉低触摸屏电极又要执行ADC读取,这在STC的ADC应用规范里是不被提倡的,确实在试验中也几曾问题连联、叫俺唠心不已。
5、因此ADC不能引用常规的整体初始化了,只能各自读取ADC时单独施行(参见俺实验通过的例程片段)。
6、现有 触屏x、触屏y以及彩屏驱动的3个(分时)状态,需要P3、P1端口状态在3个状态间进行各自的适用性设置(参见例程注释的革命原理)。
7、实验的图形按键界面牵涉本俺 “通透背景字符”之另一添彩“招法”,且待另文分解。
俺觉得5、6、条就是本实验之“命门”所在,若得不耻效法与参照,则能够让类似科学实验愉心惬意、好玩不尽,岂不善哉?


瞅瞅这里的视屏显掰:



完成如下很到位的末梢神经训练。约为老哥哥、老妹妹延寿10年许。




实验已示明:stc单片机胜任直驱触摸屏,精度比预期的高。成本低、容易搞、好用还好玩。
显示的图片和字符库都放在SD卡里,图片每幅150K字节、空心字符与箭头标记每个510字节。



细研如下图解。不仅仅搞清俺的招式,或能够进一步深谙触摸屏“德性”以利创新。




参考代码片段1:
#include "main.h"
#include "LCD26.H"
#include "SSDD.h"

u8 p = 0, q = 0,r,s,w=5;
u16 aa;
bit ConfigFlag=0,RevFlag=0;
int main()
{
      P1M0 = 0xff;    //推挽
      P3M0 = 0xff;      
    CSCS =0;
    Init_SPI();
    DelayMs(50);
    CSB=1;    DelayMs(50);
    RES=0;    DelayMs(50);
    RES=1;    DelayMs(50);
Initial_ST7783R();
DelayMs(50);
ClearScreen(0x0000);
DelayMs(50);
   
    SC_ZM1624(0, 35, 16,ZM_1624_1, 0xffff,0x000f) ;
     while(sd_reset()!=0)  ;                                  //SD1.0卡   初始化
    while(sd_init()!=0 )  SC_ZM1624(50, 50, 5,ZM_1624_1, 0xe0ff,0x000f) ;
   //sd_init4(); while (Inti_Flag)                         //SD2.0卡   初始化
    SC_ZM1624(50, 200, 5,ZM_1624_1+480, Red,0x000f) ;

     SD_TX_ALL(668);
    while(1)
    {
        p = touch_xy(6);           
    if(p>40&p<60)
        {
        S_ZM1624(192, 0,ZM_1624_1+(p/100%10)*48, 0xffff,0x000f) ;//显示y坐标
        S_ZM1624(192,16,ZM_1624_1+(p/10%10)*48, 0xffff,0x000f) ;
        S_ZM1624(192,32,ZM_1624_1+(p%10)*48, 0xffff,0x000f) ;   
                    p = touch_xy(7);
                S_ZM1624(216, 0,ZM_1624_1+(p/100%10)*48, 0xffff,0x000f) ;//显示x坐标
        S_ZM1624(216,16,ZM_1624_1+(p/10%10)*48, 0xffff,0x000f) ;
        S_ZM1624(216,32,ZM_1624_1+(p%10)*48, 0xffff,0x000f) ;        
                if(p>40&p<70)   {                                      //响应左键上翻图片
            if(w<1) w=23; w--;
              SD_TX_ALL(668+(w*300));    DelayMs(500);
                          LCD_XP_ZF5180(0,0,0x051F,652+w%10);              //显示图片编号
                        LCD_XP_ZF5180(51,0,0x051F,652+w/10%10);
                                  }
                if(p>120&p<160) {                                      //响应右键下翻图片
            w++; if(w>22)w=0;   
              SD_TX_ALL((w*300)+668);     DelayMs(500);
                      LCD_XP_ZF5180(0,0,0x051F,652+w%10);              //显示图片编号
                        LCD_XP_ZF5180(51,0,0x051F,652+w/10%10);   
                        }
        }
            
                p = touch_xy(7);                                    //再显示y坐标
            S_ZM1624(192, 0,ZM_1624_1+(p/100%10)*48, 0xffff,0x000f) ;
        S_ZM1624(192,16,ZM_1624_1+(p/10%10)*48, 0xffff,0x000f) ;
        S_ZM1624(192,32,ZM_1624_1+(p%10)*48, 0xffff,0x000f) ;   
         CSCS=1;DelayMs(1);CSCS=0;      
                     
                p = touch_xy(6);                                    //再显示x坐标
                S_ZM1624(216, 0,ZM_1624_1+(p/100%10)*48, 0xffff,0x000f) ;
        S_ZM1624(216,16,ZM_1624_1+(p/10%10)*48, 0xffff,0x000f) ;
        S_ZM1624(216,32,ZM_1624_1+(p%10)*48, 0xffff,0x000f) ;   
               DelayMs(1);              

                LCD_XP_ZF5180(95,160,Red,7568) ;                   //显示触摸屏方向键
        LCD_XP_ZF5180(95,255,Red,7568+1) ;                                            
          LCD_XP_ZF5180(160,206,Red,7568+2) ;
          LCD_XP_ZF5180(30,206,Red,7568+3) ;
               
                LCD_XP_ZF5180(96,162,0xffff,7568) ;               //错位双写触摸屏方向键
        LCD_XP_ZF5180(96,257,0xffff,7568+1) ;             //以免被同色背景淹没                              
          LCD_XP_ZF5180(161,208,0xffff,7568+2) ;
          LCD_XP_ZF5180(28,207,0xffff,7568+3) ;
  }
}

参考代码片段2:
//===========读取ADC=============================================================================
u8 GetADCResult(u8 ch)
{     
        u8 h,t=2;
        if(ch==6)ADC_CONTR = 0x8e; //0x80 ADC电源控制位,0x00 speed 540个时钟,0x08 ADC起始控制位,
            else     ADC_CONTR = 0x8f;  
      while(--t) ;                  //等待若干时钟
    while (!(ADC_CONTR & 0x10));    //等待ADC转换完成  ,0x10 ADC完成标志(ADC_FLAG)
    ADC_CONTR = 0;                  //ADC_FLAG 清零,Close ADC
    return ADC_RES;                 //返回ADC结果
}
   
//===========获取触摸屏数据(带初始化)    y为ox6通道 、x为ox7通道================================
u8 touch_xy(u8 ch)                                          
{
    u8 a,b,c;   
    if(ch==6) { P3M0 = 0x80; P3M1 = 0x40;  P37 = 1;  P17 = 0;  //P37推挽、P36高阻、P37拉高、P17拉低、
                P1ASF = 0x40;      }                           //设置P16口为AD口  
    if(ch==7) { P3M0 = 0x40; P3M1 = 0x80;  P36 = 1;  P16 = 0;  //P36推挽、P37高阻、P36拉高、P16拉低、
              P1ASF = 0x80;      }                           //设置P17口为AD口  
    DelayMs(0);
      ADC_RES = 0;                         //清除结果寄存器
    a = GetADCResult(ch); b = GetADCResult(ch);  c = GetADCResult(ch); //读取指定口数据,读3 次。
    if(b<a)a = b;  if(c<a)a = c;           //选取最小的
        DelayMs(1);
    P3M0 = 0xff; P3M1 = 0x00;              //恢复显示驱动设置
    P1M0 = 0xff; P1M1 = 0x00;
    return a ;
}

厉害了~一看就是高手一枚~

摩拜

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top