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

📄 spi.c

📁 驱动芯片为ILI9320的TFT LCD 在s3c2410下的应用
💻 C
字号:
/**********************************************************
Date:2008.02.01
by  :dding832@126.com
***********************************************************/
#include "def.h"
#include "option.h"
#include "2410addr.h"
#include "2410lib.h"
#include "Spi.h"

void SpiConfig(void)
{
	/*GPG8(CLK) OUTPUT*/
	rGPGCON = (rGPGCON & ~(0x3 << 16)) | (0x1 << 16); 
	
	/*GPG0(SDI) OUTPUT*/
	rGPGCON = (rGPGCON & ~(0x3)) | (0x1); 
}

void Spi_Start(void)
{
	SCLK(0);
	CS(1);
	SDI(1);
	SCLK(1);
	CS(0);
}

void  DelayNo(U32 i)
{
    for(;i>0;i--);
}


void SpiInit(void)
{
	CS(1);
	SCLK(0);
	SDI(0);
	DelayNo(5);
}
void SpiTest(void)
{
	SCLK(1);
	SCLK(0);
	SDI(1);
	SDI(0);
	CS(1);
	CS(0);
}

#if 0
void SpiInit(void)
{
	/* enable pclk for spiclk */
	rCLKCON |= (1<<18);
	
	/* set GPIO as SPI Pin    */
	rGPECON &= ~(0x3F << 22);       //GPE11,12,13   控制位清零 
	rGPECON |= (0x2A << 22);        //GPE11,12,13   设置位SPIMISO0,SPIMOSI0,SPICLK0
	rGPEUP |= (0x7<<11);	        //disable pull
	
	/* 
	Config GPD8(VD16) is CS for ILI9320
	Initialize  is high   
	*/ 				  
	rGPDDAT |=(0x1 << 8);      //CS HIGH 配置在Lcd_Port_Init()函数中完成
    
    /* 
    Baudrate = PCLK/2/(Prescaler value + 1)
    PCLK = 203000000/4 = 50750000 Hz
    Prescaler value = 0x18 = 24(rSPPRE0)
    Baudrate = 50750000/2/(24 + 1) = 1015000 = 1.015MHz
    */
    rSPPRE0 =0x18;
   
    rSPPIN0=0x02;
    
    /*
    Polling mode, SCK Enable, master, active high, fomart A, normal mode
    */
    rSPCON0 = 0x18;  
}
#endif

int halSpiReadReg(int addr)
{
	  int Value=0x99;
	  
	  // Set CS to low to activate cc1100
 	  rGPGDAT &= ~(0x1 << 7);
 	  Delay(3);
 	  
 	  //make sure that cc1100's SO is low 
 	  //Set 2410 GPE11 as in	
	  rGPECON &= ~(0x3 << 22); 				
	  //Wait CC1100's SO is low		
	  while(rGPEDAT&(0x1<<11))			
  	  Uart_Printf("Dding:Wait CC1100's SO is low\n");
  	  //Set 2410 GPE11 as SPIMISO0
	  rGPECON &= ~(0x3 << 22); 		
	  rGPECON |= (0x2 << 22);
  

	  // Check the status of Transfer Ready flag(READY=1) ,and then write data to SPTDAT0
	  while( (rSPSTA0 & 0x01) != 1 );

	  rSPTDAT0 = addr|0x80; // Read Value from cc1100 Register( 设置第八位为1,)
	  
	  // Wait to complete write data
	  while( (rSPSTA0 & 0x01) != 1 );
	  
	  // Write  value For Read value
	  rSPTDAT0 = 0; 
	  
	  // Wait to complete write data
	  while( (rSPSTA0 & 0x01) != 1 );
 
	  Value=rSPRDAT0;
	  
	  // Set CS to high to disable cc1100
	  rGPGDAT |= (0x1 << 7);
	  
	  return Value;
	  
}

void halSpiWriteReg(int addr,int Value)
{
	  // Set CS to low to activate cc1100
 	  rGPGDAT &= ~(0x1 << 7);
 	  Delay(3);
 	  
 	  //make sure that cc1100's SO is low 
 	  //Set 2410 GPE11 as in
	  rGPECON &= ~(0x3 << 22); 
	  //Wait CC1100's SO is low
	  while(rGPEDAT&(0x1<<11));
	  //Set 2410 GPE11 as SPIMISO0
	  rGPECON &= ~(0x3F << 22); 		
	  rGPECON |= (0x2A << 22);
 	  
 	  // Check the status of Transfer Ready flag(READY=1) ,and then write data to SPTDAT0
	  while( (rSPSTA0 & 0x01) != 1 );
	  
	  rSPTDAT0=addr&0x7f;
	  
	  // Wait to complete write data
	  while( (rSPSTA0 & 0x01) != 1 );
	  
	  Delay(10);		//on LPC2214
	  rSPTDAT0=Value;
	  // Wait to complete write data
	  while( (rSPSTA0 & 0x01) != 1 );
	  	  
	  // Set CS to high to unactivate cc1100
	  rGPGDAT |= (0x1 << 7);
	  	  
}

void spitest(void)
{	
	char Value=99;
	
	
	
	Uart_Printf( "\n  %s  \n", "spi test" );
	SpiInit();
	halSpiWriteReg(0x11,0x13);
	while(1)
	{	  	 

	  Value=halSpiReadReg(0x11);
	  
	  Uart_Printf("Dding: The Value of 0x11 is 0x%x\n",Value);
	  Uart_Printf("Dding: The Value of 0x11 is 0x%x\n",Value);
	  Uart_Printf("Dding: The Value of 0x11 is 0x%x\n",Value);
	  Uart_Printf("Dding: The Value of 0x11 is 0x%x\n",Value);
	  Uart_Printf("Dding: The Value of 0x11 is 0x%x\n",Value);
 
	  //test
	  Uart_Printf("*******************************************\n");
	  Uart_Printf("Dding: v_pSSPregs->rSPCON0 is 0x%x\n",rSPCON0);
	  Uart_Printf("Dding: v_pSSPregs->rSPPIN0 is 0x%x\n",rSPPIN0);
	  Uart_Printf("Dding: v_pSSPregs->rSPPRE0 is 0x%x\n",rSPPRE0);
	  Uart_Printf("Dding: v_pSSPregs->rSPSTA0 is 0x%x\n",rSPSTA0);
	  Uart_Printf("Dding: v_pSSPregs->rSPTDAT0 is 0x%x\n",rSPTDAT0);
	  Uart_Printf("Dding: v_pSSPregs->rSPRDAT0 is 0x%x\n",rSPRDAT0);
	  Uart_Printf("Dding: v_pIOPregs->rGPECON  is 0x%x\n",rGPECON);
	  Uart_Printf("Dding: v_pIOPregs->rGPEUP  is 0x%x\n",rGPEUP );
	  Uart_Printf("Dding: v_pIOPregs->rGPGDAT is 0x%x\n",rGPGDAT);
	  Uart_Printf("Dding: v_pIOPregs->rGPFCON is 0x%x\n",rGPFCON);
	  Uart_Printf("Dding: v_pIOPregs->rGPFDAT is 0x%x\n",rGPFDAT);
	  Uart_Printf("Dding: v_pCLKPWRregs->rCLKCON is 0x%x\n",rCLKCON);
	  
      Uart_Printf("*******************************************\n");
 
 	  //Delay(10000);		//delay 200ms
	}	
}

void Lcd_SPI_Process(U8 type, U16 datas)
{	
	unsigned char i;
	unsigned char orders;
	
	//SpiInit();
	
	CS(0);      
	DelayNo(100);
	
	if(type == 1)
	{	
	    orders = 0x74;   //写命令
	}
	else		
	{
	    orders = 0x76;  //写数据
    }
	
	for(i = 0; i < 8; i++)
	{
		SCLK(0);
		DelayNo(1000);
		if(orders & 0x80)
		{
			SDI(1);
		}
		else
		{
			SDI(0);
		}
		
		DelayNo(1000);
		SCLK(1);
		DelayNo(1000);
		
		orders = orders << 1;
	}
	
	for(i = 0; i <16; i++)
	{
		SCLK(0);
		DelayNo(1000);
		
		if(datas & 0x8000)
		{
			SDI(1);
		}
		else
		{
			SDI(0);
		}
		
		DelayNo(1000);
		SCLK(1);
		DelayNo(1000);
		datas = datas << 1;
	}
	CS(1);
}


U16 Lcd_Reg_Read(U16 reg)
{
	unsigned char i;
	unsigned char orders;
	unsigned char retValue;
	
	//SpiInit();
	
	CS(0);      
	DelayNo(100);
	
	orders = 0x77;	//读寄存器
	
	for(i = 0; i < 8; i++)
	{
		SCLK(0);
		DelayNo(100);
		if(orders & 0x80)
		{
			SDI(1);
		}
		else
		{
			SDI(0);
		}
		
		DelayNo(100);
		SCLK(1);
		DelayNo(100);
		
		orders = orders << 1;
	}
	
	for(i = 0; i <16; i++)
	{
		SCLK(0);
		DelayNo(100);
		
		if(reg & 0x8000)
		{
			SDI(1);
		}
		else
		{
			SDI(0);
		}
		
		DelayNo(100);
		SCLK(1);
		DelayNo(100);
		reg = reg << 1;
	}
	
	retValue = 0;
	for(i = 0; i <8; i++)
	{
		retValue = retValue << 1;
		SCLK(0);
		DelayNo(100);
		retValue |= SDO;
		DelayNo(100);
		SCLK(1);
		DelayNo(100);
	}
	
	retValue = 0;
	for(i = 0; i <16; i++)
	{
		retValue = retValue << 1;
		SCLK(0);
		DelayNo(100);
		
		if(SDO)
		{
			retValue = retValue | 1;
		}
		
		DelayNo(100);
		SCLK(1);
		DelayNo(100);
	}
	CS(1);
	
	return retValue;
}

