#include <mega48.h>       
#include <delay.h>       
#include <nokia3310.h>        
void main(void)       
{         
  PORTB&=209;       
  DDRB|=46;                         //设置单片机的4个LCD引脚输出0        
  while(1)        
       {         
         lcd_init();                //lcd初始化                
         lcd_cls();                 //清屏,光标回位       
         lcd_gotoxy(16,2);          //光标定位到第16列,第1行(最上面是0行)        
         lcd_putsf("NOKIA3310",9);  //显示Flash里面的字符串,共9个        
         lcd_gotoxy(38,4);       
         lcd_putchar(’O’);          //显示英文字母大写O       
         lcd_putchar(75);           //数字75的的ASCII字符是英文字母大写K  
         delay_ms(1000);       
       }       
}  
//下面是 <nokia3310.h> 文件内容        
/*************************************************************        
使用者只需把这个nokia3310.h的文件复制到工程目录即可        
使用nokia3310库函数时,请先定义3310与MCU的连接        
本例子3310LCD与单片机的连接如下        
RESET   PB1        
D/C     PB2        
SDIN    PB3        
SCLK    PB5        
SCE     GND                                           
英文字库,5*8点阵,每一个字符占用5个字节,共94个可显示字符数据**/           
                                     
#define RESET PORTB.1           //RESET=0时,LCD复位        
#define DC    PORTB.2           //DC=0_指令,DC=1_数据          
#define SDIN  PORTB.3        
#define SCLK  PORTB.5             
//#define www.avrdiy.com Panxiaoyi  
flash unsigned char data[]={             
0x00, 0x00, 0x00, 0x00, 0x00,   // sp        
0x00, 0x00, 0x2f, 0x00, 0x00,   // !        
0x00, 0x07, 0x00, 0x07, 0x00,   // "        
0x14, 0x7f, 0x14, 0x7f, 0x14,   // #        
0x24, 0x2a, 0x7f, 0x2a, 0x12,   // $        
0x62, 0x64, 0x08, 0x13, 0x23,   // %        
0x36, 0x49, 0x55, 0x22, 0x50,   // &        
0x00, 0x05, 0x03, 0x00, 0x00,   // ’        
0x00, 0x1c, 0x22, 0x41, 0x00,   // (        
0x00, 0x41, 0x22, 0x1c, 0x00,   // )        
0x14, 0x08, 0x3E, 0x08, 0x14,   // *        
0x08, 0x08, 0x3E, 0x08, 0x08,   // +        
0x00, 0x00, 0xA0, 0x60, 0x00,   // ,        
0x08, 0x08, 0x08, 0x08, 0x08,   // -        
0x00, 0x60, 0x60, 0x00, 0x00,   // .        
0x20, 0x10, 0x08, 0x04, 0x02,   // /        
0x3E, 0x51, 0x49, 0x45, 0x3E,   // 0        
0x00, 0x42, 0x7F, 0x40, 0x00,   // 1        
0x42, 0x61, 0x51, 0x49, 0x46,   // 2        
0x21, 0x41, 0x45, 0x4B, 0x31,   // 3        
0x18, 0x14, 0x12, 0x7F, 0x10,   // 4        
0x27, 0x45, 0x45, 0x45, 0x39,   // 5        
0x3C, 0x4A, 0x49, 0x49, 0x30,   // 6        
0x01, 0x71, 0x09, 0x05, 0x03,   // 7        
0x36, 0x49, 0x49, 0x49, 0x36,   // 8        
0x06, 0x49, 0x49, 0x29, 0x1E,   // 9        
0x00, 0x36, 0x36, 0x00, 0x00,   // :        
0x00, 0x56, 0x36, 0x00, 0x00,   // ;        
0x08, 0x14, 0x22, 0x41, 0x00,   // <        
0x14, 0x14, 0x14, 0x14, 0x14,   // =        
0x00, 0x41, 0x22, 0x14, 0x08,   // >        
0x02, 0x01, 0x51, 0x09, 0x06,   // ?        
0x32, 0x49, 0x59, 0x51, 0x3E,   // @        
0x7C, 0x12, 0x11, 0x12, 0x7C,   // A        
0x7F, 0x49, 0x49, 0x49, 0x36,   // B        
0x3E, 0x41, 0x41, 0x41, 0x22,   // C        
0x7F, 0x41, 0x41, 0x22, 0x1C,   // D        
0x7F, 0x49, 0x49, 0x49, 0x41,   // E        
0x7F, 0x09, 0x09, 0x09, 0x01,   // F        
0x3E, 0x41, 0x49, 0x49, 0x7A,   // G        
0x7F, 0x08, 0x08, 0x08, 0x7F,   // H        
0x00, 0x41, 0x7F, 0x41, 0x00,   // I        
0x20, 0x40, 0x41, 0x3F, 0x01,   // J        
0x7F, 0x08, 0x14, 0x22, 0x41,   // K        
0x7F, 0x40, 0x40, 0x40, 0x40,   // L        
0x7F, 0x02, 0x0C, 0x02, 0x7F,   // M        
0x7F, 0x04, 0x08, 0x10, 0x7F,   // N        
0x3E, 0x41, 0x41, 0x41, 0x3E,   // O        
0x7F, 0x09, 0x09, 0x09, 0x06,   // P        
0x3E, 0x41, 0x51, 0x21, 0x5E,   // Q        
0x7F, 0x09, 0x19, 0x29, 0x46,   // R        
0x46, 0x49, 0x49, 0x49, 0x31,   // S        
0x01, 0x01, 0x7F, 0x01, 0x01,   // T        
0x3F, 0x40, 0x40, 0x40, 0x3F,   // U        
0x1F, 0x20, 0x40, 0x20, 0x1F,   // V        
0x3F, 0x40, 0x38, 0x40, 0x3F,   // W        
0x63, 0x14, 0x08, 0x14, 0x63,   // X        
0x07, 0x08, 0x70, 0x08, 0x07,   // Y        
0x61, 0x51, 0x49, 0x45, 0x43,   // Z        
0x00, 0x7F, 0x41, 0x41, 0x00,   // [        
0x55, 0x2A, 0x55, 0x2A, 0x55,   // 55        
0x00, 0x41, 0x41, 0x7F, 0x00,   // ]        
0x04, 0x02, 0x01, 0x02, 0x04,   // ^        
0x40, 0x40, 0x40, 0x40, 0x40,   // _        
0x00, 0x01, 0x02, 0x04, 0x00,   // ’        
0x20, 0x54, 0x54, 0x54, 0x78,   // a        
0x7F, 0x48, 0x44, 0x44, 0x38,   // b        
0x38, 0x44, 0x44, 0x44, 0x20,   // c        
0x38, 0x44, 0x44, 0x48, 0x7F,   // d        
0x38, 0x54, 0x54, 0x54, 0x18,   // e        
0x08, 0x7E, 0x09, 0x01, 0x02,   // f        
0x18, 0xA4, 0xA4, 0xA4, 0x7C,   // g        
0x7F, 0x08, 0x04, 0x04, 0x78,   // h        
0x00, 0x44, 0x7D, 0x40, 0x00,   // i        
0x40, 0x80, 0x84, 0x7D, 0x00,   // j        
0x7F, 0x10, 0x28, 0x44, 0x00,   // k        
0x00, 0x41, 0x7F, 0x40, 0x00,   // l        
0x7C, 0x04, 0x18, 0x04, 0x78,   // m        
0x7C, 0x08, 0x04, 0x04, 0x78,   // n        
0x38, 0x44, 0x44, 0x44, 0x38,   // o        
0xFC, 0x24, 0x24, 0x24, 0x18,   // p        
0x18, 0x24, 0x24, 0x18, 0xFC,   // q        
0x7C, 0x08, 0x04, 0x04, 0x08,   // r        
0x48, 0x54, 0x54, 0x54, 0x20,   // s        
0x04, 0x3F, 0x44, 0x40, 0x20,   // t        
0x3C, 0x40, 0x40, 0x20, 0x7C,   // u        
0x1C, 0x20, 0x40, 0x20, 0x1C,   // v        
0x3C, 0x40, 0x30, 0x40, 0x3C,   // w        
0x44, 0x28, 0x10, 0x28, 0x44,   // x        
0x1C, 0xA0, 0xA0, 0xA0, 0x7C,   // y        
0x44, 0x64, 0x54, 0x4C, 0x44,   // z        
0x00, 0x08, 0x36, 0x41, 0x00,   // {        
0x00, 0x00, 0x7F, 0x00, 0x00,   // |        
0x00, 0x41, 0x36, 0x08, 0x00,   // }        
0x08, 0x10, 0x08, 0x04, 0x08    // ~        
};        
//=======================================================================================        
void lcd_write(unsigned char byte)        //写LCD函数,模拟SPI通信    
{      
  unsigned char i;                        //先写数据的高位,后写低位    
  for(i=128;i>0;i>>=1)      
     {       
       if( byte & i ) SDIN=1; else SDIN=0;      
       SCLK=0; SCLK=1;       
     }      
}       
/*上面的是模拟SPI发送数据函数,下面的是硬件SPI发送数据函数        
void lcd_write(unsigned char data)        
{         
  SPCR=80;        
  SPDR=data;                              //开始发送数据        
  while((SPSR>>7)==0);                    //等待发送接收结束        
}        */        
//=======================================================================================        
void lcd_cls(void)                        //nokia3310清屏,光标复位        
{        
  unsigned int  i=0;         
  DC=0;        
  lcd_write(128);                         //光标回到0列        
  lcd_write(64);                          //光标回到0行        
  DC=1;                                   //准备写数据        
  for(i=0;i<504;i++)                      //写504个0数据,就是清屏        
  lcd_write(0);        
}         
//=======================================================================================        
                
void lcd_init(void)                       //nokia3310初始化函数        
{         
  RESET=0;            
  RESET=1;                                //复位结束        
  DC=0;                                   //准备写指令        
  lcd_write(32+1);                        //进入扩展指令      
  lcd_write(128+38);                      //设置Vop,相当于亮度         
  lcd_write(4+3);                         //设置温度系数,相当于对比度          
  lcd_write(16+3);                        //设置偏置,这句要与不要的实际效果好像一样      
  lcd_write(32+0);                        //进入基本指令      
  lcd_write(12);                          //使能芯片活动/垂直寻址      
}         
//=======================================================================================        
//光标定位,x(0-83)是列地址,y(0-5)是行地址            
void lcd_gotoxy(unsigned char x,unsigned char y)        
{        
  DC=0;        
  lcd_write(x+128);        
  lcd_write(y+64);        
}        
//=======================================================================================        
            
void lcd_putchar(unsigned char character) //显示ASCII值的字符        
{        
  unsigned char i=0;        
  unsigned int No;        
  No=character-32;                        //字模数据是由空格开始,空格字符的ASCII的值就是32        
  No=No*5;                                //每个字符的字模是5个字节        
  DC=1;         
  while(i<5)                              //一个字符的字模是5个字节,就是5*8点阵        
     {        
       lcd_write(data[No]);          
       i++;        
       No++;        
     }        
  lcd_write(0);                           //每个字符之间空一列        
}          
//=====================================================================================        
void lcd_putsf(flash unsigned char *string , unsigned char n) //显示FLASH里面的字符串        
{                
  unsigned char i=0;        
  while(i<n)        
       {          
         lcd_putchar( string[i] );        //顺序显示字符        
         i++;                                 
       }        
}