?? lcd.c
字號:
/*****************************************************/
/* File name : LCD.c */
/* Description : Code for Nokia 3310LCD, display IC:PCD8544 */
/* Platform : SourceInsight3.5 + WinARM20060606 for 7S256 */
/* Author : Michael Zhang - 章其波 */
/* Email : sudazqb@163.com */
/* MSN : zhangqibo_1985@hotmail.com */
/* Date : 2007-12-06 */
/* NOT FOR COMMERCIAL USE, ALL RIGHT RESERVED! */
/*****************************************************/
/* Change Log: */
/* 20080928: modify codes for ARM platform (NXP LPC2132) */
/* 20071222: modify for use another chip on board (mcuzone mp3) */
/* 20071206: modify code for Atmel ARM AT91SAM7S256 */
/* 20071122: fix a bug for some 3310lcd will not work with display function */
/* 20071021: original version */
/*****************************************************/
#include"LCD.h"
/*********** Display buffer in SRAM ************/
unsigned char disBuf[504];
#if HW_SPI
/*********************** Hardware SPI Speed Set **************/
void lcdSpiSpeedSet()
{
S0PCCR = 12; /* 設置SPI0時鐘分頻值為8 Set the value of dividing frequency to 8 */
S0PCR = (0 << 3) | // CPHA = 0, 數據 在SCK 的第一個時鐘沿采樣
(1 << 4) | // CPOL = 1, SCK 為低有效
(1 << 5) | // MSTR = 1, SPI 處于主模式
(0 << 6) | // LSBF = 0, SPI 數據傳輸MSB (位7)在先
(0 << 7); // SPIE = 0, SPI 中斷被禁止
#if 0
AT91PS_SPI pSPI = AT91C_BASE_SPI;
unsigned int reg;
unsigned char speed = MCK/1000000/2; /* 3310's max Fsclk is 4MHz, so 2MHz is ok! */
reg = pSPI->SPI_CSR[0]; /* we control the CS but not SPI , so just use default SPI_CSR0 */
reg = ( reg & ~(AT91C_SPI_SCBR) ) | ( (unsigned int)speed << 8 ); /* recaulate */
pSPI->SPI_CSR[0] = reg; /* set the value */
#endif
}
/************************ Hardware SPI Speed set End *********/
#endif
/************************ SPI write a byte *********************/
void lcdWriteByte(unsigned char val)
{
/* we do not assert cs signal in each write cycle, cs is select in block data transfer */
//AT91PS_SPI pSPI = AT91C_BASE_SPI;
#if HW_SPI /* Use Hardware SPI */
S0PDR = val;
while(0 == (S0PSR & 0x80)); /* wait for SPI0F being set, that is, wait for finishing of data being send */
// return(S0PDR);
#if 0
while( !( pSPI->SPI_SR & AT91C_SPI_TDRE ) ); /* transfer compl. wait */
pSPI->SPI_TDR = val;
while( !( pSPI->SPI_SR & AT91C_SPI_RDRF ) ); /* wait for char */
return (unsigned char)( pSPI->SPI_RDR ); /* it's important to read RDR here! */
#endif
#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
}
/***************************************************************/
/************************ SPI write a command *********************/
void lcdWriteCmd(unsigned char val)
{
// unsigned char temp;
//AT91PS_SPI pSPI = AT91C_BASE_SPI;
LCD_RS_L; /* command select */
#if HW_SPI /* Use Hardware SPI */
S0PDR = val;
while(0 == (S0PSR & 0x80)); /* wait for SPI0F being set, that is, wait for finishing of data being send */
//return(S0PDR);
#if 0
while( !( pSPI->SPI_SR & AT91C_SPI_TDRE ) ); /* transfer compl. wait */
pSPI->SPI_TDR = val;
while( !( pSPI->SPI_SR & AT91C_SPI_RDRF ) ); /* wait for char */
temp = (unsigned char)( pSPI->SPI_RDR ); /* it's important to read RDR here! */
#endif
#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; /* command deselect, data transfer now */
}
/***************************************************************/
/***************** LCD initialization *****************************/
void lcdInit(void)
{
#if 0
AT91PS_SPI pSPI = AT91C_BASE_SPI;
AT91PS_PMC pPMC = AT91C_BASE_PMC;
#endif
LCD_PORT_INI; /* IO port initialization*/
#if 0
#if HW_SPI /* If hardware SPI is used, Initialize SPI & adjust the SPI speed */
/* disable PIO from controlling MOSI, MISO, SCK (=hand over to SPI) */
pPIO->PIO_PDR = AT91C_PA12_MISO | AT91C_PA13_MOSI | AT91C_PA14_SPCK;
/* set pin-functions in PIO Controller */
pPIO->PIO_ASR = AT91C_PA12_MISO | AT91C_PA13_MOSI | AT91C_PA14_SPCK;
/* enable peripheral clock for SPI ( PID Bit 5 ) */
pPMC->PMC_PCER = ( 1 << AT91C_ID_SPI ); /* n.b. IDs are just bit-numbers */
/* SPI enable and reset */
pSPI->SPI_CR = AT91C_SPI_SPIEN | AT91C_SPI_SWRST;
/* SPI mode: master, fixed periph. sel., FDIV=0, fault detection disabled */
pSPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED | AT91C_SPI_MODFDIS;
/* set PCS for fixed select, in this program we do not use select of the SPI */
/* We control the select ourself, so the default cs is 0, but we never use it */
pSPI->SPI_MR &= 0xFFF0FFFF; /* clear old PCS - redundant (AT91lib) */
pSPI->SPI_MR |= ( (0<<16) & AT91C_SPI_PCS ); /* set PCS */
pSPI->SPI_CSR[0] = AT91C_SPI_NCPHA | AT91C_SPI_BITS_8;
/* set SPI clock speed */
lcdSpiSpeedSet();
/* Enable SPI interface */
pSPI->SPI_CR = AT91C_SPI_SPIEN;
#endif
#endif
lcdSpiSpeedSet();
lcdClrDisBuf(); /* clear display buffer: not the lcd internal buffer */
_delay_ms(15); /*MAX F_CPU should below than 16MHz*/
_delay_ms(15);
LCD_RST_L; /* Reset LCD */
_delay_ms(1);
LCD_RST_H;
_delay_ms(1); /* 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; /* 84*48/8 = 504*/
unsigned char * p = disBuf;
while(n--)*p++ = 0x00; /* clear the content */
}
/** 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, we then do not need to assert and dessert it in each spi cycle */
/***************************************************************************/
/*** 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++); /* send one byte data */
}
}
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 ];/* find out which byte it is in */
if(val)*p |= (1<<(y%8)); /* then modify the right bit according the value of "val" */
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 ];/* find out which byte it is in */
if(*p & (1<<(y%8)))return 1; /* return the value of that bit */
else return 0;
}
/* Lcd test utility, if the connection & lcd is ok, you'll see the screen is filling dots */
void lcdTest(void)
{
unsigned int i,j;
unsigned char val = 0;
lcdClrDisBuf(); /* clear the buffer first */
while(1)
{
if (val)val = 0;
else val = 1;
for(i=0;i<48;i++)
{
for(j=0;j<84;j++)
{
OnePixel(j,i,val); /* write data, and the display is lines, you can image what it is like */
lcdUpdateDisplay(); /* update the display contents */
_delay_ms(1); /* a delay, otherwise the transfer is too fast */
}
}
}
}
/* demo program
int main()
{
lcdInit();
lcdTest();
while(1);
}*/
/* This is the end of LCD.c */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -