📄 lcd.c
字号:
/*****************************************************/
/* File name : LCD.c */
/* Description : Code for Nokia 3310LCD, display IC:PCD8544 */
/* Platform : AVRStudio4.13 + WinAVR20070525 for AVR */
/* Author : Michael Zhang - 章其波 */
/* Email : sudazqb@163.com */
/* MSN : zhangqibo_1985@hotmail.com */
/* Date : 2007-10-21 */
/* NOT FOR COMMERCIAL USE, ALL RIGHT RESERVED! */
/*****************************************************/
/* Change Log: */
/* 20071122: fix a bug for some 3310lcd will not work with display function */
/* 20071021: original version */
/*****************************************************/
#include"LCD.h"
/******************** IO utilities ***************************/
#define LCD_RS_H LCD_RS_PORT |= 1<<LCD_RS_BIT
#define LCD_RS_L LCD_RS_PORT &= ~(1<<LCD_RS_BIT)
#define LCD_E_H LCD_E_PORT |= 1<<LCD_E_BIT
#define LCD_E_L LCD_E_PORT &= ~(1<<LCD_E_BIT)
#define LCD_RST_H LCD_RST_PORT |= 1<<LCD_RST_BIT
#define LCD_RST_L LCD_RST_PORT &= ~(1<<LCD_RST_BIT)
#define LCD_SCK_H LCD_SCK_PORT |= 1<<LCD_SCK_BIT
#define LCD_SCK_L LCD_SCK_PORT &= ~(1<<LCD_SCK_BIT)
#define LCD_MOSI_H LCD_MOSI_PORT |= 1<<LCD_MOSI_BIT
#define LCD_MOSI_L LCD_MOSI_PORT &= ~(1<<LCD_MOSI_BIT)
#define PORT_INI { \
LCD_RS_H; \
LCD_E_H; \
LCD_RST_H; \
LCD_SCK_H; \
LCD_MOSI_H; \
LCD_RS_DDR |= 1<<LCD_RS_BIT; \
LCD_E_DDR |= 1<<LCD_E_BIT; \
LCD_RST_DDR |= 1<<LCD_RST_BIT; \
LCD_SCK_DDR |= 1<<LCD_SCK_BIT; \
LCD_MOSI_DDR |= 1<<LCD_MOSI_BIT; \
}
/**************************************************************/
/*********** Display buffer in SRAM ************/
unsigned char disBuf[504];
#if HW_SPI
/*********************** Hardware SPI Speed Set **************/
void lcdSpiSpeedSet(void)
{
SPCR = (1<<SPE) | (1<<MSTR);
#if (F_CPU>8000000)
SPSR &= ~(1<<SPI2X); /* 1/4 F_CPU */
#else
SPSR |= 1<<SPI2X; /* 1/2 F_CPU */
#endif
}
/************************ Hardware SPI Speed set End *********/
#endif
/************************ SPI write a byte *********************/
void lcdWriteByte(unsigned char val)
{
//LCD_E_L;
#if HW_SPI /* Use Hardware SPI */
SPDR = val;
while(!(SPSR & (1<<SPIF))); /* Wait transfer end */
#else /* Use common GPIO to simulate the timing*/
unsigned char i = 8;
while(i--)
{
LCD_SCK_L;
if(val&0x80)LCD_MOSI_H; /* MSB first */
else LCD_MOSI_L;
LCD_SCK_H;
val <<= 1; /* Data shift */
}
#endif
//LCD_E_H;
}
/***************************************************************/
/************************ SPI write a command *********************/
void lcdWriteCmd(unsigned char val)
{
//LCD_E_L;
LCD_RS_L;
#if HW_SPI /* Use Hardware SPI */
SPDR = val;
while(!(SPSR & (1<<SPIF))); /* Wait transfer end */
#else /* Use common GPIO to simulate the timing*/
unsigned char i = 8;
while(i--)
{
LCD_SCK_L;
if(val&0x80)LCD_MOSI_H; /* MSB first */
else LCD_MOSI_L;
LCD_SCK_H;
val <<= 1; /* Data shift */
}
#endif
LCD_RS_H;
//LCD_E_H;
}
/***************************************************************/
/***************** LCD initialization *****************************/
void lcdInit(void)
{
PORT_INI; /* IO port initialization*/
#if HW_SPI /* If hardware SPI is used, adjust the SPI speed */
//lcdSpiSpeedSet();
SPCR = (1<<SPE) | (1<<MSTR)|(1<<SPR0)|(1<<SPR1);
SPSR &= ~(1<<SPI2X); /* 1/4 F_CPU */
#endif
lcdClrDisBuf(); /* clear display buffer: not the lcd internal buffer */
_delay_ms(15); /*MAX F_CPU should below than 16MHz*/
_delay_ms(15);
_delay_ms(15);
_delay_ms(15);
_delay_ms(15);
_delay_ms(15);
_delay_ms(15);
_delay_ms(15);
LCD_RST_L; /* Reset LCD */
_delay_ms(2);
_delay_ms(2);
LCD_RST_H;
_delay_us(40); /* Short Delay */
LCD_E_L; /* Enable LCD: CS = 0 */
lcdWriteCmd(0x21); /* Expanted Instuction, Set H = 1 */
lcdWriteCmd(0xc8); /* Set bias voltage */
lcdWriteCmd(0x06); /* Set temperature */
lcdWriteCmd(0x13); /* Set 1/48 cycle*/
lcdWriteCmd(0x20); /* Normal Insturction, Set H = 0 */
lcdWriteCmd(0x0c); /* Display control, Normal mode*/
lcdUpdateDisplay(); /* Update display */
LCD_E_H; /* Disable LCD: CS =1 */
}
/******** Clear the display buffer, external buffer in mico's SRAM ***************/
void lcdClrDisBuf(void)
{
unsigned int n = 504;
unsigned char * p = disBuf;
while(n--)*p++ = 0x00;
}
/** Update the display, actually transfer the data of the SRAM to LCD through SPI ****/
void lcdUpdateDisplay(void)
{
//unsigned int n = 504;
unsigned char * p = disBuf;
unsigned int i,j;
#if HW_SPI /* If hardware SPI is used, adjust the SPI speed*/
lcdSpiSpeedSet(); /* Other SPI device may share the SPI & they may change the speed */
#endif
LCD_E_L; /* Chip select */
/***************************************************************************/
/*** It seems that some 3310lcd do not support the following code ****/
//lcdWriteCmd(0x0c);
//lcdWriteCmd(0x40 | 0); /* Set row to 0 */
//lcdWriteCmd(0x80 | 0); /* Set column to 0*/
/* To make sure the data always start at codinate(0,0) */
//while(n--)
// lcdWriteByte(*p++);
/***************************************************************************/
/* so we use this, set the address at each row */
for(i=0;i<6;i++)
{
lcdWriteCmd(0x40 | i); /* Set row to 0 */
lcdWriteCmd(0x80 | 0); /* Set column to 0*/
for(j=0;j<84;j++)
{
lcdWriteByte(*p++);
}
}
LCD_E_H; /* chip deselect */
}
/*********** Set a pixel bit with value val *************************/
void OnePixel(unsigned char x,unsigned char y,unsigned char val)
{
unsigned char *p = &disBuf[ (unsigned int)y/8*84 + x ];//找到对应字节
if(val)*p |= (1<<(y%8)); //修改对应位
else *p &= ~(1<<(y%8));
}
/********** Read the pixel value withe the given codination ************/
unsigned char ReadPixel(unsigned char x,unsigned char y)
{
unsigned char *p = &disBuf[ (unsigned int)y/8*84 + x ];//找到对应字节
if(*p & (1<<(y%8)))return 1;
else return 0;
}
/* demo program
int main()
{
lcdInit();
onePixel(10,10,1);
lcdUpdateDisplay();
while(1);
}*/
/* This is the end of LCD.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -