mini2440裸试验—计算器(LCD显示,触摸屏突破)

关于Pait_Bmp(x0,
y0, x,
y, BMPaddr);函数

像素图在屏幕左上角为(0,0),Pait_Bmp中的x0。y0分别像素点初始位置,x,y为BMP图片的X,Y的大小。BMPaddr为BMP图片转换的数组地址

基于T35 TFT LCD屏实现功能

1. 在屏幕上画一个计算器界面,包含0-9,+。-,*。/;

2. 实现触摸选择界面上的数字和运算符。

3. 并计算出结果显示在显示框内。

注意。仅仅实现整数功能,没涉及小数。仅仅实现一次运算,不保存上次运算结果。

实现界面:

实现过程:

开启LCD电源,初始化LCD>>>LCD填充界面图片>>>开启触摸屏中断>>>获取键值>>>区分数字和功能来调用数字图片显示。

 

数字图片

空白图: 除数为零提示图:

数字图像:                                 
                                                
                                     

数值过长提示图:

1、开启LCD电源,初始化LCD

当中:时序发生器(TIMEGEN)

TIMEGEN产生LCD驱动器的控制信号。如VFRAME、VLINE、VCLK和VM。这些控制信号与REGBANK中的LCDCON1/2/3/4/5寄存器配制有着紧密关系。

基于这些可编程的REGBANK中LCD控制寄存器的配制,TIMEGEN能够产生合适的可编程控制信号来支持多种不同类型的LCD驱动器.

TFT屏的工作时序:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbXV5YW5nX3Jlbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" >

VSYNC为帧同步信号。每发出一个脉冲表示新的一屏图像数据開始传输。

VSF=HSF÷[(VSPW+1)+(VBPD+1)+(VFPD+1)+(LINEVAL+1)]

HSYNC为行同步信号。每发出一个脉冲表示新的一行图像数据開始传输。

HSF=VCLK÷[(HSPW+1)+(HSPD+1)+(HFPD+1)+(HOZVAL+1)]

VCLK为像素同步信号,每发出一个脉冲表示新的一个点图像数据開始传输。

VCLK=HCLK÷[(CLKVAL+1)×2]

LCD显示是一帧一帧(一个画面)的,每一帧里显示又是从上到下一行一行的。每一行显示又是从左到右一个点一个点的。

而VSYNC,HSYNC,VCLK这些决定了他们的显示速度。

图中的VSPW,HSPW等决定对应脉冲的宽度。VBPD,HBPD决定了延时时间。

这些參数的设置都是由LCDCONn决定的。

初始化LCD:(设置TIMEGEN)

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbXV5YW5nX3Jlbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" >

/**************************************************************
 TFT LCD功能模块初始化//此函数没开启屏蔽功能
**************************************************************/
void LCD_Init(void)
{
#define	M5D(n)	((n)&0x1fffff)
#define LCD_ADDR ((U32)LCD_BUFFER)
     //con1[6:5]显示模式选择为 TFT LCD面板 模式  [4:1]选择为 TFT的16bpp 像素模式
	rLCDCON1 = (LCD_PIXCLOCK << 8) | (3 <<  5) | (12 << 1);
	//con2[23:14]设置高度320  VSPW[5:0]决定对应脉冲的宽度; VFPD[13:6]、VBPD[31:24]决定了延时时间;  选择option.h文件里T35定义參数
   	rLCDCON2 = (LCD_UPPER_MARGIN << 24) | ((LCD_HEIGHT - 1) << 14) | (LCD_LOWER_MARGIN << 6) | (LCD_VSYNC_LEN << 0);
   	//con3[18:8]设置高度240   HFPD、HBPD决定了延时时间;  选择option.h文件里T35定义參数
   	rLCDCON3 = (LCD_RIGHT_MARGIN << 19) | ((LCD_WIDTH  - 1) <<  8) | (LCD_LEFT_MARGIN << 0);
   	//con4  HSPW[8:0]决定对应脉冲的宽度; 选择option.h文件里T35定义參数
   	rLCDCON4 = (13 <<  8) | (LCD_HSYNC_LEN << 0);

#if !defined(LCD_CON5)
#    define LCD_CON5 ((1<<11) | (1 << 9) | (1 << 8) | (1 << 3) | (1 << 0))
#endif
    rLCDCON5   =  LCD_CON5;

    rLCDSADDR1 = ((LCD_ADDR >> 22) << 21) | ((M5D(LCD_ADDR >> 1)) <<  0);
    rLCDSADDR2 = M5D((LCD_ADDR + LCD_WIDTH * LCD_HEIGHT * 2) >> 1);
    rLCDSADDR3 = LCD_WIDTH;        

    rLCDINTMSK |= 3;   //中断屏蔽
  	rTCONSEL   &= (~7);

   	rTPAL     = 0x0;
   	rTCONSEL &= ~((1<<4) | 1);

}

使能LCD

/**************************************************************
LCD视频和控制信号输出或者停止,1开启视频输出
**************************************************************/
void Lcd_EnvidOnOff(int onoff)
{
    if(onoff==1)
    rLCDCON1|=1; // ENVID=ON
    else
    rLCDCON1 =rLCDCON1 & 0x3fffe; // ENVID Off
}

开启LCD电源

/**************************************************************
TFT LCD 电源控制引脚使能
**************************************************************/
void Lcd_PowerEnable(int invpwren,int pwren)
{
    //GPG4 is setted as LCD_PWREN
    rGPGUP = rGPGUP|(1<<4); // Pull-up disable
    rGPGCON = rGPGCON|(3<<8); //GPG4=LCD_PWREN

    //Enable LCD POWER ENABLE Function
    rLCDCON5 = rLCDCON5&(~(1<<3))|(pwren<<3);   // PWREN
    rLCDCON5 = rLCDCON5&(~(1<<5))|(invpwren<<5);   // INVPWREN
}

2、开启触摸屏中断

/**************************************************************
 TFT LCD *触摸屏中断函数*
**************************************************************/

void __irq Adc_Tc_Handler(void)
{  

    rADCTSC|=(1<<3)|(1<<2); //XP上拉电阻无效, 自己主动连续測量X坐标和Y坐标.
    rADCCON|=(1<<0);//ADC转换開始  

    while(rADCCON&(1<<0));//检測ADC转换是否開始且ADCCON[0]自己主动清0
    while(!(rADCCON&(0x1<<15))); //检測ADCCON[15]是否为1,ADC转换是否结束,(必须)
    while(!(rINTPND&((U32)0x1<<31)));//检測ADC中断是否已请求  

    xdata=rADCDAT0&0x3ff;//读x坐标 >>xdata并非像素点,而是模拟信号 0-1000
    ydata=rADCDAT1&0x3ff;//读y坐标  

    Uart_Printf("\n       Xdata=%04d, Ydata=%04d\n", xdata, ydata);  

    rSUBSRCPND|=(0x1<<9);   //清除中断
    rSRCPND|=((U32)0x1<<31);
    rINTPND|=((U32)0x1<<31);  

    rADCTSC =0xd3;     //ADC等待中断模式
    rADCTSC|=(0x1<<8);  //ADCTSC[8]=1,设置抬起中断信号  

    while(!(rSUBSRCPND&(0x1<<9)));  //检測触屏抬起中断是否已请求   

    rADCTSC &=~(0x1<<8);//ADCTSC[8]=0光标按下中断信号  

    //  因为以下这段代码和上面这段代码是看到大神们都会加上去的。调试得到
    //  现象:上面的清除中断实现触屏中断,而以下这段则是加快中断后的响应
    //  (我的实验结果是:没以下的时候,触屏后的数值显示时间变长,蜂鸣器的
    //  响声也变长,有种慢一拍的感觉)

    rSUBSRCPND|=(0x1<<9);
    rSRCPND|=((U32)0x1<<31);
    rINTPND|=((U32)0x1<<31);
}   

void Touch_Init(void)
{
    rADCCON=((1<<14)|(9<<6));    //A/D分频时钟有效,其值为9
    rADCTSC=0xd3;  //光标按下中断信号,YM有效,YP无效,XM有效,XP无效,XP上拉电阻,普通ADC转换,等待中断模式
    rADCDLY=50000; //正常转换模式转换延时大约为(1/3.6864M)*50000=13.56ms  

    rINTSUBMSK &=~(0x1<<9);//TC中断使能
    rINTMSK &=~((U32)0x1<<31);//ADC总中断使能  

    pISR_ADC=(U32)Adc_Tc_Handler;//指向中断向量表  

}

3、获取键值

并定义变量botten1存储键值,flag1按键标记。flag2运算标记