void LCD_CtrlWrite_ILI9320(unsigned char reg, U16 datas)
{
	Lcd_SPI_Process(LCD_Command,reg);
	Lcd_SPI_Process(LCD_Data,datas);
}

void ILI9320_Init(void)
{
    //****************Reset LCD Driver*************************//
	LCD_nReset_HIGH();
	Delay(10);		//Delay 1ms
	LCD_nReset_LOW();
	Delay(100);		//Delay 10ms
	LCD_nReset_HIGH();
	Delay(500);		//Delay 50ms
	//****************Start Initial Sequence******************//
	LCD_WriteReg(0x00e5,0x8000);	//Set the Vcore voltage and this setting is must
	LCD_WriteReg(0x0000,0x0001);	//Starting internal OSC
	LCD_WriteReg(0x0001,0x0100);	//Set SS and SM bit
	//LCD_WriteReg(0x0002,0x0400);	//Set 1 line inversion
	LCD_WriteReg(0x0002,0x0400);
	LCD_WriteReg(0x0003,0x1030);	//Set GRAM write direction and BGR=1
	LCD_WriteReg(0x0004,0x0000);	//Resize register
	
	//LCD_WriteReg(0x0008,0x0202);	//Set the back porch and front porch
	LCD_WriteReg(0x0008,0x0808);
	LCD_WriteReg(0x0009,0x0000);	//Set non-display area refresh cycle ISC[3:0]
	LCD_WriteReg(0x000a,0x0000);	//FRAME function
	LCD_WriteReg(0x000c,0x0111);	//RGB interface setting
	LCD_WriteReg(0x000d,0x0000);	//Frame marker Position
	LCD_WriteReg(0x000f,0x0000);	//RGB interface polarity
	/*
	//SPI可以运行
	LCD_WriteReg(0x000c,0x0000);	//RGB interface setting
	LCD_WriteReg(0x000d,0x0000);	//Frame marker Position
	LCD_WriteReg(0x000f,0x0000);	//RGB interface polarity
	*/
	
	//****************Power On Sequence***********************//
	LCD_WriteReg(0x0010,0x0000);	//SAP,BT[3:0],AP,DSTB,SLP,STB
	//LCD_WriteReg(0x0011,0x0007);	//DC1[2:0],DC0[2:0],VC[2:0]
	LCD_WriteReg(0x0011,0x0000);
	LCD_WriteReg(0x0012,0x0000);	//VREG1OUT voltage
	LCD_WriteReg(0x0013,0x0000);	//VDV[4:0] for VCOM amplitude
	Delay(2000);
	//LCD_WriteReg(0x0010,0x16b0);	//SAP,BT[3:0],AP,DSTB,SLP,STB
	//LCD_WriteReg(0x0011,0x0007);	//R11H=0X0031 at VCI=3.3V DC1[2:0],DC0[2:0],VC[2:0]
	LCD_WriteReg(0x0010,0x17b0);
	LCD_WriteReg(0x0011,0x0147);
	Delay(500);						//Delay 50ms
	//LCD_WriteReg(0x0012,0x011a);	//R12h=0x1800 at VCI=3.3V VDV[4:0] for VCOM amplitude
	LCD_WriteReg(0x0012,0x013c);
	Delay(500);
	//LCD_WriteReg(0x0013,0x1b00);
	//LCD_WriteReg(0x0029,0x0012);	//R29H=0X0008 AT VCI=3.3V VCM[4:0] FOR VCOMH
	LCD_WriteReg(0x0013,0x0e00);
	LCD_WriteReg(0x0029,0x0009);
	Delay(500);
	LCD_WriteReg(0x0020,0x0000);	//gram horizontal address
	LCD_WriteReg(0x0021,0x0000);	//gram vertical address

	//****************Adjust the Gamma Curve*******************//
	/* LCD_WriteReg(0x0030,0x0000);
	LCD_WriteReg(0x0031,0x0707);
	LCD_WriteReg(0x0032,0x0707);

	LCD_WriteReg(0x0036,0x001f);
	LCD_WriteReg(0x0037,0x0105);
	LCD_WriteReg(0x0038,0x0002);
	LCD_WriteReg(0x0039,0x0707);

	LCD_WriteReg(0x003c,0x0602);
	LCD_WriteReg(0x003d,0x1000); */
	LCD_WriteReg(0x0030,0x0207);
	LCD_WriteReg(0x0031,0x0505);
	LCD_WriteReg(0x0032,0x0102);
	LCD_WriteReg(0x0035,0x0007);
	LCD_WriteReg(0x0036,0x0606);
	LCD_WriteReg(0x0037,0x0707);
	LCD_WriteReg(0x0038,0x0006);
	LCD_WriteReg(0x0039,0x0407);

	LCD_WriteReg(0x003c,0x0605);
	LCD_WriteReg(0x003d,0x0601);
	//Delay(500); delete
	
	//****************Set GRAM area***************************//
	LCD_WriteReg(0x0050,0x0000);	//Horizontal GRAM Start Address
	LCD_WriteReg(0x0051,0x00ef);	//Horizontal GRAM End Address
	LCD_WriteReg(0x0052,0x0000);	//Vertical GRAM Start Adderss
	LCD_WriteReg(0x0053,0x013f);	//Vertical GRAM END Address
	
	LCD_WriteReg(0x0060,0x2700);	//Gate Scan Line
	LCD_WriteReg(0x0061,0x0001);	//NDL,VLF,REV
	LCD_WriteReg(0x006a,0x0000);	//set scrolling line

	//****************Partial Display Control*****************//
	LCD_WriteReg(0x0080, 0x0000);
	LCD_WriteReg(0x0081, 0x0000);
	LCD_WriteReg(0x0082, 0x0000);
	LCD_WriteReg(0x0083, 0x0000);
	LCD_WriteReg(0x0084, 0x0000);
	LCD_WriteReg(0x0085, 0x0000);

	//****************Panel Control***************************//
	//LCD_WriteReg(0x0090, 0x0012);
	LCD_WriteReg(0x0090, 0x0016);
	LCD_WriteReg(0x0092, 0x0000);
	LCD_WriteReg(0x0093, 0x0003);
	LCD_WriteReg(0x0095, 0x0110);
	LCD_WriteReg(0x0097, 0x0000);
	LCD_WriteReg(0x0098, 0x0000);
	
	LCD_WriteReg(0x0007, 0x0173); // 262K color and display ON
	Delay(500);
	LCD_WriteReg(1,0x0022);
	Delay(1000);
	
	/*
	LCD_WriteReg(0x0007, 0x0001);
	Delay(200);
	LCD_WriteReg(0x0007, 0x0021);
	LCD_WriteReg(0x0007, 0x0023);
	Delay(200);
	LCD_WriteReg(0x0007, 0x0173);
	LCD_WriteReg(1,0x0022);
	Delay(1000);*/
}

