运用到lcd,timer,touch触摸屏,uar函数t等

第一次做的一个裸机设计花了一天半左右的时间,顺便重新温习了前面裸机程序的知识。从lcd,timer计时器,touch触摸屏,uart中断这四个方面着手,以下是第一次实现功能的程序,还需要后期的一些优化,如触摸屏校准,led亮灯,按键图片的切换等等。

main主函数,打印图片和字

#include"lcd.h"
#include"timer.h"
#include "def.h"
#include"uart.h"
#include"touch.h"
int Main()
{    int a=0,b=0,c=0,d=0,f=0,g=0,h=0;
    //Lcd_ClearScr(0xffffff);
    Uart0_Init(115200) ;
    touch_init();
   lcd_Init();
   Timer0_Init();
   paint_pic(gImage_test);
   Draw_Text16(300,100,0xff00ff,test0);
   Draw_Text16(280,100,0xff00ff,test0);
   Draw_Text16(260,100,0xff00ff,test0);
   Draw_Text16(240,100,0xff00ff,test0);
   Draw_Text16(220,100,0xff00ff,test0);
   Draw_Text16(200,100,0xff00ff,test0);
    while(1)
    {
        //paint_line(10,100,10,250, 0xffff00);
        //paint_line(50,100,50,250, 0xff00ff);
        //paint_line(100,100,100,250, 0x00ffff);
        Draw_Text16(234,100,0xff00ff,testn);
        Draw_Text16(274,100,0xff00ff,testn);
        Draw_Text16(5,10,0xff00ff,han1);
        //Lcd_ClearScr1(15,50,16,16,0xfff00);
        Draw_Text16(30,10,0xff00ff,han2);
    }
    return 0;
}

lcd.h

/*********************************************
  NAME: class_lcd.h
  DESC:
 *********************************************/

#ifndef __class_lcd_h__
#define __class_lcd_h__

extern void lcd_Init(void);
extern void paint_pic(const unsigned char pic[]);
extern void paint_pixel(unsigned int x,unsigned int y, unsigned short colour );
extern void paint_line(int x1,int y1,int x2,int y2,int colour);
extern void Draw_Text16(int x,int y,int colour,unsigned char ch[]);//显示16*16汉字

extern const unsigned char gImage_test[];//图片数组

static  unsigned char han1[]={ 0x20, 0x4, 0x18, 0x4, 0x9,
0x24, 0xFF, 0xA4, 0x2, 0x24, 0x42, 0x24, 0x22, 0x24, 0x14, 0x24,
 0x14, 0x24, 0x8, 0x24, 0x8, 0x24, 0x14, 0x24, 0x22,
 0x4, 0x43, 0x4, 0x81, 0x14, 0x0, 0x8,

};//刘
static  unsigned char han2[]={0x10, 0x4, 0x13, 0xFE, 0x12, 0x4,
0x12, 0x4, 0x57, 0xFC, 0x5A, 0x4, 0x52, 0x4, 0x93, 0xFC, 0x10, 0x40,
 0x10, 0x20, 0x13, 0xFC, 0x29, 0x8, 0x24, 0x88,
 0x40, 0x90, 0x47, 0xFE, 0x80, 0x0,
};//煜

static  unsigned char test0[]={0x0 ,0x0, 0x0, 0x0 ,0x0, 0x0, 0x7, 0xF0, 0x1C ,0x38, 0x38 ,
   0x1C, 0x38, 0x1C, 0x78, 0x1E ,0x78, 0x1E, 0x38, 0x1C, 0x38 ,0x1C ,0x38, 0x1C, 0x1C ,
   0x38, 0x7, 0xE0 ,0x0 ,0x0 ,0x0,0x0,};//0
 static  unsigned char test1[]={0x0, 0x0 ,0x0, 0x0 ,0x0 ,0x0,0x1, 0xC0, 0xF ,0xC0, 0x1,
 0xC0 ,0x1, 0xC0, 0x1, 0xC0, 0x1, 0xC0, 0x1, 0xC0, 0x1, 0xC0 ,0x1 ,0xC0, 0x1 ,0xC0,
  0x1F, 0xF8, 0x0, 0x0, 0x0, 0x0,};//1
static  unsigned char test2[]={0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF ,0xF0 ,0x18,0x18, 0x38,
 0x1C ,0x38, 0x1C, 0x0, 0x38, 0x0, 0x70, 0x1, 0xC0 ,0x7, 0x0 ,0xC, 0x4, 0x3F ,0xFC, 0x3F,
  0xFC, 0x0, 0x0, 0x0, 0x0,};//2
static  unsigned char test3[]={0x0 ,0x0 ,0x0 ,0x0, 0x0 ,0x0 ,0xF ,0xF0, 0x38, 0x38, 0x38,
 0x18, 0x0 ,0x38, 0x3 ,0xF0 ,0x3 ,0xF0, 0x0 ,0x18, 0x0, 0x1C, 0x38, 0x1C, 0x38, 0x18,
  0x1F, 0xF0, 0x0 ,0x0, 0x0 ,0x0,};//3
  static  unsigned char test4[]={0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ,0x0, 0x30, 0x0, 0xF0 ,0x1 ,0xF0, 0x2, 0x70, 0xC ,0x70,0x18, 0x70 ,0x30 ,0x70, 0x3F, 0xFE ,0x0, 0x70, 0x0, 0x70, 0x3, 0xFE ,0x0, 0x0, 0x0, 0x0,};//4
  static  unsigned char test5[]={0x0 ,0x0, 0x0, 0x0, 0x0 ,0x0, 0x1F ,0xFC, 0x18, 0x0 ,0x18 ,0x0, 0x18, 0xC0, 0x1F, 0xF8, 0x18, 0x1C ,0x0, 0x1C, 0x10, 0x1C ,0x38, 0x1C, 0x38, 0x18 ,0xF, 0xF0, 0x0 ,0x0 ,0x0 ,0x0,};//5
  static  unsigned char test6[]={0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7 ,0xF8, 0xC, 0x38, 0x18, 0x10, 0x38, 0x0, 0x3F, 0xF8, 0x7C ,0x1C, 0x78, 0xC ,0x38 ,0xE , 0x38 , 0xC , 0x1C , 0x18 , 0xF  ,0xF0  ,0x0  ,0x0  ,0x0 ,0x0,};//6
  static  unsigned char test7[]={0x0, 0x0 ,0x0, 0x0 ,0x0 ,0x0, 0x1F, 0xFE ,0x38 ,0xC ,0x30, 0x10, 0x0 ,0x30 ,0x0, 0x60, 0x0, 0xC0 ,0x1, 0x80, 0x3, 0x80, 0x3, 0x80, 0x3, 0x80 ,0x3 ,0x80 ,0x0, 0x0, 0x0, 0x0,};//7
  static  unsigned char test8[]={0x0 ,0x0, 0x0 ,0x0, 0x0 ,0x0, 0xF ,0xF0 ,0x38, 0x1C, 0x30, 0xC ,0x3C, 0x1C,0x1F, 0xF0, 0xF ,0xF0 ,0x38 ,0x78 ,0x70, 0x1C, 0x70, 0xC, 0x38 ,0x18, 0xF ,0xF0 ,0x0, 0x0, 0x0, 0x0};//8
  static  unsigned char test9[]={0x0, 0x0, 0x0, 0x0 ,0x0, 0x0, 0xF, 0xF0, 0x38 ,0x18, 0x30, 0x1C, 0x70 ,0x1C, 0x70, 0x1C, 0x38 ,0x3C, 0x1F, 0xDC, 0x0, 0x1C, 0x18, 0x38, 0x3C, 0x70, 0x1F, 0xE0 ,0x0, 0x0 ,0x0 ,0x0};//9
static  unsigned char testq[]={0xff ,0xff ,0xff ,0xff, 0xff ,0xff ,0xff ,0xff,0xff ,0xff ,0xff ,0xff, 0xff ,0xff ,0xff ,0xff,
 0xff ,0xff ,0xff ,0xff,0xff ,0xff ,0xff ,0xff,0xff ,0xff ,0xff ,0xff,0xff ,0xff ,0xff ,0xff,0xff ,0xff ,0xff ,0xff,};//清屏
static unsigned char testn[]={0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0};
#endif  //__class_led_h__

lcd程序中实现汉字数字还有图片的显示,这里使用的图片要求较为苛刻,图片全屏时似乎会覆盖字,这个问题还有待解决

#include "2440addr.h"
#include"lcd.h"
#include "def.h"

static void lcd_power_control(int enable);

volatile unsigned short LCDBANK[272][480]; //申请帧内存 LCDBANK是系统随机分配的
//注意这里的数据类型一定是16位的也就是unsigned short 因此该数组是按照16bpp算的,正好数组里面每个单元存储一个像素
//假如这是使用的unsigend int 类型那么rLCDSADDR2 的时候就跟unsigned short 不同,有可能出现奇怪的现象,比如满屏幕只显示
// 480/2  272/2   
//unsigned char  占据8位 一个字节
//unsigned short   占据16位 两个字节
//unsigned int      占据32位 两个字节