/**************************************************************
             ------------获取键值--------------
**************************************************************/
void get_key(void){
    //数字块
    if( xdata >= 70 && xdata <= 285 && ydata >= 100 && ydata < 262 )       //0
    {   Beep(2000, 100);botten1 = 0;flag1=1;xdata = ydata = 0;  }
    else if( xdata >= 70 && xdata <= 285 && ydata >= 263 && ydata < 425 )    //1
    {   Beep(2000, 100);botten1 = 1;flag1=1;xdata = ydata = 0;  }
    else if( xdata >= 285 && xdata <= 500 && ydata >= 263 && ydata < 425 )    //2
    {   Beep(2000, 100);botten1 = 2;flag1=1;xdata = ydata = 0;  }
    else if( xdata >= 500 && xdata <= 715 && ydata >= 263 && ydata < 425 )     //3
    {   Beep(2000, 100);botten1 = 3;flag1=1;xdata = ydata = 0;  }
    else if( xdata >= 70 && xdata <= 285 && ydata >= 425 && ydata < 587 )     //4
    {   Beep(2000, 100);botten1 = 4;flag1=1;xdata = ydata = 0;  }
    else if( xdata >= 285 && xdata <= 500 && ydata >= 425 && ydata < 587 )     //5
    {   Beep(2000, 100);botten1 = 5;flag1=1;xdata = ydata = 0;  }
    else if( xdata >= 500 && xdata <= 715 && ydata >= 425 && ydata < 587 )     //6
    {   Beep(2000, 100);botten1 = 6;flag1=1;xdata = ydata = 0;  }
    else if( xdata >= 70 && xdata <= 285 && ydata >= 587 && ydata < 750 )     //7
    {   Beep(2000, 100);botten1 = 7;flag1=1;xdata = ydata = 0;  }
    else if( xdata >= 285 && xdata <= 500 && ydata >= 587 && ydata < 750 )     //8
    {   Beep(2000, 100);botten1 = 8;flag1=1;xdata = ydata = 0;  }
    else if( xdata >= 500 && xdata <= 715 && ydata >= 587 && ydata < 750 )     //9
    {   Beep(2000, 100);botten1 = 9;flag1=1;xdata = ydata = 0;  }
    else
    //功能运算块
    if( xdata >= 715 && xdata <= 930 && ydata >= 100 && ydata < 262 )          //除
    {   Beep(2000, 100);botten1 = '/';flag1=1;flag2=1;xdata = ydata = 0;  }
    else if( xdata >= 715 && xdata <= 930 && ydata >= 263 && ydata < 425 )     //乘以
    {   Beep(2000, 100);botten1 = '*';flag1=1;flag2=2;xdata = ydata = 0;  }
    else if( xdata >= 715 && xdata <= 930 && ydata >= 425 && ydata < 587 )     //减法
    {   Beep(2000, 100);botten1 = '-';flag1=1;flag2=3;xdata = ydata = 0;  }
    else if( xdata >= 715 && xdata <= 930 && ydata >= 587 && ydata < 750 )     //加法
    {   Beep(2000, 100);botten1 = '+';flag1=1;flag2=4;xdata = ydata = 0;  }
    else
    if( xdata >= 500 && xdata <= 715 && ydata >= 100 && ydata < 262 )          //等于
    {   Beep(2000, 100);botten1 = '=';flag1=1;xdata = ydata = 0;  }
    else
    if( xdata >= 285 && xdata <= 500 && ydata >= 100 && ydata < 262 )         // 清空
    {   Beep(2000, 100);botten1 = 'c';flag1=1;xdata = ydata = 0;  }
}

4、区分键值来调用数字图片显示

