基于ATMEGA8515的SPI驱动ST7565P液晶屏的程序(原创)

这是用SPI方式来驱动12864液晶的源程序,液晶屏的控制芯片为ST7565P经测试SPI的时钟可达到振荡频率的二分频。比用普通IO口模拟串行的方式快多了。。。 
下面贴出源代码,有详细注释。。。。 
本程序简单实用,可拿去作简单参考。。。。 
编译环境:GCC+AVR STUDIO 
单片机:ATMEGA 8515 
晶振:   3.6864M 



#include<avr/io.h>        //包含头文件 
#include<avr/pgmspace.h> 

#define   COMMAND    
#define   DATA        

//数据线定义: 
// SI==========PB5  // 
// A0==========PC0 
// CS==========PC2 
// RES=========PC1 
// SCL=========PB7 
// 
unsigned char gushi[8][112]PROGMEM= 
{0x10,0x10,0x92,0x92,0x92,0xF2,0x9E,0x92,0x92,0x92,0x92,0x92,0xFE,0x10,0x10,0x00,  //君问归期未有期 
0x00,0x00,0xF8,0x01,0x06,0xE0,0x22,0x22,0x22,0x22,0xE2,0x02,0x02,0xFE,0x00,0x00, 
0x00,0xF8,0x00,0x00,0xFF,0x00,0x04,0x84,0x84,0x84,0x84,0x84,0x84,0xFC,0x00,0x00, 
0x00,0x04,0xFF,0x54,0x54,0x54,0xFF,0x04,0x00,0xFE,0x22,0x22,0x22,0xFE,0x00,0x00, 
0x40,0x40,0x48,0x48,0x48,0x48,0xC8,0xFF,0x48,0x48,0x48,0x48,0x48,0x40,0x40,0x00, 
0x00,0x04,0x84,0x44,0xE4,0x34,0x2C,0x27,0x24,0x24,0x24,0xE4,0x04,0x04,0x04,0x00, 
0x00,0x04,0xFF,0x54,0x54,0x54,0xFF,0x04,0x00,0xFE,0x22,0x22,0x22,0xFE,0x00,0x00}, 

{0x40,0x20,0x10,0x0C,0xFE,0x45,0x44,0x44,0x44,0x44,0x44,0x44,0xFD,0x00,0x00,0x00, 
0x00,0x00,0xFF,0x00,0x00,0x03,0x02,0x02,0x02,0x02,0x03,0x40,0x80,0x7F,0x00,0x00, 
0x00,0x87,0x40,0x30,0x0F,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3F,0x00,0x00, 
0x42,0x22,0x1B,0x02,0x02,0x0A,0x33,0x62,0x18,0x07,0x02,0x22,0x42,0x3F,0x00,0x00, 
0x20,0x20,0x10,0x10,0x08,0x06,0x01,0xFF,0x01,0x02,0x04,0x08,0x18,0x30,0x10,0x00, 
0x02,0x01,0x00,0x00,0xFF,0x09,0x09,0x09,0x29,0x49,0xC9,0x7F,0x00,0x00,0x00,0x00, 
0x42,0x22,0x1B,0x02,0x02,0x0A,0x33,0x62,0x18,0x07,0x02,0x22,0x42,0x3F,0x00,0x00}, 

{0x00,0x00,0xFE,0x42,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x42,0xFE,0x00,0x00,0x00,    //巴山夜雨涨池 
0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00, 
0x04,0x04,0x84,0xC4,0x3C,0x14,0x85,0x66,0xBC,0x24,0x24,0x24,0xE4,0x24,0x04,0x00, 
0x02,0x02,0xF2,0x32,0x52,0x92,0x12,0xFE,0x32,0x52,0x92,0x12,0xF2,0x02,0x02,0x00, 
0x10,0x61,0x86,0x60,0xF2,0x12,0x12,0x1E,0x80,0xFF,0xA0,0x90,0x88,0x86,0x80,0x00, 
0x24,0x24,0xE4,0xFC,0xA2,0x22,0x22,0x80,0x70,0x00,0xFF,0x40,0x20,0x18,0x00,0x00, 
0x10,0x60,0x02,0x8C,0x60,0x80,0xF8,0x40,0x40,0xFE,0x20,0x20,0x10,0xF0,0x00,0x00}, 

{0x00,0x00,0x3F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x78,0x20,0x00, 
0x00,0x20,0x7F,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x20,0x7F,0x00,0x00, 
0x02,0x01,0x00,0xFF,0x00,0x82,0x41,0x22,0x14,0x09,0x14,0x23,0x40,0xC0,0x40,0x00, 
0x00,0x00,0xFF,0x01,0x02,0x04,0x00,0x7F,0x01,0x02,0x44,0x80,0x7F,0x00,0x00,0x00, 
0x04,0xFC,0x03,0x00,0x01,0x41,0x81,0x7F,0x00,0xFF,0x42,0x0C,0x30,0x60,0x20,0x00, 
0x02,0x01,0x00,0xFF,0x00,0x83,0x40,0x20,0x18,0x07,0x01,0x06,0x18,0xE0,0x40,0x00, 
0x08,0x08,0x7C,0x03,0x00,0x00,0x3F,0x40,0x40,0x5F,0x40,0x42,0x44,0x43,0x70,0x00}, 

{0x80,0x40,0xF0,0x1C,0x07,0xE2,0x24,0x24,0x24,0xE4,0x04,0x04,0xFC,0x04,0x04,0x00,  //何当共剪西窗烛 
0x00,0x00,0x40,0x42,0x5C,0x48,0x40,0x40,0x7F,0x40,0x50,0x4E,0x44,0xC0,0x00,0x00, 
0x00,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x00,0x00, 
0x00,0x04,0xF4,0x54,0x55,0x56,0x54,0xF4,0x04,0x04,0xE6,0x05,0x04,0xF4,0x04,0x00, 
0x02,0xF2,0x12,0x12,0x12,0xFE,0x12,0x12,0x12,0xFE,0x12,0x12,0x12,0xF2,0x02,0x00, 
0x00,0x4C,0x44,0xE4,0x54,0x44,0x64,0xD5,0x46,0x44,0x4C,0x54,0xD4,0x24,0x2C,0x00, 
0x80,0x60,0x00,0xFF,0x20,0x18,0xF0,0x10,0x10,0xFF,0x12,0x10,0xF0,0x10,0x00,0x00}, 

{0x00,0x00,0x7F,0x00,0x00,0x07,0x02,0x02,0x02,0x07,0x20,0x40,0x3F,0x00,0x00,0x00,   
0x00,0x00,0x20,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x7F,0x00,0x00, 
0x02,0x02,0x82,0x42,0x32,0x1F,0x0A,0x02,0x02,0x06,0x0B,0x32,0xE2,0x42,0x02,0x00, 
0x00,0x08,0x8F,0x89,0x49,0x2B,0x1D,0x0B,0x08,0x08,0x08,0x4A,0x8C,0x7B,0x00,0x00, 
0x00,0x7F,0x28,0x24,0x22,0x21,0x20,0x20,0x20,0x21,0x22,0x22,0x22,0x7F,0x00,0x00, 
0x00,0x00,0x00,0xFF,0x44,0x62,0x55,0x49,0x55,0x43,0x41,0x40,0xFF,0x00,0x00,0x00, 
0x40,0x20,0x18,0x07,0x04,0x28,0x63,0x21,0x21,0x3F,0x11,0x15,0x1B,0x30,0x00,0x00}, 

{0x80,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x00,0xFE,0x02,0x02,0x02,0xFE,0x00,0x00,    //却话巴山夜雨时 
0x40,0x41,0x4E,0xC4,0x00,0x20,0x24,0x24,0x24,0x24,0xFC,0x22,0x22,0x22,0x20,0x00, 
0x00,0x00,0xFE,0x42,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x42,0xFE,0x00,0x00,0x00, 
0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00, 
0x04,0x04,0x84,0xC4,0x3C,0x14,0x85,0x66,0xBC,0x24,0x24,0x24,0xE4,0x24,0x04,0x00, 
0x02,0x02,0xF2,0x32,0x52,0x92,0x12,0xFE,0x32,0x52,0x92,0x12,0xF2,0x02,0x02,0x00, 
0x00,0xFC,0x44,0x44,0x44,0xFC,0x10,0x90,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x00}, 

{0x00,0x10,0x3C,0x13,0x10,0x08,0x0A,0x1C,0x08,0xFF,0x00,0x08,0x10,0x0F,0x00,0x00, 
0x00,0x00,0x00,0x7F,0x20,0x10,0x00,0x7E,0x22,0x22,0x23,0x22,0x22,0x7E,0x00,0x00, 
0x00,0x00,0x3F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x78,0x20,0x00, 
0x00,0x20,0x7F,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x20,0x7F,0x00,0x00, 
0x02,0x01,0x00,0xFF,0x00,0x82,0x41,0x22,0x14,0x09,0x14,0x23,0x40,0xC0,0x40,0x00, 
0x00,0x00,0xFF,0x01,0x02,0x04,0x00,0x7F,0x01,0x02,0x44,0x80,0x7F,0x00,0x00,0x00, 
0x00,0x07,0x04,0x04,0x04,0x07,0x00,0x00,0x03,0x40,0x80,0x7F,0x00,0x00,0x00,0x00}, 

}; 
 
//发送一个字节到ST7565P并等待发送完毕 
//入口:要发送的字节 
//返回值:无 
 
void SPIByte(unsigned char byte)    
      SPDR =byte;     //写数据 
      while(!(SPSR &(1<<SPIF)));  //等待发送完成 
 
