⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd.c

📁 mp3量不要让站长把时间都花费在为您修正说明上。压缩包解压时不能有密码。系统会自动删除debug和release目录
💻 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 + -