void lcd_Init(void)
{
    #define VBPD         (1)            //垂直同步信号的后肩
    #define VFPD         (1)            //垂直同步信号的前肩
    #define VSPW         (9)            //垂直同步信号的脉宽

#define HBPD         (1)            //水平同步信号的后肩
    #define HFPD         (1)            //水平同步信号的前肩
    #define HSPW         (40)            //水平同步信号的脉宽
    
    
    
    
       rGPCUP   = 0xffffffff;   // 禁止内部上拉
       rGPCCON  = 0xaaaaaaaa;   // GPIO管脚用于VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND
       rGPDUP   = 0xffffffff;   // 禁止内部上拉
       rGPDCON  = 0xaaaaaaaa;   // GPIO管脚用于VD[23:8]
       rGPBCON &= ~(3<<0);  // lcd背光灯控制引脚
          rGPBCON |= (1<<0);
          rGPBDAT &= ~(1<<0);     //关闭背光灯

// 设置像素时钟频率,屏幕模型,bpp模式
    rLCDCON1 = (5<< 8)|(3 <<5 )|(12 << 1)  ;
 //设置垂直方向各信号的时间参数
    rLCDCON2 = (VBPD << 24)|(271 << 14)|(VFPD << 6)|(VSPW);
 //设置水平方向各信号的时间参数
    rLCDCON3 = (HBPD << 19)|(479 << 8)|(HFPD);
 //HSPW值,表示脉冲宽度为(HSPW)个VCLK周期
    rLCDCON4 = (HSPW);
 //信号极性 数据存储格式等的设置  
    rLCDCON5 = (1 << 11) |(1 << 10)| (1 << 9) | (1 << 8)    | (1) ;
    //选择565格式  上升沿取视频数据  VLINE/HSYNC VFIAME/VSYNC 反转 存储格式P1 P2
    
    rLCDSADDR1 = (((unsigned int)LCDBANK >> 22) << 21) | ((((unsigned int)LCDBANK)>> 1)& 0x1fffff );
    //((unsigned int)LCDBANK >> 22) << 21)  将内存地址的22到30位存到寄存器的21到29位中
    //((((unsigned int)LCDBANK)>> 1)& 0x1fffff )内存首地址(32位的数值)的第21~1位放到寄存器的20~0
    //&0x1fffff的作用是取出低21位 这样不会影响到存入寄存器的高22-32位。
     rLCDSADDR2 = ( ((unsigned int)LCDBANK + ( (480 * 272 *2) ) >> 1 ))  & 0x1fffff;
     //((the frame end address) >>1 ) + 1  之所以有(480 * 272 *2)的乘以2是因为16BPP
     //假如8BPP乘以1表示在8BPP中一个像素使用一个字节来表示
     ///先左移1位后取低21位
    
     rLCDSADDR3 = (0 << 11) | (480 / 1);
     //offsize为0 16bpp正好一个像素占用一个半字

///禁止临时调色板寄存器
        rTPAL = 0;
     //    rTCONSEL &=~((1<<4) | 1);
        rLCDINTMSK |= (3);                                                    // MASK LCD Sub Interrupt

rLCDCON1 |= 1;//使能LCD数据信号的传输
         
    lcd_power_control(1);
}

/*********************************
lcd电源使能函数
为1表示使能电源信号
为0表示禁止电源

***************************************/
static void lcd_power_control(int enable)
{
    rGPGCON = (rGPGCON & (~(3<<8))) | (3<<8);   // GPG4用作LCD_PWREN
    rGPGUP  = (rGPGUP & (~(1<<4))) | (1<<4);    // 禁止内部上拉
    rGPGDAT = rGPGDAT | (1<<4) ; //输出高电平
    rLCDCON5 = rLCDCON5 & (~(1<<3)) | (enable<<3); //LCD_PWREN信号输出使能
   
    rGPBDAT |= (enable<<0);     //打开背光灯

}

/**************************************************************
lcd颜色函数
参数1 x的坐标值
参数2 y的坐标值
参数3 该点的颜色值
功能说明:LCD控制器从内存中获得某个像素的16位颜色值后,直接通过VD[23:0]数据线
          发生给LCD,也就是让LCD屏幕显示所设置的colour值。
**************************************************************/
void paint_pixel(unsigned int x,unsigned int y, unsigned short colour )
{

if ( (x < 480) && (y < 272) )
        LCDBANK[(y)][(x)] = colour;

}

/**************************************************************
LCD显示图片
输入要显示图片
**************************************************************/

void paint_pic(const unsigned char pic[])
{
    
    int x,y;
    unsigned int colour;
    int p = 0;
    
    for( y =0 ; y < 240 ; y++ )
    {
        for( x = 0 ; x < 480 ; x++ )
        {
            colour = pic[p] | (pic[p+1]<<8) ;//获取图片的像素值(一个点16数据表示)
        
            //colour = pic[p] ;
            if ( ( x < 480) && ( y < 240) )
                LCDBANK[y][x] = colour ;    //获取得到的图片像素值格式也是565
                                            //所以可以直接赋值给LCD显示
            p = p + 2 ;  //图片一个像素点是按照8位而本程序配置的是16位
        }
    }   
    
}

void Lcd_ClearScr1(int x0,int y0,int h,int l,U32 c)
{
    unsigned int x,y;
    for( y = y0 ; y <y0+l; y++ )
    {    
        for( x = x0 ; x <x0+h ; x++ )
        {
        LCDBANK[y][x] = c ;
        }
    }
}

/**************************************************************
TFT LCD全屏填充特定颜色单元或清屏
**************************************************************/
void Lcd_ClearScr(unsigned int colour)
{
    unsigned int x,y ;
        
    for( y = 0 ; y < 272 ; y++ )
    {
        for( x = 0 ; x < 480; x++ )
        {
            LCDBANK[y][x] = colour ;
        }
    }
}

/**************************************************************
LCD显示16*16的汉字
参数1 x轴的坐标
参数2 y轴的坐标
参数3 线条的颜色
参数4 汉字的数组
**************************************************************/

void Draw_Text16(int x,int y,int colour,unsigned char ch[])//显示16*16汉字
{
       unsigned short int i,j;
       unsigned char mask,buffer;
 
       for(i=0;i<16;i++)
       {
              mask=0x80;                  //掩码,用作取出每一位
              buffer=ch[i*2];             //提取一行的第一个字节
              for(j=0;j<8;j++)
              {                  
                     if(buffer&mask)//这一位为1则显示 注意:上色就是显示了-不给上色也就显示不了
                     {
                            paint_pixel(x+j,y+i,colour);        //为笔画上色
                     }
                     mask=mask>>1; //用以取出下一位                 
              }
              mask=0x80;                  //掩码   
              buffer=ch[i*2+1];         //提取一行的第二个字节
              for(j=0;j<8;j++)
              {                  
                     if(buffer&mask)
                     {
                            paint_pixel(x+j+8,y+i,colour);           //为笔画上色
                     }
                     mask=mask>>1;                  
              }
       }
}

/**************************************************************
LCD画线
参数1 x轴的起点坐标
参数2 y轴的起点坐标
参数3 x轴的终点坐标
参数4 y轴的终点坐标
参数5 线条的颜色
**************************************************************/

void paint_line(int x1,int y1,int x2,int y2,int colour)
{
    int dx,dy,e;
    dx=x2-x1;
    dy=y2-y1;
    
    if(dx>=0)
    {
        if(dy >= 0) // dy>=0
        {
            if(dx>=dy) // 1/8 octant
            {
                e=dy-dx/2;
                while(x1<=x2)
                {
                    paint_pixel(x1,y1,colour);
                    if(e>0){y1+=1;e-=dx;}   
                    x1+=1;
                    e+=dy;
                }
            }
            else        // 2/8 octant
            {
                e=dx-dy/2;
                while(y1<=y2)
                {
                    paint_pixel(x1,y1,colour);
                    if(e>0){x1+=1;e-=dy;}   
                    y1+=1;
                    e+=dx;
                }
            }
        }
        else           // dy<0
        {
            dy=-dy;   // dy=abs(dy)

if(dx>=dy) // 8/8 octant
            {
                e=dy-dx/2;
                while(x1<=x2)
                {
                    paint_pixel(x1,y1,colour);
                    if(e>0){y1-=1;e-=dx;}   
                    x1+=1;
                    e+=dy;
                }
            }
            else        // 7/8 octant
            {
                e=dx-dy/2;
                while(y1>=y2)
                {
                    paint_pixel(x1,y1,colour);
                    if(e>0){x1+=1;e-=dy;}   
                    y1-=1;
                    e+=dx;
                }
            }
        }   
    }
    else //dx<0
    {
        dx=-dx;     //dx=abs(dx)
        if(dy >= 0) // dy>=0
        {
            if(dx>=dy) // 4/8 octant
            {
                e=dy-dx/2;
                while(x1>=x2)
                {
                    paint_pixel(x1,y1,colour);
                    if(e>0){y1+=1;e-=dx;}   
                    x1-=1;
                    e+=dy;
                }
            }
            else        // 3/8 octant
            {
                e=dx-dy/2;
                while(y1<=y2)
                {
                    paint_pixel(x1,y1,colour);
                    if(e>0){x1-=1;e-=dy;}   
                    y1+=1;
                    e+=dx;
                }
            }
        }
        else           // dy<0
        {
            dy=-dy;   // dy=abs(dy)

if(dx>=dy) // 5/8 octant
            {
                e=dy-dx/2;
                while(x1>=x2)
                {
                    paint_pixel(x1,y1,colour);
                    if(e>0){y1-=1;e-=dx;}   
                    x1-=1;
                    e+=dy;
                }
            }
            else        // 6/8 octant
            {
                e=dx-dy/2;
                while(y1>=y2)
                {
                    paint_pixel(x1,y1,colour);
                    if(e>0){x1-=1;e-=dy;}   
                    y1-=1;
                    e+=dx;
                }
            }
        }   
    }

}

timer计数器函数

#include "timer.h"
#include "config.h"
#include"lcd.h"

void timer0_service_Init(void);

void Timer0_Init(void)
{
//第一步:选定timer0-5定时器,设置预分频器 TCFG0和TCFG1
//        定时器的时钟频率 = PCLK / {prescaler value+1 } / {divider value}
//(2440init.s设置好了PCLK=50m)

rTCFG0 &= ~(0xFF) ;
    rTCFG0 |= 99 ;    //预分频系数为99
    rTCFG1 &= ~(0xf) ;
    rTCFG1 |= 0x02 ;   //8分频
//定时器的时钟频率=50000000/100/8=62500
//第二步:给定时器设定定时时间,也就是给TCNTB0装入初值
//        和 装入TCMPBn寄存器比较器(默认0)
    rTCNTB0 = 62500 ;//1s中断一次
//第三步:设置定时时间载入方式及其打开定时器 使用寄存器TCON
    rTCON |=  (1 << 1)  ;//将TCNTB0和TCMPB0装入内部的TCNT0和TCMP0
    rTCON &=~(0xf);
    rTCON |= 0x09 ;  //自动重载并且打开定时器0
    rINTMSK &=~(1<<10);//打开定时器0 中断
    timer0_service_Init();//中断服务函数初始化

}

void __irq timer0_service(void)
{
    
  static int flag=0;
 if(flag>4)
 {flag=0;}
  switch(flag)
        {
            case 0:
                Lcd_ClearScr(0x000000);
                // paint_pic(gImage_test);
                break ;    
            case 1:
                Lcd_ClearScr(0x00ff00);
                // paint_pic(gImage_test1);
                break ;
            case 2:
                Lcd_ClearScr(0xff0000);
                // paint_pic(gImage_test);
                break ;
            case 3:
                Lcd_ClearScr(0xffffff);
                // paint_pic(gImage_test1);
            case 4:
                //Lcd_ClearScr(0x00<<11|0x00<<5|0x00 );
                 paint_pic(gImage_test);
                break ;    
            default:
               break ;    
        }
    flag++;
 
  rSRCPND |= (0x1<<10);
  rINTPND |= (0x1<<10);
 
}

void timer0_service_Init(void)
{
    pISR_TIMER0 = (unsigned int)timer0_service ;

}

uart中断函数
#include "config.h"
#include "uart.h"

#define TXD0READY (1 << 2)
#define RXD0READY (1 << 0)
#define PCLK 50000000//时钟源设为PCLK

void Uart0_Init(unsigned int bandrate)
{
    //1.设置相关的引脚为UART功能的引脚
    rGPHCON &= ~((3 << 4) | (3 << 6)) ;//GPH2-GPH3是RX/TX
    rGPHCON |= ((2 << 4) | (2 << 6)) ;//GPH2--TXD[0];GPH3--RXD[0]
    rGPHUP = 0x00 ;                   //使能上拉
    //2.设置UART的数据帧格式 可通过ULCONn来设置
    rULCON0 |= 0x03 ;  // 无校验 8位数据,1位停止位
    //3.UART时钟为PCLK,查询方式  可通过UCONn来设置             
    rUCON0 = 0x05 ; //0101
     //    设置UART的波特率  UBRDIVn        
    rUBRDIV0  = PCLK / bandrate / 16 - 1 ;
    rURXH0 = 0;
}

void putc(unsigned char c)
{
     /* 向UTXH0寄存器中写入数据,UART即自动将它发送出去 */
    rUTXH0 = c ;
    while(!(rUTRSTAT0 & TXD0READY)) ;//等待上个字符发送完毕
}
unsigned char getc(void)
{
    unsigned char c ;
    /* 等待,直到接收缓冲区中的有数据 */
    while(!(rUTRSTAT0 & RXD0READY)) ;
     /* 直接读取URXH0寄存器,即可获得接收到的数据 */
    c = rURXH0 ;
    return c ;
    
}

#include "2440addr.h"
#include "config.h"
#include "uart.h"
#include "touch.h"
#include"timer.h"
#include"lcd.h"
extern int a,b,c,d,e,f,g,h;
int xdata=0;
int ydata=0;
void __irq touch_isr()
{

//1、    进入中断服务函数 判断是触笔按下引起的中断还是触笔抬起引起的中断
    /*检测子中断源,判断是否是触摸屏(INT_TC)中断,且触摸笔按下*/
    //正常情况下这里是因为触笔按下触发的中断
    if(rSUBSRCPND &(1<<9))   //检查是否完成了中断位ADC
    {
        if( !(rADCDAT0&0x8000))  //当触笔落下时,rADCDAT0【15?=0;
           {
    
               putc(' ');
           }
        else                         //当触笔抬起时,rADCDAT0【15?=1;        
           {
              
               putc(' ');
              
           }
    }
    
   // 2、    设置XP的上拉电阻无效,切换到自动(顺序)得到X、Y坐标中断接口模式
    rADCTSC |= (1<<3)|(1<<2); //XP上拉无效,自动(顺序)得到X、Y坐标

//3、    在自动测量XY坐标模式下,重新设置延时间隔ADCDLY,注意初始频率为PCLK
     rADCDLY=40000;     //正常转换模式延时 (1/50M)*40000=0.8ms
   //4、    设置寄存器ADCCON[0](此时保证ADCCON[0]=0) 使之开始转换ADC。
     rADCCON |= 0x1;          //   设置AD开始转换  当硬件启动ADC转换时,该位被清0
    
    //5、    通过判断ADCCON【0】 ADCCON【15】 SRCPND【31】 是否已经转化结束。
    while(rADCCON & 0x1);   //检查AD转换是否已经开始        
    while(!(rADCCON & (1<<15)));  //等待AD转换结束

while(!(rSRCPND &(1<<31)));  //检查AD中断标志位是否产生中断请求
 
//6、    读取ADCDAT0 和ADCDAT1的低10位获取坐标值
    xdata=(rADCDAT0&0x3ff);//取出低10位//11 1111 1111 xxxx xxxx
 /*获取X,Y坐标*/
    ydata=(rADCDAT1&0x3ff);//取出低10位5、    通过判断ADCCON【0】 ADCCON【15】 SRCPND【31】 是否已经转化结束。
    
    
     if(xdata<250&& xdata>200&&ydata<870&&ydata>740)rINTMSK&=~(1<<10);//开始
    else if(xdata<350&& xdata>280&&ydata<870&&ydata>740)rINTMSK|=(1<<10);//暂停
    else if(xdata<495&& xdata>415&&ydata<870&&ydata>740){     rINTMSK&=~(1<<10);
                                                            a=0,b=0,c=0,d=0,e=0,f=0;
                                                            rINTMSK|=(1<<10);
                                                            Draw_Text16(300,100,0x000000,testq);
                                                               Draw_Text16(280,100,0x000000,testq);
                                                               Draw_Text16(260,100,0x000000,testq);
                                                              Draw_Text16(240,100,0x000000,testq);
                                                              Draw_Text16(220,100,0x000000,testq);
                                                              Draw_Text16(200,100,0x000000,testq);        
                                                            Draw_Text16(300,100,0xff00ff,test0);
                                                               Draw_Text16(280,100,0xff00ff,test0);
                                                               Draw_Text16(260,100,0xff00ff,test0);
                                                              Draw_Text16(240,100,0xff00ff,test0);
                                                              Draw_Text16(220,100,0xff00ff,test0);
                                                              Draw_Text16(200,100,0xff00ff,test0);                                                            
                                                        }//重置
    
    
    
    //7、    清除中断挂起标志位 涉及到的寄存器有SUBSRCPND SRCPND  INTPND
    rSUBSRCPND |=(1<<9);   //清中断
    rSRCPND    |=(1<<31);
    rINTPND    |=(1<<31);

//串口发送读取的数据
   putc('x'); putc(':');
   putc(xdata/1000%10+48);//千位 例如0200如果千位为0 则ASCII值为48则才能显示出0,所以要加上48
   putc(xdata/100%10+48);//百位,
   putc(xdata/10%10+48); //十位
   putc(xdata%10+48);  //个位
 
   putc('y'); putc(':');
   putc(ydata/1000%10+48);
   putc(ydata/100%10+48);
   putc(ydata/10%10+48);
   putc(ydata%10+48);
   
//8、    转换模式为等待中断模式(ADCTSC=0xd3),并设置设置触笔抬起触发中断ADCTSC[8]=1

/*设置触摸屏为等待中断模式,等待触摸笔抬起*/
    rADCTSC =0xd3;     //设置为等待中断模式  Wfait,XP_PU,XP_Dis,XM_Dis,YP_Dis,YM_En
    rADCTSC=rADCTSC|(1<<8); //设置触笔抬起触发中断
//检查光标提起中断信号
//9、    检测是否触笔是否抬起,并等待触笔抬起(rSUBSRCPND【9】=?1)
while(1)  //检查抬笔状态
{
  if(rSUBSRCPND & (1<<9))
   //抬笔时再次触发中断
  {
    
     putc(' ');
     putc(0x0d);//发送换行符
     putc(0x0a);
      break;  
  }
}
 
  // 10、    重新设置延时间隔ADCDLY,在等待中断模式,注意初始频率为3.6864M
   
  rADCDLY=36864;  //等待中断模式延迟 (1/3.6864M)*36864=0.01s=10ms
 
//  11、    设置触摸屏为等待中断模式,并设置下次触摸笔按下产生中断

rADCTSC =0xd3;   //设置触摸屏为等待中断模式,等待下次触摸笔按下
   
  // 12、    为了确保可以再次清除中断挂起标志位 涉及到的寄存器有SUBSRCPND SRCPND  INTPND
    
   rSUBSRCPND  |=(1<<9);   //清中断
    rSRCPND    |=(1<<31);
    rINTPND    |=(1<<31);

}

void touch_init()   /*触摸屏初始化*/
{   
   
  // AD转换频率=PCLK/(分频值+1),且AD的最高频率为2.5M,这里PCLK=50M,所以AD的转换频率为2M
   unsigned int preScaler = 24;
   
   //1、设置等待模式下的延时时间(此时频率为3.6864M) 给ADCDLY寄存器赋值
    rADCDLY=36864;        //等待中断模式延迟 (1/3.6864M)*36864=0.01s=10ms
    
   //2、设置ADC转换的时钟频率 通过寄存器ADCCON来赋值
    rADCCON = (1<<14)|(preScaler<<6); //设置分频系数,并且设定分频有效
                                      //设置A/D转换的时钟 = PCLK/(24+1)=2Mhz,小于2.5M。
   // 3、    设置中断接口模式为等待中断模式 ADCCON= 0xd3
    rADCTSC=0xd3;   //设置触摸屏为等待中断模式,等待触摸笔被按下(触笔按下触发中断)
   
   // 4、    清除中断挂起标志位 涉及到的寄存器有SUBSRCPND SRCPND  INTPND
    rSUBSRCPND |= (1<<9); //清除子中断INT_TC标志位
    rSRCPND    |= (1<<31);   //清除adc中断INT_ADC标志位
    rINTPND    |= (1<<31);   //清除adc中断INT_ADC标志位
        
   // 5、    使能ADC及其触摸屏有关的中断 涉及到底寄存器有INTSUBMSK  INTMSK
    rINTSUBMSK &= ~(1<<9); //使能INT_TC中断
    rINTMSK    &= ~(1<<31);//使能INT_ADC中断

pISR_ADC = (unsigned int )touch_isr;  //将中断执行函数如入地址赋给INT_TC中断
}

第一次嵌入式裸机应用设计——秒表器相关推荐

  1. 基于嵌入式Linux的MP3播放器的设计与实现

    摘要:本文详细介绍了嵌入式系统的特点以及嵌入式系统开发的流程,分析基于嵌入式Linux的MP3播放器的关键技术,设计和实现了一种基于嵌入式系统的 MP3 播放器.该播放器利用 QT 技术和开源的音频解 ...

  2. 这个设计思想能启蒙你很多年,嵌入式裸机按键扫描

    这个设计思想能启蒙你很多年,嵌入式裸机按键扫描 摘要:本文目的是讲述一个按键扫描处理的面向对象开发的设计思想,适用于裸机开发,通过按键扫描,检测到按键是否按下,松开等状态,并将该状态通过其他形式反馈给 ...

  3. 嵌入式系统软件架构设计

    嵌入式系统软件架构设计 目录 1. 前言 4 2. 决定架构的因素和架构的影响 4 2.1. 常见的误解 5 2.1.1. 小型的系统不需要架构 5 2.1.2. 敏捷开发不需要架构 7 3. 嵌入式 ...

  4. linux 远程挂载摄像头_基于Linux的嵌入式网络摄像机设计

    本嵌入式网络摄像机采用高性能ARM9芯片微处理器,内置嵌入式Web服务器. 通过嵌入式多任务操作系统采集摄像机视频数据:采集的视频信号数字化后经MJPEG算法压缩,再通过内部总线送到内置的Web服务器 ...

  5. 基于STM32的光敏传感器数据采集系统-嵌入式系统与设计课程设计

    目录 1 项目概述 1.1 项目介绍 1.2 项目开发环境 1.3 小组人员及分工 2 需求分析 2.1 系统需求分析 2.2 可行性分析 2.3 项目实施安排 3 系统硬件设计 3.1 系统整体硬件 ...

  6. 嵌入式系统开发设计---嵌入式系统开发设计

    嵌入式系统设计的主要任务是定义系统的功能.决定系统的架构,并将功能映射到系统实现架构上.这里,系统架构既包括软件系统架构也包括硬件系统架构.一种架构可以映射到各种不同的物理实现,每种实现表示不同的取舍 ...

  7. 嵌入式系统课程设计题目

    简介:一些嵌入式系统课程设计题目,可以当做对你学习ARM的一个检测. 嵌入式系统课程设计-选题要求及课题 1.嵌入式系统课程设计时长两星期,要求学生分组进行课程设计,每组学生人数为2-3人(可在不超过 ...

  8. Vivado设计秒表计时器实现00分00.00秒到59分59.99秒的计时(verilog语言)

    目录 0.写在最前 一.课程设计要求: 三.名词说明解释 四.Vivado代码实现部分 五.仿真测试程序 六.约束文件 七.开发板结果展示 八.关于改进/扩展 ① 增加秒与 0.1s 之间的分隔符&q ...

  9. 基于ARM的嵌入式网络收音机的设计

    基于ARM的嵌入式网络收音机的设计 摘要:研究了一种基于ARM处理器的嵌入式网络收音机的设计方案.该系统以ARM处理器及其外围设备为硬件平台,以嵌入式Linux为操作系统,实现了网络收音.局域网共享音 ...

最新文章

  1. 算法-----最大子序和(Java 版本)
  2. inux时间问题两篇
  3. Python的逻辑判断和循环 || 打印九九乘法表
  4. 【项目管理】ITTO-相关方管理
  5. Java Integer于Int 进行==双等于的内存比较时的一些问题说明
  6. Android自定义属性 format详解
  7. eclipse查看git地址_gitamp;github的入门实战
  8. 手把手教你用Python给小姐姐美个颜
  9. 英语国家的学生学语法么?_纪念国家语法日
  10. 荒野行动系统推荐观战榜_荒野行动 观战延迟投票结果公示 更新计划抢先看!...
  11. shell脚本--判断输入的ip是否正确
  12. 伪造http请求救急
  13. mac vulkan_基于 mac 的 ncnn vulkan iOS集成参考
  14. 操作系统课程设计之二级文件系统演示
  15. 一维卷积神经网络在近红外光谱分析中的应用
  16. php 上传图片返回预览,图片上传前的预览(PHP)
  17. WPF 自定义分页控件TextBox分页页数只输入数字验证
  18. 如何实现发票信息的自动录入与查验?
  19. Windows防火墙添加禁用规则——以禁用微信为例
  20. Oracle 11g R2+RAC+ASM+redhat安装详解1

热门文章

  1. 安网路由器 静态IP和PPOE混用时,如果设置了路由器定时重启可能导致路由器罢工...
  2. DM10分区图文教程
  3. 有哪些免费下载PNG格式的素材网站?
  4. MATLAB 到底有多厉害?
  5. 8款最佳的开源在线学习CMS系统[转]
  6. 烦不烦,别再问我时间复杂度了:这次不色,女孩子进来吧
  7. python 实现股票MACD计算
  8. h5学习笔记:学习frozenui 的ui-row代码
  9. WindowsServer2019下Php(php-7.4.3-Win32-vc15-x64) 调用C# .dll文件
  10. python爬虫之多线程threading、多进程multiprocessing、协程aiohttp 批量下载图片