//将一个字节发送的ST7565P的函数 
//入口参数: select ,data 
//select:根据此值确定发送给ST7565P的是数据还是命令 
//data: 要发送给ST7565的一个字节 
//返回值:无 
 
void LCD_SPISend(unsigned char select,unsigned chardata) 
      PORTC&= ~(1<<2);          // CS=0芯片使能信号 
      if(select == COMMAND)     //传输的是命令 
           
          PORTC &=~(1<<0);     //根据ST7565P的数据手册,传输命令时A0应该是为低电平 
          SPIByte(data);   
          PORTC |=1<<0;             // A0=1    
     
      else 
     
          SPIByte(data); 
     
      PORTC|= 1<<2;       //CS=恢复不使能 
 
//写坐标函数 
//入口参数:x y 
//y:  页面地址,此液晶将显示区域分为9个页面,y的值域0~8 
//x:   列地址,值域:0~127 
//返回值:无 
 
void LCD_XYSet(unsigned char x,unsigned chary) 
      LCD_SPISend(COMMAND,0xB0|y);           //y的值为0~8 
      LCD_SPISend(COMMAND,0x10|(x>>4)); 
      LCD_SPISend(COMMAND,0x00|(x&0x0F)); 
//延时函数 
//入口: ms  当延时100毫秒时,ms的值为100即可 
//返回值:无 
void DelayMs(volatile unsigned int ms) 
    volatile unsigned inti; 
    volatile unsigned intj; 
    for(i=0;i<ms;i++) 
     
          j=280; 
          while(j--); 
     
// 
//初始化SPI及液晶屏的函数 
//入口:无 
//返回值:无 
void LCD_Init(void) 
{    
      SPCR =0x5C;  
      SPSR|= 1<<SPI2X; 
//SPI的功能设置解释:使能SPI;采用主机模式;SPI的传输模式为模式3;时钟频率为系统时钟的两分频,即    //3.6864/2M 
      DelayMs(100); 
      SPIByte(0xFF);         //可发可不发,无意义 
      PORTC&= ~(1<<1);              //将复位脚拉低 
      DelayMs(5);                   //延时5ms,等待电源稳定 
      PORTC|= 1<<1;                   //将复位脚拉高 
      DelayMs(5); 
      LCD_SPISend(COMMAND,0xAE);         //将液晶屏的显示关掉 
      LCD_SPISend(COMMAND,0xA3);         //设置偏压比 
      LCD_SPISend(COMMAND,0xA0);         //设置SEG输出方向 
      LCD_SPISend(COMMAND,0xC8);         //设置公共端输出扫描方向 

      LCD_SPISend(COMMAND,0x25);         //调整 (1 +Rb/Ra) ratio 值,调整此值影响很大 
      LCD_SPISend(COMMAND,0x81);         //开始设置α的命令 
      LCD_SPISend(COMMAND,0x28);         //设置α的值,值越大对比度越强,调整此值影响不太,是微调的
      DelayMs(5); 
      LCD_SPISend(COMMAND,0x2F);         //开启相关电压 
      DelayMs(50);                
      LCD_SPISend(COMMAND,0xAF);         //显示开 
      LCD_SPISend(COMMAND,0xF8);          
      LCD_SPISend(COMMAND,0x01);         //此两条命令是设置升压比的 
    DelayMs(500);                      //不知此延时可否省去,不过了安全起见,初次调试保留为好。。
 
//清屏函数 
//入口:无 
//返回值:无 
/// 
void Clear_Display(void) 
      unsigned char i; 
      unsigned char j; 
      for(i=0;i<8;i++) 
     
              LCD_XYSet(0,i); 
              for(j=0;j<128;j++) 
             
                LCD_SPISend(DATA,0);    //传输数据 
             
     

 
//显示一首李商隐的诗歌: 
//  君问归期未有期 
//  巴山夜雨涨秋池 
//  何当共剪西窗烛 
//  却话巴山夜雨时 
//入口:无 
//返回值:无 
 
void Gushi_Display(void) 
      unsigned char i; 
      unsigned char j; 
      for(i=0;i<8;i++) 
     
          LCD_XYSet(8,i); 
          for(j=0;j<112;j++) 
             
                LCD_SPISend(DATA,__LPM(&gushi[i][j])); 
             
     

int main(void) 
      DDRB =0xFF;       //将IO口配置为输出 
      PORTB= 0xFF;       //让IO口都输出高电平 
      DDRC =0xFF;       //配置为输出 
      PORTC= 0xFF;       //输出高电平 
      DelayMs(1); 
      LCD_Init();         //初始化的函数 
      Clear_Display();     //清屏函数 
      Gushi_Display(); 
      while(1) 
     
     
编译结果如下: 
AVR Memory Usage 
---------------- 
Device: atmega8515 

Program:     1688 bytes(20.6% Full) 
(.text + .data + .bootloader) 

Data:           0 bytes (0.0%Full) 
(.data + .bss + .noinit) 


Build succeeded with 0 Warnings... 

显示效果如下:
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值