123456789 发表于 2024-4-6 00:42:25

WINAVR下液晶3310的驱动

从网址邮购处买到3310的液晶显示。试了一下,感觉很好,屏幕很清晰,很适合自己做点小项目。参考网站上的例子,用WINAVR(2005/02/14) 重新写了一个驱动,贴出来与大家共享。

网站上的例子, 初始化当中有一点DUG,提出来与大家讨论:
1. PB4当作RES的控制脚不妥当,因为在SPI下,PB4只能是输入,作输出控制RES不妥。
http://www.mcuzx.net/data/attachment/forum/month_1005/1005132344ea015d5636e5be06.jpg
2. 屏幕的最上面一行,显示不停滚动的中文:“欢迎光临本网站!” 好像后面还跟一些乱码(不知是否WINAVR的原因)。我在程序中改变了一下,现在正常了。
//NokiaLCD.h

/*********************************************************************************** Name         :NokiaLCD.h Description:Header file for Nokia 84x48 graphic LCD driver. Author       :2005-06-24 - TeSTCode Compiler   :WINAVR Version: 20050214 ************************************************************************************/ #ifndef NOKIALCD_INCLUDED #define NOKIALCD_INCLUDED #include <avr/pgmspace.h>#define LCD_X_RES      (84) #define LCD_Y_RES      (48) #define LCD_Array_SIZE   ((LCD_X_RES * LCD_Y_RES) / 8) #define LCD_DC_PORT   PORTB //LCDµÚ4½Å£¬ Mega32£ºPB1µÚ2½Å #define LCD_DC_DDR   DDRB #define LCD_DC_BIT_NUM (1) #define LCD_CE_PORT   PORTB //LCDµÚ5½Å£¬ Mega32£ºPB0µÚ1½Å #define LCD_CE_DDR   DDRB #define LCD_CE_BIT_NUM (0) #define LCD_RST_PORT   PORTA//LCDµÚ8½Å£¬ Mega32£ºPA2 µÚ3½Å #define LCD_RST_DDR   DDRA #define LCD_RST_BIT_NUM (2) /***************************************************************************** *            SPI Definitions */ #define SPI_PORT PORTB #define SPI_DDR       DDRB //Data direction register #define SPI_PIN       PINB //Port used for SPI #define SPI_SS_NUM (4) //SPI Slave select, must be set as output #define SPI_MOSI_NUM (5) //SPI CPU master output #define SPI_MISO_NUM (6) //SPI CPU master input #define SPI_SCK_NUM(7) //SPI clock, CPU master #define delay_1us()       _delay_us(1) #define delay_1ms()       _delay_ms(1) #ifndef BIT #define BIT(x) (1 << (x)) #endif enum {LCD_CMD= 0, LCD_DATA = 1}; class NokiaLcd{ private: unsigned char LcdRow,LcdCol;void InitLCDSPI(void);public: NokiaLcd(unsigned char mRow = LCD_Y_RES,    unsigned char mCol= LCD_X_RES); void LCD_init(void); void LCD_clear(void); void LCD_set_XY(unsigned char X, unsigned char Y); void LCD_write_string(unsigned char X,unsigned char Y,char *s); void LCD_write_chinese_string(unsigned char X, unsigned char Y,                  unsigned char ch_with,unsigned char num,                  unsigned char line,unsigned char row); void LCD_move_chinese_string(unsigned char X, unsigned char Y, unsigned char T);                  void LCD_write_char(unsigned char c); void LCD_draw_bmp_pixel(unsigned char X,unsigned char Y,PGM_P map,                   unsigned char Pix_x,unsigned char Pix_y);                   void LCD_write_byte(unsigned char data, unsigned char dc);    void delay_nus(unsigned int n); void delay_nms(unsigned int n);            }; #endif ///////////////////////////////////////////////////////////////////////////////// //NokiaLCD.c /**************************************************************************** Name         :NokiaLCD.c Description:This is a driver for the Nokia 84x48 graphic LCD. Author       :2005-06-24 - TeSTCode Compiler   :WINAVR Version: 20050214 *****************************************************************************/ #include <avr/io.h> #include <avr/delay.h> #include "NokiaLCD.h" #include "english_6x8_pixel.h" #include "move_chinese_string_pixel.h" #include "write_chinese_string_pixel.h" NokiaLcd::NokiaLcd(unsigned char mRow, unsigned char mCol) : LcdRow(mRow), LcdCol(mCol) {    InitLCDSPI();    LCD_init(); }/***************************************************************************** * WriteReadSPI: Send character to SPI and return character read back */ void NokiaLcd::InitLCDSPI(void) { //Set SPI ports as output    SPI_DDR |= SPI_DDR|(1<<SPI_SCK_NUM)|(1<<SPI_MOSI_NUM)|(1<<SPI_SS_NUM);    SPI_PORT = SPI_PORT & (~(1<<SPI_MISO_NUM)); //Turn off pull-up /* Enable SPI, Master, set clock rate fck/16 */ SPSR |= (1<<SPI2X);               // ÉèÖÃSPIʱÖÓ±¶ËÙ   SPCR |= (1<<SPE)|(1<<MSTR); // ʹÄÜSPI½Ó¿Ú£¬Ö÷»úģʽ£¬4MʱÖÓ } /*----------------------------------------------------------------------- Name         :LcdInit Description:Performs MCU SPI & LCD controller initialization. -----------------------------------------------------------------------*/ void NokiaLcd::LCD_init(void) {    _delay_ms(30);//30ms power on delay    LCD_DC_DDR |= (1<<LCD_DC_BIT_NUM); //Set DC pin as output    LCD_CE_DDR |= (1<<LCD_CE_BIT_NUM); //Seet Ce pin as output    LCD_RST_DDR |= (1<<LCD_RST_BIT_NUM);//Set reset pin as output          //Toggle display reset pin.   LCD_RST_PORT &= ~(1<<LCD_RST_BIT_NUM);//LCD reset low   delay_1us(); //delay 1us   LCD_RST_PORT |= (1<<LCD_RST_BIT_NUM);            LCD_CE_PORT &= ~(1<<LCD_CE_BIT_NUM);   delay_1us();   LCD_CE_PORT |= (1<<LCD_CE_BIT_NUM);   delay_1us();   LCD_write_byte(0x21, LCD_CMD); // LCD Extended Commands.   LCD_write_byte(0xc8, LCD_CMD); // Set LCD Vop (Contrast).   LCD_write_byte(0x06, LCD_CMD); // Set Temp coefficent.   LCD_write_byte(0x13, LCD_CMD); // LCD bias mode 1:48.   LCD_write_byte(0x20, LCD_CMD); // LCD Standard Commands, Horizontal addressing mode   LCD_clear();            // Lcd clear screen   LCD_write_byte(0x0c, LCD_CMD); // LCD Standard Commands, Horizontal addressing mode         LCD_CE_PORT &= ~(1<<LCD_CE_BIT_NUM);// Deselect Lcd } /*----------------------------------------------------------------------- Name    : LCD Clear Screen Description: LcdClear Screen-----------------------------------------------------------------------*/ void NokiaLcd::LCD_clear(void)   {   unsigned int i;   LCD_write_byte(0x0c, LCD_CMD);   LCD_write_byte(0x80, LCD_CMD);   for (i=0; i<504; i++)       LCD_write_byte(0, LCD_DATA);   } /*----------------------------------------------------------------------- Name         :LCD_set_XY Description: Set Lcd X(Page) Y(Column) position-----------------------------------------------------------------------*/ void NokiaLcd::LCD_set_XY(unsigned char X, unsigned char Y) {   LCD_write_byte(0x40 | Y, LCD_CMD); // column   LCD_write_byte(0x80 | X, LCD_CMD);    // row } /*----------------------------------------------------------------------- Name         :LCD_write_char Description:Display one ASCII character -----------------------------------------------------------------------*/ void NokiaLcd::LCD_write_char(unsigned char c)   {   unsigned char line;   c -= 32; LCD_write_byte(0x00,LCD_DATA);   for (line=0; line<5; line++)       LCD_write_byte(pgm_read_byte(&font6x8), LCD_DATA);   } /*----------------------------------------------------------------------- Name         :LCD_writeString Description:Write English string to Lcd Screen -----------------------------------------------------------------------*/ void NokiaLcd::LCD_write_string(unsigned char X,unsigned char Y,char *s)   {   LCD_set_XY(X,Y);   while (*s)      {   LCD_write_char(*s);   ++s;   }   } /*----------------------------------------------------------------------- Name         :LCD_write_chinese_string Description:Write chinese character string to LCD Screen Argument(s):X, Y -> Coordinate for new cursor position.         ch_with -> Chinese Character width         num-> number of characters to display         line -> start line of the chinese character         row   ->Space lines between each char -----------------------------------------------------------------------*/                         void NokiaLcd::LCD_write_chinese_string(unsigned char X, unsigned char Y,                     unsigned char ch_with,unsigned char num,                  unsigned char line,unsigned char row)   {   unsigned char i,n;          LCD_set_XY(X,Y);                           //ÉèÖóõʼλÖà        for (i=0;i<num;)       {      for (n=0; n<ch_with*2; n++)            //дһ¸öºº×Ö          {             if (n==ch_with)                      //дºº×ÖµÄÏ°벿·Ö            {                LCD_set_XY((X+(ch_with+row)*i),Y+1);               }         LCD_write_byte(pgm_read_byte(&write_chinese_string),LCD_DATA);          }      i++;      LCD_set_XY((X+(ch_with+row)*i),Y);       }   }    /*----------------------------------------------------------------------- Name         :LCD_move_chinese_string Description:move the chinese string line on the screen; Argument(s):X, Y -> Coordinate for new cursor position.               T -> moving speed -----------------------------------------------------------------------*/                         void NokiaLcd::LCD_move_chinese_string (unsigned char X, unsigned char Y, unsigned char T)   {   unsigned char i,n,j=0;   unsigned char buffer_h={0};   unsigned char buffer_l={0};            for (i=0; i<96; i++)       {         buffer_h = pgm_read_byte(&move_chinese_string);         buffer_l = pgm_read_byte(&move_chinese_string);         j++;         if (j==12) j=0;                  for (n=0; n<83; n++)         {            buffer_h=buffer_h;             buffer_l=buffer_l;         }                   LCD_set_XY(X,Y);         for (n=0; n<83; n++)         {            LCD_write_byte(buffer_h,LCD_DATA);         }                   LCD_set_XY(X,Y+1);          for (n=0; n<83; n++)         {            LCD_write_byte(buffer_l,LCD_DATA);         }                  delay_nms(T);       }   } /*----------------------------------------------------------------------- Name         :LCD_draw_bmp_pixel Description:draw a picture on the Lcd screen Argument(s):X, Y -> start position on thelcd screen               map->picture array on the flash               Pix_x   ->picture height (pixes)               Pix_y   ->picture width (pixes) -----------------------------------------------------------------------*/ void NokiaLcd::LCD_draw_bmp_pixel(unsigned char X,unsigned char Y,PGM_P map,                   unsigned char Pix_x,unsigned char Pix_y)            {   unsigned int i,n;   unsigned char row;          if (Pix_y%8==0) row=Pix_y/8;//Cal. the total page numbers       else         row=Pix_y/8+1;          for (n=0;n<row;n++)       {      LCD_set_XY(X,Y);         for(i=0; i<Pix_x; i++)         {             LCD_write_byte(pgm_read_byte( &map), LCD_DATA);         }         Y++;                         //go to next page       }         } /*----------------------------------------------------------------------- Name         :LCD_write_byte Description:Sends data to display controller. Argument(s):data -> Data to be sent               cd   -> Command or data (see/use enum) -----------------------------------------------------------------------*/ void NokiaLcd::LCD_write_byte(unsigned char data, unsigned char command) {   LCD_CE_PORT &= ~(1<<LCD_CE_BIT_NUM); // Enable SPI      if (command == LCD_CMD)// Send command       LCD_DC_PORT &= ~(1<<LCD_DC_BIT_NUM);                  else       LCD_DC_PORT |= (1<<LCD_DC_BIT_NUM);         // Send data   SPDR = data; // Load data to SPDR   while ((SPSR & 0x80) == 0);         // Wait until data sent   LCD_CE_PORT |= (1<<LCD_CE_BIT_NUM); // ¹Ø±ÕLCD } void NokiaLcd::delay_nus(unsigned int n)       //delay n us {    unsigned int i=0;    for (i=0;i<n;i++)    _delay_us(1); }    void NokiaLcd::delay_nms(unsigned int n)       //Delay n ms {    unsigned int i=0;    for (i=0;i<n;i++)    _delay_ms(1); }

http://www.mcuzx.net/data/attachment/forum/month_1005/1005132344b2841f09214763a2.jpg
页: [1]
查看完整版本: WINAVR下液晶3310的驱动