<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

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

        ST7586S的AVR單片機驅動程序

        作者:huqin   來源:本站原創   點擊數:  更新時間:2014年11月22日   【字體:

        AVR 單片機 MEGA64A
        /***************************ST7586S********************************************/

        /************************PE5  --->  /CS ***************************************/
        /************************PG3  --->  RS  ***************************************/
        /************************PG4  --->  /WR ***************************************/
        /************************PA0  --->  /RD ***************************************/
        /********************PF0-PF7  --->  DATA DB0-DB7 ******************************/
        /************************PA1  --->  /RESET ************************************/
        /************************PA2  --->  LED+(H)************************************/   
        #define LCD_COMMAND  0
        //數據
        #define LCD_DATA   1
         
        #define DATA_IO_INIT() {DDRF=0xFF;PORTF=0x00;}
         
        #define LCD_RST_ON() {DDRA|=BIT(1);PORTA&=~BIT(1);}
        #define LCD_RST_OFF() {DDRA|=BIT(1);PORTA|=BIT(1);}
         
        #define LCD_RS_LOW_COMMAND() {DDRG|=BIT(3);PORTG&=~BIT(3);}
        #define LCD_RS_HIGH_DATA() {DDRG|=BIT(3);PORTG|=BIT(3);}
         
        #define LCD_RD_LOW() {DDRA|=BIT(0);PORTA&=~BIT(0);}
        #define LCD_RD_HIGH() {DDRA|=BIT(0);PORTA|=BIT(0);}
         
        #define LCD_WR_LOW() {DDRG|=BIT(4);PORTG&=~BIT(4);}
        #define LCD_WR_HIGH() {DDRG|=BIT(4);PORTG|=BIT(4);}
         
        #define LCD_CS_LOW_ON() {DDRE|=BIT(5);PORTE&=~BIT(5);}
        #define LCD_CS_HIGH_OFF() {DDRE|=BIT(5);PORTE|=BIT(5);}
         
        #define LCD_LED_OFF() {DDRA|=BIT(2);PORTA|=BIT(2);}
        #define LCD_LED_ON() {DDRA|=BIT(2);PORTA&=~BIT(2);}
         
        //ST7586 COMMAND
        #define LCD_NOP 0x00
        #define LCD_RST 0x01 //軟件復位,RAM內容不清
        #define POWER_SAVE_ON 0x10 //0X10,SLEEP,0X11,WAKE UP
        #define POWER_SAVE_OFF 0x11
        #define PARTIAL_DISPLAY_ON 0x12 //0x12,ON,0x13,OFF
        #define PARTIAL_DISPLAY_OFF 0x13
        #define INVERSE_DISPLAY_OFF 0x20 //0x20,正顯,0X21,負顯
        #define INVERSE_DISPLAY_ON 0x21
        #define ALL_PIXEL_ON 0x23 //0x22,off,0X23,on
        #define ALL_PIXEL_OFF 0x22
        #define DISPLAY_ON 0x29
        #define DISPLAY_OFF 0X28
        #define SET_COLUMN_ADDRESS 0x2A //0x2A+XS0000H+XE007FH 0<=XS<=XE<=7F
        #define SET_ROW_ADDRESS 0x2B //0x2B+YS+YE 0<=YS<=YE<=9F
        #define WRITE_DISPLAY_DATA 0x2C
        //#define READ_DISPLAY_DATA 0x2E //串口模式無此功能
        #define PARTIAL_DISPLAY_AREA 0x30 //個參數
        #define SCROLL_AREA 0x33 // TA,SA,BA:0-A0
        #define DISPLAY_CONTROL 0x36 //MY,MX1,MX0
        #define START_LINE 0x37 //0-9F
        #define DISPLAY_MODE 0x38 //四級灰度,39,單色顯示
        #define ENABLE_DDRAM_INTERFACE 0x3A //3AH+02H
        #define DISPLAY_DUTY 0xB0 //B0+9F
        #define FIRST_OUTPUT_COM 0xB1 //B1H+00H
        #define FOSC_DIVIDER 0xB3 //B3H+1;0:不分頻,1:2分頻,2:4分頻,3:8分頻
        #define PARTIAL_DISPLAY 0xB4 //B4+A0,在局部顯示區域設置之前寫入
        #define SET_VOP 0xC0 //+42H+01H
        #define VOP_INCREASE 0xC1
        #define VOP_DECREASE 0xC2
        #define BIAS_SYSYTEM 0xC3  //C3+04;1/10
        #define BOOSTER_LEVEL 0xC4 //C4+07
        #define VOP_OFFSET 0xC7 //C7+1
        #define ANALOG_CONTROL 0xD0 //D0+1D
        #define FRAME_RATE 0xF0 //F0+06+0B+0D+12H
        /****************************取模方式******************************************/
        /******點陣格式--陰碼,列行式,取模走向為逆向**********************************/
        //舉一個例子,顯示0,像素16*24,顯示的有效數據的位數一定是要3的倍數
        //16*24,寬度是2個字節16位,但是傳輸給LCD顯示時,一定要補2位,是16+2=18
        /*************************************16*24*************************************/
        const unsigned char Image_0[]=
        {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x0E,0xE0,0x1C,0x70,
        0x1C,0x70,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
        0x38,0x38,0x1C,0x70,0x1C,0x70,0x0E,0xE0,0x07,0xC0,0x00,0x00,0x00,0x00,0x00,0x00};/*0*/  

        /*******************************LCD寫命令**********************************/
        void LCD_Cmd_Write(unsigned char cmd)
           {
               LCD_RS_LOW_COMMAND();
          LCD_RD_HIGH();
               /*LCD_ChkBusy();*/         //Call LCD_ChkBusy to Check Busy Bit
          LCD_WR_LOW();
          NOP();
          NOP();
          DDRF = 0xFF;
          PORTF = cmd;
               LCD_CS_LOW_ON();
          NOP();
          NOP();
               LCD_WR_HIGH();
              Some_NOP(3);
          LCD_CS_HIGH_OFF();
           }

        /*****************************LCD寫數據**********************************/
        void LCD_Data_Write(unsigned char data)
           {
              /*LCD_ChkBusy(); */      //Call LCD_ChkBusy to Check Busy Bit
              DDRF = 0xFF;
         LCD_RS_HIGH_DATA();
         LCD_RD_HIGH();
              PORTF = data;
         LCD_WR_LOW();
         NOP();
         NOP();
         LCD_CS_LOW_ON();     
              NOP()
         NOP();
              LCD_WR_HIGH();
              Some_NOP(3);
              LCD_CS_HIGH_OFF();
           }  
        /***********************LCD讀數據*******************************/
        unsigned char LCD_Data_Read(void)
           {
               unsigned char data_m=0;
               DDRF = 0x00;  //讀出
               LCD_RS_HIGH_DATA();
               LCD_RD_HIGH(); 
          LCD_WR_LOW();
          NOP();
          NOP();                    
               LCD_CS_LOW_ON();
          NOP();
          NOP();
               LCD_WR_HIGH();
               NOP();
               NOP();
              LCD_RD_LOW();
              NOP();
              NOP();
              data_m = PINF;
              LCD_RD_HIGH();
            NOP();
              NOP();
              return data_m;
           }
        /*********0<XS<XE<7F,0<YS<YE<9F************/
        //LCD_Clear_RAM(0,127,0,159);//x-y
        void LCD_Clear_RAM(uchar xs,uchar xe,uchar ys,uchar ye)
           {
               uchar x,y;
          LCD_Cmd_Write(SET_COLUMN_ADDRESS);
          LCD_Data_Write(0x00);
          LCD_Data_Write(xs);
          LCD_Data_Write(0x00);
          LCD_Data_Write(xe);
          
          LCD_Cmd_Write(SET_ROW_ADDRESS);
          LCD_Data_Write(0x00);
          LCD_Data_Write(ys);
          LCD_Data_Write(0x00);
          LCD_Data_Write(ye);
          
          LCD_Cmd_Write(WRITE_DISPLAY_DATA);
          for(y=ys;y<=ye;y++)
           {
           for(x=xs;x<=xe;x++)
        {
            LCD_Data_Write(0x00);
        }
        }   
           }  
        //========================================================
        // 畫圖函數
        //========================================================
        void Image_Disp(uchar x,uchar y,uchar width,uchar high,const uchar *pstr)
        // 坐標(x,y),x為水平方向字符位(1個字符位占3個像素點);y為垂直方向像素行;
        // width:圖片寬度,按照水平方向像素點計算;high:為圖片高度,按照像素點計算,*pstr 圖片數組名
           {
          uchar i,j,k,data,temp;
          LCD_Cmd_Write(0x2a); // Column Address Setting
          LCD_Data_Write(0x00); // 
          LCD_Data_Write(x); // 
          LCD_Data_Write(0x00);
          LCD_Data_Write((width/3)+x-1); //
          LCD_Cmd_Write(0x2b); // Row Address Setting
          LCD_Data_Write(0x00); // 
          LCD_Data_Write(y);
          LCD_Data_Write(0x00);
          LCD_Data_Write(y+high-1);
          LCD_Cmd_Write(0x2c);
          for(i=0;i<high;i++)
           {
               for(j=0;j<width;j=j+24)
                {
                    data = *pstr++;
        for(k=0;k<2;k++)
           {
               temp = data&0xe0;
           LCD_Data_Write(LCD_Change_Tab[temp>>5]);
                     data = data<<3;
                   }
            data = data + ((*pstr)>>2); 
                for(k=0;k<2;k++)
                 {
                     temp = data&0xe0;
           LCD_Data_Write(LCD_Change_Tab[temp>>5]);
                     data = data<<3;
                   }
          data = data + (((*pstr++)&0x03)<<4);  
                 data = data +((*pstr)>>4);
         for(k=0;k<2;k++)
              {
                    temp = data&0xe0;
              LCD_Data_Write(LCD_Change_Tab[temp>>5]);
                        data = data<<3;
                        }
                                     data = data +(((*pstr++)&0x0f)<<2);
                     for(k=0;k<2;k++)
                      {
                          temp = data&0xe0;
                          LCD_Data_Write(LCD_Change_Tab[temp>>5]);
                                          data = data<<3;
                        }
                            }
           }
            }    

        void Image18_Disp(uchar x,uchar y,uchar width,uchar high,const uchar *pstr)
        // 坐標(x,y),x為水平方向字符位(1個字符位占3個像素點);y為垂直方向像素行;
        // width:圖片寬度,按照水平方向像素點計算;high:為圖片高度,按照像素點計算,*pstr 圖片數組名
           {
          uchar i,j,k,data,temp;
          LCD_Cmd_Write(0x2a); // Column Address Setting
          LCD_Data_Write(0x00); // 
          LCD_Data_Write(x); // 
          LCD_Data_Write(0x00);
          LCD_Data_Write((width/3)+x-1); //
          LCD_Cmd_Write(0x2b); // Row Address Setting
          LCD_Data_Write(0x00); // 
          LCD_Data_Write(y);
          LCD_Data_Write(0x00);
          LCD_Data_Write(y+high-1);
          LCD_Cmd_Write(0x2c);
          for(i=0;i<high;i++)
           {
                    data = *pstr++;
        for(k=0;k<2;k++)
           {
               temp = data&0xe0;
           LCD_Data_Write(LCD_Change_Tab[temp>>5]);
                     data = data<<3;
                   }
         
            data = data + ((*pstr)>>2); 
                for(k=0;k<2;k++)
                 {
                     temp = data&0xe0;
           LCD_Data_Write(LCD_Change_Tab[temp>>5]);
                     data = data<<3;
                   }
         
        data = data + (((*pstr++)&0x03)<<4);//指針
                for(k=0;k<2;k++)
                 {
                     temp = data&0xe0;
           LCD_Data_Write(LCD_Change_Tab[temp>>5]);
                     data = data<<3;
                   } 
             }
            }   
        void Image8_Disp(uchar x,uchar y,uchar width,uchar high,const uchar *pstr)
        // 坐標(x,y),x為水平方向字符位(1個字符位占3個像素點);y為垂直方向像素行;
        // width:圖片寬度,按照水平方向像素點計算;high:為圖片高度,按照像素點計算,*pstr 圖片數組名
           {
          uchar i,j,k,data,temp;
          LCD_Cmd_Write(0x2a); // Column Address Setting
          LCD_Data_Write(0x00); // 
          LCD_Data_Write(x); // 
          LCD_Data_Write(0x00);
          LCD_Data_Write((width/3)+x-1); //
          LCD_Cmd_Write(0x2b); // Row Address Setting
          LCD_Data_Write(0x00); // 
          LCD_Data_Write(y);
          LCD_Data_Write(0x00);
          LCD_Data_Write(y+high-1);
          LCD_Cmd_Write(0x2c);
          for(i=0;i<high;i++)
           {
                    data = *pstr++;
        for(k=0;k<3;k++)
           {
               temp = data&0xe0;
           LCD_Data_Write(LCD_Change_Tab[temp>>5]);
                     data = data<<3;
                   }
             }
            }

        /**********************LCD復位程序********************/
        void LCD_Reset(void )
        {
        LCD_RST_OFF();
        Delay_us(20);
        LCD_RST_ON();
        Delay_us(50);
        LCD_RST_OFF();
        Delay_us(20);


        /*************************LCD初始化***********************/
        void LCD_Init(void)
        {
        LCD_Reset();
        Delay_ms(10);
        LCD_Cmd_Write(POWER_SAVE_OFF);//wake up
        Delay_ms(10);
        LCD_Cmd_Write(0xd7); // Disable Auto Read
        LCD_Data_Write(0x9F);
        LCD_Cmd_Write(0xe0);// Enable OTP Read
        LCD_Data_Write(0x00);
        Delay_ms(10);
        LCD_Cmd_Write(0xe3); // OTP Up-Load
        Delay_ms(20);
        LCD_Cmd_Write(0xe1); // OTP Control Out
        // initail set
        LCD_Cmd_Write(0x11); // Sleep Out
        LCD_Cmd_Write(0x28); // Display OFF Delay_ms(50);
        LCD_Cmd_Write(0xc0); // Vop = B9h
        LCD_Data_Write(0x1f); // contrast value
        LCD_Data_Write(0x01); // 01
        LCD_Cmd_Write(0xc3); // BIAS
        LCD_Data_Write(0x02); // 05 = 1/12
        LCD_Cmd_Write(0xc4); // Booster = x8
        LCD_Data_Write(0x07);
        LCD_Cmd_Write(0xd0); // Enable Analog Circuit
        LCD_Data_Write(0x1d);
        LCD_Cmd_Write(0xb5); // N-Line = 13
        LCD_Data_Write(0x8d); //8d
        LCD_Cmd_Write(0x38); // 4 Gray
        // SdCmd(0x39); // B/W Mode
        LCD_Cmd_Write(0x3a); // Enable DDRAM Interface
        LCD_Data_Write(0x02);
        LCD_Cmd_Write(0x36); // Dispaly Control
        LCD_Data_Write(0xc8); // MY=1,MX[1:0]=11;
        LCD_Cmd_Write(0xb0); // Duty Setting
        LCD_Data_Write(0x9f); // 160 line 9f
        LCD_Cmd_Write(0x20); // Display Inversion OFF
        LCD_Cmd_Write(0xb1); // First COM out
        LCD_Data_Write(0x00); // com0
        LCD_Clear_RAM(0,127,0,159);
        LCD_Cmd_Write(0x29); // Display ON
        }

         
        實際調試時一開始使用的是電源發生器的,5V標準的電壓,當時沒發現陰影,LCD是3.3V的,實際線路板上電壓大概是5.06V,結果背景就開始有陰影了,后來重新外加弄了塊5V轉3.3V的轉接線路板。

        其中DIR的電平可以單獨再用一個I/O口去控制,不過一般實際使用時基本上都是WRITE LCD的,READ LCD RAM很少,如無READ指令的話,DIR可以直接接高電平。
         
        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