/**************************************************************
             ------------处理键值--------------
**************************************************************/
void resout(){

    if(flag2==4)               {sum1=sum1+sum2; show_picturu(sum1);  sum1=0;sum2=0;flag2=0;  }   //依据标志flag2 进行对应的  sum1=sum1 ? sum2  的运算,运算完sum1 sum2置零
         else if(flag2==3)     {sum1=sum1-sum2; show_picturu(sum1);  sum1=0;sum2=0;flag2=0;  }
              else if(flag2==2){sum1=sum1*sum2; show_picturu(sum1);  sum1=0;sum2=0;flag2=0;  }
                   else if(flag2==1){
                            if(sum2==0) {sum1=0;sum2=0;flag2=0;  Pait_Bmp(1, 34, 236, 30, error);Delay(500);show_picturu(0);}  //对除数为0处理。
                            else {sum1=sum1/sum2;show_picturu(sum1);  sum1=0;sum2=0;flag2=0; }}       //注意:除法运算结果会舍去小数部分

}
void cleaning(){
  sum1=0,sum2=0;flag2=0;show_picturu(0);
}
void show_num(void){
    while(flag1){
    flag1=0;   //标志置零
         switch(botten1){
         case 0:
         case 1:
         case 2:
         case 3:
         case 4:
         case 5:
         case 6:
         case 7:
         case 8:
         case 9:{sum2=sum2*10+botten1;
                    if(sum2>999999999){
                        sum2=0;Pait_Bmp(2, 34, 236, 30, numerror);
                        Delay(500);show_picturu(sum2);
                    }
                    else show_picturu(sum2);
                } break;       //按键值存于 sum2

         case '+':
         case '-':
         case '*':
         case '/': sum1=sum2,sum2=0; break;                                //sum2值转存于sum1,sum2置零

         case '=': resout(); break;

         //之前把以下的这段放在这里,观察变量发现sum1和和sum2到这里就置零了(按下=后永远等于0),无奈之下试试把推断放进一个函数 resout(); 里看看。结果成功了!

!。
        /* if(flag2==4)          {show_picturu(sum1+sum2);  sum2=0;flag2=0;}   //依据标志flag2 进行对应的  sum1=sum1 ? sum2  的运算
         else if(flag2==3)     {show_picturu(sum1-sum2);  sum2=0;flag2=0;  }
              else if(flag2==2){show_picturu(sum1*sum2);  sum2=0;flag2=0;  }
                   else if(flag2==1){
                            if(sum2==0) {sum1=0;sum2=0;flag2=0;  Pait_Bmp(1, 34, 236, 30, error);Delay(500);show_picturu(0);}  //对除数为0处理。
                            else {show_picturu(sum1/sum2);  sum2=0;flag2=0; }}       //注意:除法运算结果会舍去小数部分
        */

        case 'c': cleaning(); break;
         }

    }
}

5、调用图片

<span style="font-size:10px;">/**************************************************************
             ------------调用图片函数--------------
**************************************************************/
void show_picturu(int sum){
 int k=0,j=0;
    Pait_Bmp(1, 34, 238, 30, clean);
    if(sum>0){                          //数值大于0时
        for(;sum>0;){
            k=sum%10;                   //k用来取余数
            sum=sum/10;                 //num舍去最后一位
            ++j;                        //j用来标志k的余数在原数值中的实际位数
            numTOpic(k,j);
            }
        }
    else if(sum==0){                    //数值等于0时
             numTOpic(0,1);
        }
    else if(sum<0){                    //数值小于0时
             sum=-sum;
             for(;sum>0;){
                 k=sum%10;                   //k用来取余数
                 sum=sum/10;                 //num舍去最后一位
                 ++j;                        //j用来标志k的余数在原数值中的实际位数
                 numTOpic(k,j);
                }
            Pait_Bmp(238-13*(j+1), 34, 13, 30, num_);
        }

}
void numTOpic(int m ,int n){
switch(m){
    case 0:Pait_Bmp(238-13*n, 34, 13, 30, num0);break;
    case 1:Pait_Bmp(238-13*n, 34, 13, 30, num1);break;
    case 2:Pait_Bmp(238-13*n, 34, 13, 30, num2);break;
    case 3:Pait_Bmp(238-13*n, 34, 13, 30, num3);break;
    case 4:Pait_Bmp(238-13*n, 34, 13, 30, num4);break;
    case 5:Pait_Bmp(238-13*n, 34, 13, 30, num5);break;
    case 6:Pait_Bmp(238-13*n, 34, 13, 30, num6);break;
    case 7:Pait_Bmp(238-13*n, 34, 13, 30, num7);break;
    case 8:Pait_Bmp(238-13*n, 34, 13, 30, num8);break;
    case 9:Pait_Bmp(238-13*n, 34, 13, 30, num9);break;
}
}
</span>

附:

硬件环境:J-link v8、mini2440、J-link转接板、串口转USB线、T35 TFT LCD屏

软件环境:windows7(32位)、开发板uboot(NandFlash)、J-link驱动(J-Link ARM V4.10i)、SecureCRT、ADS1.2

完整项目下载

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2025-01-17 01:35:53

mini2440裸试验—计算器(LCD显示,触摸屏突破)的相关文章