void SPI_Interface(void)
{
    IM3_LOW();
    IM2_HIGH();
    IM1_LOW();
    IM0_HIGH(); 
}

void Screen_Clear(U16 col)
{
    U16 x = 0;
    U16 y = 0;
    LCD_CtrlWrite_ILI9320(0x20, 0x0000);
    LCD_CtrlWrite_ILI9320(0x21, 0x0000);
    
    Lcd_SPI_Process(1,0x22);
    for(x = 0; x<320; x++)
    {
        for(y = 0; y<240; y++)
        {
            Lcd_SPI_Process(0, col);
        }
    }
}

void LCD_WriteByte(unsigned char dat)
{
	unsigned char i;
    
    for(i=0;i<8;i++)
	{
		SCLK(0);
		if(dat & 0x80)
		{
			SDI(1);
		}
		else
		{
			SDI(0);
		}
		SCLK(1);
		dat<<=1;
	}
}

void LCD_WriteReg(unsigned char index,unsigned int val)
{
    LCD_WriteRegIndex(index);

	CS(0);
    LCD_WriteByte(0x76);
    LCD_WriteByte(val>>8);
    LCD_WriteByte(val&0xff);
    CS(1);
}

void  LCD_WriteRegIndex(unsigned char index) /* Select GRAM Reg */ 

{
	CS(0);
    LCD_WriteByte(0x74);//for register index
    LCD_WriteByte(0);	 //lower byte first
    LCD_WriteByte(index);
	CS(1);

}

void Lcd_Write_Start(void)
{
	LCD_WriteRegIndex(0x22); /* Select GRAM Reg */ 
	CS(0); 
	LCD_WriteByte(0x76);
}

void Lcd_Write_End(void)
{
	CS(1);
}

void LCD_WriteData(unsigned int val)
{
    LCD_WriteByte(val>>8);
    LCD_WriteByte(val&0xff);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -