本帖最后由 a939561900 于 2015-6-23 13:52 编辑  
 
//########################################################################### 
// LCD12864液晶显示程序 
//########################################################################### 
 
#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File 
 
// Prototype statements for functions found within this file. 
void delay_loop(Uint32); 
void Gpio_select(void); 
 
void write_byte(Uint16 x);    //写8位数据 
void lcd_write_cmd(Uint16);   //lcd 命令写  
void lcd_write_data(Uint16);  //lcd 数据写  
Uint16 lcd_read_data(void);   //lcd 数据读  
void lcd_set_dot(unsigned char x, unsigned char y); 
 
#define  BASIC_SET   0x30           //基本指令集  00110000 
#define  EXTEND_SET  0x34           //扩展指令集  00110100 
#define  DRAW_ON     0x36           //绘图显示开  00110110 
#define  DRAW_OFF    0x34           //绘图显示关  00110100 
#define  execute_72us    delay_loop(400)     //执行时间 
#define  SCLK_quarter    delay_loop(40)       //四分之一SCLK时钟 SCLK是LCD串行通信时钟 
#define  SCLK_half       delay_loop(80)       //二分之一SCLK时钟 SCLK是LCD串行通信时钟 
 
#define CS_1        GpioDataRegs.GPADAT.bit.GPIO5=1             //GPIO5作为CS    
#define CS_0        GpioDataRegs.GPADAT.bit.GPIO5=0             //GPIO5作为CS    
#define SCLK_1      GpioDataRegs.GPADAT.bit.GPIO4=1             //GPIO4作为SCLK  
#define SCLK_0      GpioDataRegs.GPADAT.bit.GPIO4=0             //GPIO4作为SCLK 
#define SDATA_OUT   GpioCtrlRegs.GPADIR.bit.GPIO2=1             //GPIO2作为SDATA   
#define SDATA_IN    GpioCtrlRegs.GPADIR.bit.GPIO2=0             //GPIO2作为SDATA 
#define SDATA       GpioDataRegs.GPADAT.bit.GPIO2 
#define RST_1       GpioDataRegs.GPADAT.bit.GPIO3=1             //GPIO3做RST  
#define RST_0       GpioDataRegs.GPADAT.bit.GPIO3=0             //GPIO3做RST   
 
#define uchar unsigned char 
#define uint  Uint16 
 
uchar AC_TABLE[]={ 
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,      //第一行汉字位置 
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,      //第二行汉字位置 
0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,      //第三行汉字位置 
0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,      //第四行汉字位置 
}; 
 
Uint16 sign[]={ 
0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, 
0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11, 
0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19, 
0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21, 
}; 
uchar  str2[]="合肥零零电子科技"; 
uchar  str1[]="黄河远上白云间,一片孤城万仞山。羌笛何须怨杨柳,春风不度玉门关。"; 
Uint16  bmp1[]; 
 
Uint16 Key = 1;  
 
/****************************************************************************************** 
* 函数名称    :Delay 
******************************************************************************************/ 
void Delay(uint MS) 
{ 
     uchar us,usn; 
     while(MS!=0)            //for 12M 
      {  
         usn = 2; 
         while(usn!=0) 
          { 
            us = 0xf5; 
            while (us!=0) 
             { 
               us--; 
             }; 
            usn--; 
           } 
         MS--; 
      } 
} 
/****************************************************************************************** 
* 函数名称    :DelayKey 
******************************************************************************************/ 
void DelayKey(uint Second , uint MS100) 
{                              //输入精确到0.1S,是用"," 
     uint i; 
     for(i=0;i<Second*100+MS100*10;i++) 
     { 
           if(Key==0) 
           { 
                 Delay(20); 
                 while(Key==0)  
                   { 
                           Delay(20); 
                   } 
                 break; 
           } 
           else Delay(10); 
     } 
} 
 
/****************************************************************************************** 
* 函数名称    :LcmInit 
******************************************************************************************/ 
void LcmInit( void ) 
{ 
     lcd_write_cmd(0x30);      //8BitMCU,基本指令集合 
     lcd_write_cmd(0x03);      //AC归0,不改变DDRAM内容 
     lcd_write_cmd(0x0C);      //显示ON,游标OFF,游标位反白OFF 
     lcd_write_cmd(0x01);      //清屏,AC归0 
     lcd_write_cmd(0x06);      //写入时,游标右移动 
} 
 
/****************************************************************************************** 
* 函数名称    :LcmClearTXT 
* 功能描述    :文本区清RAM函数 
******************************************************************************************/ 
void LcmClearTXT( void ) 
{ 
     uchar i; 
     lcd_write_cmd(0x30);      //8BitMCU,基本指令集合 
     lcd_write_cmd(0x80);      //AC归起始位 
     for(i=0;i<64;i++) 
     lcd_write_data(0x20); 
} 
 
/****************************************************************************************** 
* 函数名称    :LcmClearBMP 
* 功能描述    :图形区清RAM函数 
******************************************************************************************/ 
void LcmClearBMP( void ) 
{ 
     uchar i,j; 
     lcd_write_cmd(0x34);      //8Bit扩充指令集,即使是36H也要写两次 
     lcd_write_cmd(0x36);      //绘图ON,基本指令集里面36H不能开绘图 
     for(i=0;i<32;i++)            //12864实际为256x32 
     { 
           lcd_write_cmd(0x80|i);      //行位置 
           lcd_write_cmd(0x80);      //列位置 
           for(j=0;j<32;j++)            //256/8=32 byte 
                lcd_write_data(0); 
     } 
} 
/****************************************************************************************** 
* 函数名称    :PutStr 
******************************************************************************************/ 
void PutStr(uchar row,uchar col,uchar *puts) 
{ 
     lcd_write_cmd(0x30);      //8BitMCU,基本指令集合 
     lcd_write_cmd(AC_TABLE[8*row+col]);      //起始位置 
     while(*puts != '\0')      //判断字符串是否显示完毕 
     { 
           if(col==8)            //判断换行 
           {            //若不判断,则自动从第一行到第三行 
                 col=0; 
                 row++; 
           } 
           if(row==4) row=0;      //一屏显示完,回到屏左上角 
           lcd_write_cmd(AC_TABLE[8*row+col]); 
           lcd_write_data(*puts);      //一个汉字要写两次 
           puts++; 
           lcd_write_data(*puts); 
           puts++; 
           col++; 
     } 
} 
/****************************************************************************************** 
* 函数名称    :PutSign 
******************************************************************************************/ 
void PutSign(uchar row,uchar col,Uint16 *sign) 
{ 
     Uint16 i=0; 
     lcd_write_cmd(0x30);      //8BitMCU,基本指令集合 
     lcd_write_cmd(AC_TABLE[8*row+col]);      //起始位置 sign_TABLE[8*row+col] 
     for(i=0;i<32;i++)      //判断字符串是否显示完毕 
     { 
           if(col==8)            //判断换行 半宽符号,所以一行16个 
           {            //若不判断,则自动从第一行到第三行 
                col=0; 
                row++; 
           } 
           if(row==4) row=0;      //一屏显示完,回到屏左上角 
           lcd_write_cmd(AC_TABLE[8*row+col]); 
           lcd_write_data(*sign);      //一个汉字要写两次 
           sign++; 
           col++; 
     } 
 
 
} 
/****************************************************************************************** 
* 函数名称    :PutBMP 
******************************************************************************************/ 
void PutBMP(Uint16 *puts) 
{ 
     uint x=0; 
     uchar i,j; 
     lcd_write_cmd(0x34);      //8Bit扩充指令集,即使是36H也要写两次 
     lcd_write_cmd(0x36);      //绘图ON,基本指令集里面36H不能开绘图 
     for(i=0;i<32;i++)            //12864实际为256x32 
     { 
           lcd_write_cmd(0x80|i);      //行位置 
           lcd_write_cmd(0x80);      //列位置 
           for(j=0;j<16;j++)      //256/8=32 byte 
           {            //列位置每行自动增加 
                 lcd_write_data(((puts[x]&0xFF00)>>8)); 
                 lcd_write_data((puts[x]&0x00FF)); 
                 x++; 
           } 
     } 
} 
/****************************************************************************************** 
* 函数名称    :DisplayDots 
******************************************************************************************/ 
void DisplayDots(uchar DotByte) 
{ 
     uchar i,j; 
     lcd_write_cmd(0x34);      //8Bit扩充指令集,即使是36H也要写两次 
     lcd_write_cmd(0x36);      //绘图ON,基本指令集里面36H不能开绘图 
     for(i=0;i<32;i++)            //12864实际为256x32 
     { 
           lcd_write_cmd(0x80|i);      //行位置 
           lcd_write_cmd(0x80);      //列位置 
           for(j=0;j<32;j++)      //256/8=32 byte 
           {            //列位置每行自动增加 
              lcd_write_data(DotByte);                   
           } 
           DotByte=~DotByte; 
     } 
} 
 
/******************************************************************************************/ 
 
void main(void) 
{ 
 
// Step 1. Initialize System Control: 
// PLL, WatchDog, enable Peripheral Clocks 
// This example function is found in the DSP2833x_SysCtrl.c file. 
   InitSysCtrl(); 
 
// Step 2. Initalize GPIO:  
           Gpio_select(); 
 
// Step 3. Clear all interrupts and initialize PIE vector table: 
// Disable CPU interrupts 
   DINT; 
 
// Initialize PIE control registers to their default state. 
// The default state is all PIE interrupts disabled and flags 
// are cleared. 
// This function is found in the DSP2833x_PieCtrl.c file. 
   InitPieCtrl(); 
 
// Disable CPU interrupts and clear all CPU interrupt flags: 
   IER = 0x0000; 
   IFR = 0x0000; 
 
// Initialize the PIE vector table with pointers to the shell Interrupt 
// Service Routines (ISR). 
// This will populate the entire table, even if the interrupt 
// is not used in this example.  This is useful for debug purposes. 
// The shell ISR routines are found in DSP2833x_DefaultIsr.c. 
// This function is found in DSP2833x_PieVect.c. 
   InitPieVectTable(); 
 
 
 
   RST_0; 
   Delay(30); 
 
   RST_1; 
   LcmInit(); 
   LcmClearTXT(); 
   LcmClearBMP(); 
 
   for(;;) 
   {    
 
        // lcd_set_dot(2,2); 
           //显示图像 
           LcmClearTXT(); 
       PutBMP(bmp1); 
       DelayKey(20,5); 
       /* 
       //全屏间隔显示点 
       DisplayDots(0x55); 
       DelayKey(1,5); 
 
       //全屏间隔显示点             
       LcmClearTXT(); 
       DisplayDots(0xaa); 
       DelayKey(1,5); 
 
             
       */  
       //全屏显示文字 
 
                LcmClearBMP(); 
       DelayKey(15,5);  
       PutStr(0,0,str1); 
       DelayKey(30,5);  
         //  PutSign(0,0,sign); 
      /*  
       LcmClearTXT(); 
       DelayKey(15,5);  
       PutStr(0,0,str2); 
       DelayKey(30,5);  
            //全屏间隔显示半型符号             
       LcmClearTXT(); 
       PutSign(0,0,sign); 
       DelayKey(30,5);  
//            while(1); */ 
    } 
 
 
}          
 
 
/****************************************************************************************** 
* 函数名称    :delay_loop 
******************************************************************************************/ 
void delay_loop(Uint32 x) 
{ 
    Uint32      i; 
    for (i = 0; i < x; i++) {} 
} 
/****************************************************************************************** 
* 函数名称    :Gpio_select 
******************************************************************************************/ 
void Gpio_select(void) 
{ 
  EALLOW; 
        GpioCtrlRegs.GPAPUD.bit.GPIO2 = 0; 
        GpioCtrlRegs.GPAPUD.bit.GPIO3 = 0; 
        GpioCtrlRegs.GPAPUD.bit.GPIO4 = 0; 
        GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0;  
            
    GpioCtrlRegs.GPAMUX1.bit.GPIO2=0; 
    GpioCtrlRegs.GPAMUX1.bit.GPIO4=0; 
        GpioCtrlRegs.GPAMUX1.bit.GPIO3 =0; 
        GpioCtrlRegs.GPAMUX1.bit.GPIO5 =0; 
 
    GpioCtrlRegs.GPADIR.bit.GPIO2=1; 
    GpioCtrlRegs.GPADIR.bit.GPIO4=1; 
        GpioCtrlRegs.GPADIR.bit.GPIO3=1; 
        GpioCtrlRegs.GPADIR.bit.GPIO5=1; 
 
  EDIS;    
}      
/****************************************************************************************** 
* 函数名称    :write_byte 
******************************************************************************************/ 
void write_byte(Uint16 x) 
{ 
        Uint16 i = 0; 
        SDATA_OUT; 
        SCLK_quarter; 
        for(i=0;i<=7;i++) 
        { 
                SCLK_0; 
                SCLK_quarter; 
                SDATA=(0x1&((x)>>(7-i)));  //先把高位移出然后发送 
                SDATA=(0x1&((x)>>(7-i)));  
                SCLK_quarter; 
                SCLK_1;                    //把时间改成上升沿锁存的 
                SCLK_half; 
                SCLK_0; 
                SCLK_quarter; 
        } 
        SDATA=0; 
} 
 
/*void write_byte(Uint16 x) 
{ 
        Uint16 i = 0; 
        SDATA_OUT; 
        for(i=0;i<=7;i++) 
        { 
                SCLK_0; 
                SCLK_quarter; 
                if((0x1&((x)>>(7-i)))==1) 
                { 
                        GpioDataRegs.GPADAT.all = GpioDataRegs.GPADAT.all|0x04000000;  //GPIO26输出1 
                } 
                else 
                { 
                        GpioDataRegs.GPADAT.all = GpioDataRegs.GPADAT.all&0xFBFFFFFF;  //GPIO26 输出0 
                } 
                SCLK_quarter; 
                SCLK_1;                    //把时间改成上升沿锁存的 
                SCLK_half; 
                SCLK_0; 
                SCLK_quarter; 
        } 
        SDATA=0; 
}         
*/ 
/****************************************************************************************** 
* 函数名称    :read_byte 
******************************************************************************************/ 
Uint16 read_byte(void) 
{ 
        Uint16 i = 0; 
        Uint16 data = 0; 
        SDATA_IN; 
        data=0; 
        for(i=0;i<=7;i++) 
        { 
                SCLK_0; 
                SCLK_quarter; 
                SCLK_1; 
                SCLK_quarter; 
                if(SDATA) 
                { 
                   data= (data|(0x01<<(7-i)));  //注意! 
                } 
                SCLK_quarter; 
                SCLK_0; 
                SCLK_quarter; 
        } 
        return data; 
}         
/****************************************************************************************** 
* 函数名称    :lcd_write_cmd 
******************************************************************************************/ 
void lcd_write_cmd(Uint16 data)   //lcd 命令写  
{ 
        Uint16 tmp1,tmp2; 
        CS_1; 
        delay_loop(40); 
        tmp1= (data&0xF0);           //高四位 
        tmp2= ((data&0x0F)<<4);      //低四位左移  
        write_byte(0xF8); //0xF8 ==11111000 b 这个代表从MCU到LCD 并且是指令 
        write_byte(tmp1);  
        write_byte(tmp2); 
        delay_loop(40); 
        CS_0; 
        execute_72us; 
} 
/****************************************************************************************** 
* 函数名称    :lcd_write_data 
******************************************************************************************/ 
void lcd_write_data(Uint16 data)   
{ 
        Uint16 tmp1,tmp2; 
        CS_1; 
        delay_loop(40); 
        tmp1= (data&0xF0);           //高四位 
        tmp2= ((data&0x0F)<<4);      //低四位左移  
        write_byte(0xFA); //0xFA ==11111010 b 这个代表从MCU到LCD 并且是数据 
        write_byte(tmp1);  
        write_byte(tmp2); 
        delay_loop(40); 
        CS_0; 
        execute_72us; 
} 
/****************************************************************************************** 
* 函数名称    :lcd_read_data 
******************************************************************************************/ 
Uint16 lcd_read_data(void)   
{ 
        Uint16 tmp1,tmp2,data; 
        CS_1; 
        write_byte(0xFE); //0xFA ==11111110 b 这个代表从MCU到LCD 并且是数据 
        tmp1=read_byte();  
        tmp2=read_byte(); 
        CS_0; 
        execute_72us; 
        data= (tmp1&0xF0);                  //高四位 
        data= (data|((tmp2&0xF0)>>4));      //低四位 
        return data; 
} 
/****************************************************************************************** 
* 函数名称    :lcd_set_dot 
******************************************************************************************/ 
void lcd_set_dot(unsigned char x, unsigned char y)  
{  
    unsigned char x_byte, x_bit;        //在横坐标的哪一个字节,哪一个位  
    unsigned char y_byte, y_bit;  
//    unsigned char tmph, tmpl;           //定义两个临时变量,用于存放读出来的数据  
 
    x &= 0x7F;  
    y &= 0x3F;  
    x_byte = x / 16;                    //算出它在哪一个字节(地址)  
                                        //注意一个地址是16位的  
    x_bit = x&0x0F;                     //算出它在哪一个位  
    y_byte = y /32;                     //y是没在哪个字节这个说法  
                                        //这里只是确定它在上半屏还是下半屏  
                                        //0:上半屏 1:下半屏  
    y_bit = y&0x3F;                     //y_bit确定它是在第几行  
 
    lcd_write_cmd(EXTEND_SET);          //扩展指令集  
    lcd_write_cmd(DRAW_ON);            //绘图显示打开  
    lcd_write_cmd(0x80 + y_bit);        //先写垂直地址(最高位必须为1)  
                                        //具体参照数据手册  
    lcd_write_cmd(0x80 + x_byte + 8 * y_byte);   //水平坐标  
                                                 //下半屏的水平坐标起始地址为0x88  
                                                 //(+8*y_byte)就是用来确定  
                                                 //在上半屏还是下半屏  
 
    if (x_bit < 8)                               //绻鹸_bit位∮?  
    {  
        lcd_write_data(0x01 << (7 - x_bit));     //写高字节。因为坐标是从左向右的  
                                                 //而GDRAM高位在左,底位在右 
        lcd_write_data(0x00);                    //低字节全部填0  
 
    }  
    else  
    {  
        lcd_write_data(0x00);                    //高字节全部填0  
 
        lcd_write_data(0x01 << (15 - x_bit));  
 
    }   
 
    return ;  
 
}  
 
//=========================================================================== 
// No more. 
//=========================================================================== 
 
 
 
 |   
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册 
 
 
 
×
 
     
  
 |