mini2440裸机试炼之—计算器(LCD显示,触摸屏中断)

基于T35 TFT LCD屏实现功能: 1. 在屏幕上画一个计算器界面,包括0-9,+,-,*,/: 2. 实现触摸选择界面上的数字和运算符, 3. 并计算出结果显示在显示框内. 注意,只实现整数功能,没涉及小数,只实现一次运算,不保存上次运算结果. 实现界面: 实现过程: 开启LCD电源,初始化LCD>>>LCD填充界面图片>>>开启触摸屏中断>>>获取键值>>>区分数字和功能来调用数字图片显示.   数字图片: 空白图: 除数为零

Raspberry PI Model B+ (LCD显示CPU温度)

Title:Raspberry PI Model B+ (LCD显示CPU温度)  --2015-01-29 17:44 买了块连接Raspberry PI Model B+的LCD显示器,上面没写CPU温度,就加工了下. 修改后的pcd8544_rpi.c: /* ================================================================================= Name : pcd8544_rpi.c Version : 0.1

LCD显示--TM1640芯片驱动程序

TM1640芯片驱动 DIN:串行数据输入,输入数据在 SCLK 的低电平变化,在 SCLK 的高电平被传输. SCLK:在上升沿输入数据 . /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" #include "global.h" #include "string.h" /* Private ty

逆向工程第003篇:令计算器程序显示汉字(上)

一.前言 计算器(Calc.exe)程序在Windows系统中已经存在了很长的时间,也是我们十分常用的软件.但是一般来说,它所显示的都是阿拉伯数字,而且也没有字符显示的切换.这次我会以两篇文章来进行讨论如何让计算器程序显示汉字的数字.本篇来讨论修改的基本原理,下一篇则来讨论如何编程实现. 二.修改原理剖析 在我以前的很多文章中,始终在强调,Windows编程在很大程度上其实就是各种API函数的堆砌,谁掌握了更多的API函数,那么他往往就能够编写出功能齐全的强大软件.当然,编写出优秀的软件还由其它

内核启动后,lcd显示logo失败

针对-s5pv210,但对其他平台也使用 lcd显示logo失败,若显示成功默认的logo是一只企鹅,但是串口打印"Start display and show logo",但是LCD屏没有显示 [ 0.833071] s3cfb s3cfb: [fb2] dma: 0x465ab000, cpu: 0xe1000000, size: 0x005dc000 [ 0.845112] FIMD src sclk = 166750000 [ 0.965701] s3cfb s3cfb: re

LCD显示--HT1621b芯片驱动程序

HT1621b芯片驱动程序 CS : 片选输入接一上拉电阻当/CS 为高电平读写HT1621的数据和命令无效串行接口电路复位当/CS 为低电平和作为输入时读写HT1621的数据和命令有效. WR : WRITE脉冲输入接一上拉电阻在/WR 信号的上升沿 DATA线上的数据写到HT1621. DATA : 外接上拉电阻的串行数据输入/输出. /* Includes ------------------------------------------------------------------*

wm命令使用方法及LCD显示图标大小不正常时解决办法

注:Android 4.3引入的wm工具 wm命令及用法: 系统说明: usage: wm [subcommand] [options] wm size [reset|WxH] wm density [reset|DENSITY] wm overscan [reset|LEFT,TOP,RIGHT,BOTTOM] wm size: return or override display size. wm density: override display density. wm overscan:

LCD显示方向

一.ILI9341内存到显示地址的映射 本文只讨论“正常显示”,不讨论“垂直滚动显示”模式. 可以看到物理内存被两个指针访问,行指针和列指针,行指针范围从000h到013Fh,列指针范围为0000h到00EFh.也就是说,物理内存和LCD显示屏的对应关系是一种竖屏(240*320)的对应的关系.至于如何让GRAM数据显示到LCD屏上,不需要我们去考虑,只要知道这种对应关系就可以了. 那么ILI9341有8种显示方式:左上角->右下角(竖屏).左下角->右上角(竖屏).右上角->左下角(竖

七、在U-boot中让LCD显示图片

1. 编译U-boot 准备好U-boot压缩包urbetter-u-boot-1.1.6-v1.0.tgz,输入命令:tar -xvf urbetter-u-boot-1.1.6-v1.0.tgz 进入U-boot目录,按顺序执行以下命令: make clean make smdk6410_config make 会报出很多/usr/local/arm/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-gcc: not found的错误,这是因