ST7565點陣LCD的驅動程序(附實例代碼, AVR Studio + winavr)
本例使用AVR的ATmega128做的LCD顯示實例,稍加修改可以用於其它的單片機。
LCD為使用ST7565芯片的128*64的圖形點陣,這裡使用串行方式,直接用單片機的SPI控制。
/********************************************************************************************************
File Name : LCD_ST7565.c
*********************************************************************************************************/
// Include Files
#include "config.h"
#include "LCD_Font.h"
void LCD_WriteData(uint8 Data)
{
LCD_CS_OUT(0);
LCD_A0_OUT(1);
spi_write(Data);
LCD_CS_OUT(1);
}
void LCD_WriteCMD(uint8 CMD)
{
LCD_CS_OUT(0);
LCD_A0_OUT(0);
spi_write(CMD);
LCD_CS_OUT(1);
}
void LCD_DisplayOnOff(uint8 On)
{
On &= 0x01;
LCD_WriteCMD(0xAE | On);
}
void LCD_PowerControl(uint8 Power)
{
Power &= 0x07;
LCD_WriteCMD(0x28 | Power);
}
void LCD_SetStartLine(uint8 LineStart)
{
LineStart &= 0x3F;
LCD_WriteCMD(0x40 | LineStart);
}
void LCD_SetPageAddress(uint8 Page)
{
Page &= 0x0F;
LCD_WriteCMD(0xB0 | Page);
}
void LCD_SetColumnAddress(uint8 Column)
{
LCD_WriteCMD(0x10 | (Column>>4));
LCD_WriteCMD(Column & 0x0F);
}
void LCD_SetV0_Voltage_Regulator(uint8 Ratio)
{
Ratio &= 0x07;
LCD_WriteCMD(0x20 | Ratio);
}
// Electronic Volume Setting
void LCD_SetElectronicVolume(uint8 Volume)
{
Volume &= 0x3F;
LCD_WriteCMD(0x81);
LCD_WriteCMD(Volume);
}
void LCD_Init(void)
{
LCD_DDR |= BIT(LCD_CS) | BIT(LCD_A0) | BIT(LCD_RST) | BIT(LCD_BACKLIGHT);
LCD_RST_OUT(0);
_delay_us(50);
LCD_RST_OUT(1);
_delay_us(1000);
LCD_BackLightOn();
// LCD Bias Setting
LCD_WriteCMD(0xA2); // LCD Bias Set: 1/9 bias
//LCD_WriteCMD(0xA3); // LCD Bias Set: 1/7 bias
_delay_us(50);
// LCD ADC Setting
//LCD_WriteCMD(0xA0); // Set ADC 0: Noraml
LCD_WriteCMD(0xA1); // Set ADC 0: Reverse
_delay_us(50);
// Common Output Setting
LCD_WriteCMD(0xC0); // Normal : COM0~COM63
//LCD_WriteCMD(0xC8); // Reverse : COM63~COM0
_delay_us(50);
// V5 Output Voltage
LCD_SetV0_Voltage_Regulator(0x04);
_delay_us(50);
// Electronic volume control
LCD_SetElectronicVolume(0x20);
_delay_us(100);
LCD_WriteCMD(0xA4); // Display Normal
//LCD_WriteCMD(0xA5); // All point On
_delay_us(50);
//LCD_WriteCMD(0xA6); // Display Normal
LCD_WriteCMD(0xA7); // Display Reverse
_delay_us(50);
LCD_WriteCMD(0xAC);
LCD_WriteCMD(0x00);
_delay_us(50);
LCD_PowerControl(0x07);
LCD_DisplayOnOff(1);
LCD_SetStartLine(0x00);
}
//-----------------------------------------------------------------------------
// LCD:Clear picture.
//-----------------------------------------------------------------------------
void LCD_CLR(uint8 Data)
{
uint8 adrPage, adrLaw;
for(adrPage = 0; adrPage < MAX_PAGE; adrPage++)
{
LCD_SetPageAddress(adrPage);
LCD_SetColumnAddress(0);
for(adrLaw = 0; adrLaw < MAX_COLUMN; adrLaw++)
{
LCD_WriteData(Data);
}
}
}
//-----------------------------------------------------------------------------
// LCD : Display Chinese.
// Size: 16x16
//-----------------------------------------------------------------------------
uint8 LCD_DisplayHZ(char* XH_HZ, uint8 adrPage, uint8 adrColumn)
{
uint8 *dptr; // dptr_adderss for HZ code.
uint8 i, j;
char charH, charL;
charH = *XH_HZ++;
charL = *XH_HZ;
for(j=0; j<sizeof(HZ_Table)/sizeof(HZ_t); j++)
{
dptr = &HZ_Table[j].Hz_Data[0];
if(charH == pgm_read_byte(dptr) && charL == pgm_read_byte(dptr+1))
break;
}
if(j<sizeof(HZ_Table)/sizeof(HZ_t))
dptr = HZ_Table[j].Table;
else
return FALSE;
LCD_SetPageAddress(adrPage);
LCD_SetColumnAddress(adrColumn);
for(i=0; i< 16; i++)
{
LCD_WriteData(pgm_read_byte(dptr));
dptr ++;
}
LCD_SetPageAddress(adrPage+1);
LCD_SetColumnAddress(adrColumn);
for(i=0; i< 16; i++)
{
LCD_WriteData(pgm_read_byte(dptr));
dptr ++;
}
return TRUE;
}
//-----------------------------------------------------------------------------
// LCD : lcd Display ASCII.
// Size : 8X16
//-----------------------------------------------------------------------------
void LCD_DisplayASCII(uint8 XH_Dig, uint8 adrPage, uint8 adrColumn)
{
uint8 *dptr; // dptr_adderss for Dig code.
uint8 i;
if(XH_Dig < 0x20) XH_Dig = 0x20;
dptr = &ASCII[(XH_Dig-0x20)*16];
LCD_SetPageAddress(adrPage);
LCD_SetColumnAddress(adrColumn);
for(i=0; i< 8; i++)
{
LCD_WriteData(pgm_read_byte(dptr));
dptr = dptr + 1;
}
LCD_SetPageAddress(adrPage+1);
LCD_SetColumnAddress(adrColumn);
for(i=0; i< 8; i++)
{
LCD_WriteData(pgm_read_byte(dptr));
dptr = dptr + 1;
}
}
//-----------------------------------------------------------------------------
// LCD : lcd Display String.
// ASCII(8*16) 摯犖趼(16*16) 珆尨滲杅
//-----------------------------------------------------------------------------
uint8 LCD_DisplayString(char *String, uint8 adrPage, uint8 adrColumn)
{
char cData[2];
uint8 uLen,uPage,uCol;
uLen = strlen(String);
uPage = adrPage;
uCol = adrColumn;
while(uLen)
{
cData[0] = *String++;
if(cData[0] <= 0x80)
{
LCD_DisplayASCII(cData[0], uPage, uCol);
uCol += 8;
uLen --;
}
else
{
cData[1] = *String++;
LCD_DisplayHZ(cData, uPage, uCol);
uCol += 16;
uLen -= 2;
}
if(uCol >= MAX_COLUMN)
{
uCol = 0;
uPage += 2;
if(uPage >= MAX_PAGE)
uPage = 0;
}
}
return uLen;
}
//-----------------------------------------------------------------------
// LCD_DisplayPicture
// Picture Size: Hight*Weight
//-----------------------------------------------------------------------
uint8 LCD_DisplayPicture(char *Picture, uint8 adrPage, uint8 adrColumn,
uint8 Weight, uint8 Hight)
{
uint8 *dptr; // dptr_adderss for Dig code.
uint8 i, j;
if((adrPage+Hight)>MAX_PAGE) return FALSE;
if((adrColumn+Weight)>MAX_COLUMN) return FALSE;
dptr = (uint8 *)Picture;
for(i=0; i<Hight; i++)
{
LCD_SetPageAddress(adrPage+i);
LCD_SetColumnAddress(adrColumn);
for(j=0; j<Weight; j++)
{
LCD_WriteData(pgm_read_byte(dptr));
}
}
return TRUE;
}
/********************************************************************************************************
File Name : LCD_ST7565.h
*********************************************************************************************************/
#ifndef LCD_ST7565_H
#define LCD_ST7565_H
#define MAX_LINE 64
#define MAX_COLUMN 128
#define MAX_PAGE (MAX_LINE/8)
#define EN_FONT0816 1
// LCD Control Port Define
#define LCD_PORT PORTB
#define LCD_DDR DDRB
#define LCD_CS PORT6
#define LCD_A0 PORT4
#define LCD_RST PORT5
#define LCD_BACKLIGHT PORT7
#define LCD_CS_OUT(en) (LCD_PORT = (LCD_PORT & ~ BIT(LCD_CS)) | ((en & 1) * BIT(LCD_CS)))
#define LCD_A0_OUT(en) (LCD_PORT = (LCD_PORT & ~ BIT(LCD_A0)) | ((en & 1) * BIT(LCD_A0)))
#define LCD_RST_OUT(en) (LCD_PORT = (LCD_PORT & ~ BIT(LCD_RST)) | ((en & 1) * BIT(LCD_RST)))
#define LCD_BackLightOn() (LCD_PORT |= BIT(LCD_BACKLIGHT))
#define LCD_BackLightOff() (LCD_PORT &= ~BIT(LCD_BACKLIGHT))
extern void LCD_Init(void);
extern void LCD_CLR(uint8 Data);
//-----------------------------------------------------------------------------
// LCD : Display Chinese.
// Size: 16x16
//-----------------------------------------------------------------------------
extern uint8 LCD_DisplayHZ(char* XH_HZ, uint8 adrPage, uint8 adrColumn);
//-----------------------------------------------------------------------------
// LCD : lcd Display ASCII.
// Size : 8X16
//-----------------------------------------------------------------------------
extern void LCD_DisplayASCII(uint8 XH_Dig, uint8 adrPage, uint8 adrColumn);
//-----------------------------------------------------------------------------
// LCD : lcd Display String.
// ASCII(8*16) 摯犖趼(16*16) 珆尨滲杅
//-----------------------------------------------------------------------------
extern uint8 LCD_DisplayString(char *String, uint8 adrPage, uint8 adrColumn);
//-----------------------------------------------------------------------
// LCD_DisplayPicture
// Picture Size: Hight*Weight
//-----------------------------------------------------------------------
extern uint8 LCD_DisplayPicture(char *Picture, uint8 adrPage, uint8 adrColumn,
uint8 Weight, uint8 Hight);
#endif
/********************************************************************************************************
File Name : main.c
*********************************************************************************************************/
#include "config.h"
SysFlag_t SysFlag;
uint8 KeyValue;
char Hz[] = "LCD Test Prog";
int main(void)
{
init_devices();
Delay_10ms(10);
LCD_Init();
LCD_CLR(0x00);
LCD_DisplayString(Hz, 0, 0);
while(1)
{
//Handle_Connect_MainLoop();
PushButton_Proc();
}
}
用户377235 2012-6-13 19:51
请问版主,有没有GPIO模拟SPI通迅的相关代码,请指教,谢谢!