SAM4L Xplained Pro starter kit硬件SPI刷屏幕

作者: 强仔00001
上传时间为: 2014-12-11 09:35 AM

今天用硬件SPI刷了个屏幕显示。很是激动。主控使用SAM4L Xplained Pro starter kit套件实现。是基于Atmel官方的固件库实现的,自己建的模板,这样方便源代码共享到网上。主要用到这几个函数:

外设复用函数:

ioport_set_pin_mode(xxx, xxx);

ioport_disable_pin(xxx);

端口模式设置函数:

ioport_set_pin_dir(xxx, xxx);

ioport_set_pin_mode(xxx, xxx);

电平状态设置函数:

arch_ioport_set_pin_level(xxx,x )

现在我来简单说说这几个函数的用途和用法吧:

1.ioport_set_pin_mode(xxx, xxx); 这个函数是管脚功能选择函数:

例如:把PORTC30脚设为SPI的SCK时钟脚,可以这样写:

ioport_set_pin_mode(PIN_PC30B_SPI_SCK, MUX_PC30B_SPI_SCK);

2.ioport_disable_pin(xxx);这个函数是复用功能使能函数,记住一定加上这句话,这样复用功能的外设才能工作。例如把PORTC30脚设为SPI的SCK时钟脚功能打开,可以这样写:

ioport_disable_pin(PIN_PC30B_SPI_SCK);

3.ioport_set_pin_dir(xxx, xxx);这个函数是管脚的方向设置函数,例如把PORTC08脚设为输出可以这样写:

ioport_set_pin_dir(PIN_PC08, IOPORT_DIR_OUTPUT);

4.arch_ioport_set_pin_level(xxx,x ):最后是管脚电平状态设置函数,这个函数带两个参数输入的,例如把PORTC08的管脚设为低电平,写法如下:

arch_ioport_set_pin_level(PIN_PC08, 0 );

现在我来说说我函数的流程吧:

函数首先是进行sysclk_init()函数打开所有GPIO的时钟操作,这个跟STM32的芯片一个样的,要用到某些外设时,要打开相应的外设的时钟。

然后是设置串口,初始化TFT屏幕,然后用串口向电脑打印信息,最后就是一直刷新屏幕,显示21ic的图标和我论坛的ID号:

主函数的代码如下:

int main()
{
        sysclk_init();
        arch_ioport_init();
        ioport_set_pin_dir(PIN_PC07, IOPORT_DIR_OUTPUT);
        ioport_set_pin_level(PIN_PC07, IOPORT_PIN_LEVEL_LOW);
        
        
        ioport_set_pin_mode(PIN_PC26A_USART1_RXD, MUX_PC26A_USART1_RXD);
        ioport_disable_pin(PIN_PC26A_USART1_RXD);
        ioport_set_pin_mode(PIN_PC27A_USART1_TXD, MUX_PC27A_USART1_TXD);
        ioport_disable_pin(PIN_PC27A_USART1_TXD);
        
        /*
        //配置板子上的硬件SPI
        ioport_set_pin_mode(PIN_PA21A_SPI_MISO, MUX_PA21A_SPI_MISO);//把PORTA21配置成MSIO
        ioport_disable_pin(PIN_PA21A_SPI_MISO);                     //使能MSIO功能
	ioport_set_pin_mode(PIN_PA22A_SPI_MOSI, MUX_PA22A_SPI_MOSI);//把PORTA22配置成MOSI
        ioport_disable_pin(PIN_PA22A_SPI_MOSI);                      //使能MOSI功能
	ioport_set_pin_mode(PIN_PC30B_SPI_SCK, MUX_PC30B_SPI_SCK);   //把PORTB30配置成SCK
        ioport_disable_pin(PIN_PC30B_SPI_SCK);                        //使能SCK功能
   
        ioport_set_pin_mode(PIN_PB11B_SPI_NPCS2,MUX_PB11B_SPI_NPCS2);//把PORTB11配置成CS
        ioport_disable_pin(PIN_PB11B_SPI_NPCS2);                      //使能CS功能
          
        ioport_set_pin_dir(UG_2832HSWEG04_DATA_CMD_GPIO, IOPORT_DIR_OUTPUT);
	ioport_set_pin_mode(UG_2832HSWEG04_DATA_CMD_GPIO, IOPORT_MODE_PULLUP);
	ioport_set_pin_dir(UG_2832HSWEG04_RESET_GPIO, IOPORT_DIR_OUTPUT);
	ioport_set_pin_mode(UG_2832HSWEG04_RESET_GPIO, IOPORT_MODE_PULLUP);
        
        configure_console();                                //配置串口
        


        ssd1306_init();                                     //初始化OLED

	ssd1306_clear();                                    //清OLED
	
	ssd1306_set_page_address(0);                        //行地址
	ssd1306_set_column_address(0);                    //列地址
	
	ssd1306_write_text("My ID is : qianzgai00001 !");//要显示的内容

	ssd1306_set_page_address(2);

	ssd1306_set_column_address(30);

	ssd1306_write_text("----Thanks EEWORD !");
        */

        
        configure_console();                                //配置串口
        Lcd_Init();
        printf("\r\n\r\n-- TFT试验 --\r\n");
        printf("\r\n\r\n-- 强仔00001 --\r\n");
        printf("\r\n\r\n-- 联系方式:963775289 --\r\n");
        
  while (1) 
  {
      
      
      //usart_getchar(USART1,&data);
      //usart_putchar(USART1,data);
    showimage(gImage_eeborad);

  }
  
}

SPI的底层函数:

#include "asf.h"
//#define LCD_CTRL   	GPIOB				//定义TFT数据端口为PB组
//#define LCD_LED        	GPIO_Pin_9  //MCU_PB9   		对应接液晶屏(或者模块)TFT --PIN_LED背光正极(背光可以由IO口提供电流,或者外接3.3V电压)
#define LCD_RS_SET   arch_ioport_set_pin_level(PIN_PC08, 1 )
#define LCD_RS_CLR   arch_ioport_set_pin_level(PIN_PC08, 0 )
#define LCD_RST_SET  arch_ioport_set_pin_level(PIN_PC09, 1 )
#define LCD_RST_CLR  arch_ioport_set_pin_level(PIN_PC09, 0 )
#define LCD_SCL_SET  arch_ioport_set_pin_level(PIN_PC30, 1 )
#define LCD_SCL_CLR  arch_ioport_set_pin_level(PIN_PC30, 0 )
#define LCD_SDA_SET  arch_ioport_set_pin_level(PIN_PA22, 1 )
#define LCD_SDA_CLR  arch_ioport_set_pin_level(PIN_PA22, 0 )



void SPI2_Init()
{

        spi_flags_t spi_flags = SPI_MODE_0;
    	board_spi_select_id_t spi_select_id = 0;
               //配置板子上的硬件SPI
        //ioport_set_pin_mode(PIN_PA21A_SPI_MISO, MUX_PA21A_SPI_MISO);//把PORTA21配置成MSIO
        //ioport_disable_pin(PIN_PA21A_SPI_MISO);                     //使能MSIO功能
	ioport_set_pin_mode(PIN_PA22A_SPI_MOSI, MUX_PA22A_SPI_MOSI);//把PORTA22配置成MOSI
        ioport_disable_pin(PIN_PA22A_SPI_MOSI);                      //使能MOSI功能
	ioport_set_pin_mode(PIN_PC30B_SPI_SCK, MUX_PC30B_SPI_SCK);   //把PORTB30配置成SCK
        ioport_disable_pin(PIN_PC30B_SPI_SCK);                        //使能SCK功能
   
        //ioport_set_pin_mode(PIN_PB11B_SPI_NPCS2,MUX_PB11B_SPI_NPCS2);//把PORTB11配置成CS
        //ioport_disable_pin(PIN_PB11B_SPI_NPCS2);   
        ioport_set_pin_dir(PIN_PC08, IOPORT_DIR_OUTPUT);
	ioport_set_pin_mode(PIN_PC08, IOPORT_MODE_PULLUP);
	ioport_set_pin_dir(PIN_PC09, IOPORT_DIR_OUTPUT);
	ioport_set_pin_mode(PIN_PC09, IOPORT_MODE_PULLUP);
        
        struct spi_device device = {
		.id = SSD1306_CS_PIN,
	};
        spi_master_init(SPI);
	spi_master_setup_device(SPI, &device, spi_flags,16000000, spi_select_id);
	spi_enable(SSD1306_SPI);
}

/**/
u8 SPI_WriteByte(u8 Data)
{
  struct spi_device device = {.id = SSD1306_CS_PIN};
  spi_select_device(SSD1306_SPI, &device);
  spi_write_single(SPI,Data);
  spi_deselect_device(SSD1306_SPI, &device);
}


void Lcd_WriteIndex(u8 Index)
{
   struct spi_device device = {.id = SSD1306_CS_PIN};
   spi_select_device(SSD1306_SPI, &device);
   LCD_RS_CLR;
   spi_write_single(SPI, Index);
   spi_deselect_device(SSD1306_SPI, &device);
}


void Lcd_WriteData(u8 Data)
{
    struct spi_device device = {.id = SSD1306_CS_PIN};
    spi_select_device(SSD1306_SPI, &device);
    LCD_RS_SET;
    spi_write_single(SPI,Data);
    spi_deselect_device(SSD1306_SPI, &device);
}


/*
u8 SPI_WriteByte1(u8 Data)
{
	unsigned char i=0;
	for(i=8;i>0;i--)
	{
      if(Data&0x80)
      LCD_SDA_SET; //????
      else LCD_SDA_CLR;

      LCD_SCL_CLR;
      LCD_SCL_SET;
      Data<<=1;
	}
}

void Lcd_WriteIndex1(u8 Index)
{
   //SPI 写命令时序开始
   //LCD_CS_CLR;
   LCD_RS_CLR;
	unsigned char i=0;
	for(i=8;i>0;i--)
	{
      if(Index&0x80)
      LCD_SDA_SET; //????
      else LCD_SDA_CLR;

      LCD_SCL_CLR;
      LCD_SCL_SET;
      Index<<=1;
	}
}


void Lcd_WriteData1(u8 Data)
{
      LCD_RS_SET;
  	unsigned char i=0;
	for(i=8;i>0;i--)
	{
      if(Data&0x80)
      LCD_SDA_SET; //????
      else LCD_SDA_CLR;

      LCD_SCL_CLR;
      LCD_SCL_SET;
      Data<<=1;
	}
}
*/
void Lcd_WriteData16Bit(u8 DataH,u8 DataL)
{
	Lcd_WriteData(DataH);
	Lcd_WriteData(DataL);
}

void Lcd_WriteIndex16Bit(u8 DataH,u8 DataL)
{
	Lcd_WriteIndex(DataH);
	Lcd_WriteIndex(DataL);
}



void Lcd_Reset(void)
{
	LCD_RST_CLR;
	delay_ms(100);
	LCD_RST_SET;
	delay_ms(50);
}


void Lcd_Init(void)
{
	SPI2_Init();
	Lcd_Reset();
	
	Lcd_WriteIndex(0xCB);  
        Lcd_WriteData(0x39); 
        Lcd_WriteData(0x2C); 
        Lcd_WriteData(0x00); 
        Lcd_WriteData(0x34); 
        Lcd_WriteData(0x02); 

        Lcd_WriteIndex(0xCF);  
        Lcd_WriteData(0x00); 
        Lcd_WriteData(0XC1); 
        Lcd_WriteData(0X30); 
 
        Lcd_WriteIndex(0xE8);  
        Lcd_WriteData(0x85); 
        Lcd_WriteData(0x00); 
        Lcd_WriteData(0x78); 
 
        Lcd_WriteIndex(0xEA);  
        Lcd_WriteData(0x00); 
        Lcd_WriteData(0x00); 
 
        Lcd_WriteIndex(0xED);  
        Lcd_WriteData(0x64); 
        Lcd_WriteData(0x03); 
        Lcd_WriteData(0X12); 
        Lcd_WriteData(0X81); 

        Lcd_WriteIndex(0xF7);  
        Lcd_WriteData(0x20); 
  
        Lcd_WriteIndex(0xC0);    //Power control 
        Lcd_WriteData(0x23);   //VRH[5:0] 
 
        Lcd_WriteIndex(0xC1);    //Power control 
        Lcd_WriteData(0x10);   //SAP[2:0];BT[3:0] 
 
        Lcd_WriteIndex(0xC5);    //VCM control 
        Lcd_WriteData(0x3e); //对比度调节
        Lcd_WriteData(0x28); 
 
        Lcd_WriteIndex(0xC7);    //VCM control2 
        Lcd_WriteData(0x86);  //--
 
        Lcd_WriteIndex(0x36);    // Memory Access Control 
#ifdef H_VIEW
        Lcd_WriteData(0xE8); //C8	   //48 68竖屏//28 E8 横屏
#else
				Lcd_WriteData(0x48); 
#endif

        Lcd_WriteIndex(0x3A);    
        Lcd_WriteData(0x55); 

        Lcd_WriteIndex(0xB1);    
        Lcd_WriteData(0x00);  
        Lcd_WriteData(0x18); 
 
        Lcd_WriteIndex(0xB6);    // Display Function Control 
        Lcd_WriteData(0x08); 
        Lcd_WriteData(0x82);
        Lcd_WriteData(0x27);  
 
        Lcd_WriteIndex(0xF2);    // 3Gamma Function Disable 
        Lcd_WriteData(0x00); 
 
        Lcd_WriteIndex(0x26);    //Gamma curve selected 
        Lcd_WriteData(0x01); 
 
        Lcd_WriteIndex(0xE0);    //Set Gamma 
        Lcd_WriteData(0x0F); 
        Lcd_WriteData(0x31); 
        Lcd_WriteData(0x2B); 
        Lcd_WriteData(0x0C); 
        Lcd_WriteData(0x0E); 
        Lcd_WriteData(0x08); 
        Lcd_WriteData(0x4E); 
        Lcd_WriteData(0xF1); 
        Lcd_WriteData(0x37); 
        Lcd_WriteData(0x07); 
        Lcd_WriteData(0x10); 
        Lcd_WriteData(0x03); 
        Lcd_WriteData(0x0E); 
        Lcd_WriteData(0x09); 
        Lcd_WriteData(0x00); 

        Lcd_WriteIndex(0XE1);    //Set Gamma 
        Lcd_WriteData(0x00); 
        Lcd_WriteData(0x0E); 
        Lcd_WriteData(0x14); 
        Lcd_WriteData(0x03); 
        Lcd_WriteData(0x11); 
        Lcd_WriteData(0x07); 
        Lcd_WriteData(0x31); 
        Lcd_WriteData(0xC1); 
        Lcd_WriteData(0x48); 
        Lcd_WriteData(0x08); 
        Lcd_WriteData(0x0F); 
        Lcd_WriteData(0x0C); 
        Lcd_WriteData(0x31); 
        Lcd_WriteData(0x36); 
        Lcd_WriteData(0x0F); 
 
        Lcd_WriteIndex(0x11);    //Exit Sleep 
        delay_ms(120);
				
        Lcd_WriteIndex(0x29);    //Display on 
        Lcd_WriteIndex(0x2c); 

}


/*************************************************
函数名:LCD_Set_Region
功能:设置lcd显示区域,在此区域写点数据自动换行
入口参数:xy起点和终点,Y_IncMode表示先自增y再自增x
返回值:无
*************************************************/
void Lcd_SetRegion(u16 x_start,u16 y_start,u16 x_end,u16 y_end)
{	
	Lcd_WriteIndex(0x2a);
	Lcd_WriteData16Bit(x_start>>8,x_start);
	Lcd_WriteData16Bit(x_end>>8,x_end);
	Lcd_WriteIndex(0x2b);
	Lcd_WriteData16Bit(y_start>>8,y_start);
	Lcd_WriteData16Bit(y_end>>8,y_end);
	Lcd_WriteIndex(0x2c);

}


void Lcd_SetXY(u16 x,u16 y)
{
  	Lcd_WriteIndex(0x2a);
	Lcd_WriteData16Bit(x>>8,x);
	Lcd_WriteIndex(0x2b);
	Lcd_WriteData16Bit(y>>8,y);

	Lcd_WriteIndex(0x2c);
}

	
/*************************************************
函数名:LCD_DrawPoint
功能:画一个点
入口参数:无
返回值:无
*************************************************/
void Gui_DrawPoint(u16 x,u16 y,u16 Data)
{
	Lcd_SetXY(x,y);
	Lcd_WriteData(Data>>8);
	Lcd_WriteData(Data);

}    


/*************************************************
函数名:Lcd_Clear
功能:全屏清屏函数
入口参数:填充颜色COLOR
返回值:无
*************************************************/
void Lcd_Clear(u16 Color)               
{	
   unsigned int i,m;
   Lcd_SetRegion(0,0,X_MAX_PIXEL-1,Y_MAX_PIXEL-1);
   LCD_RS_SET;


   
   for(i=0;i<Y_MAX_PIXEL;i++)
   {
    for(m=0;m<X_MAX_PIXEL;m++)
      {	 

		SPI_WriteByte(Color>>8);
		SPI_WriteByte(Color);

      }   
	}
	 // LCD_CS_SET;  
}

void Lcd_WriteData_16Bit(u16 Data)
{
	Lcd_WriteData(Data>>8);
	Lcd_WriteData(Data);
}
好长的代码;

来看看显示效果吧,还是挺赞的:

全部评论 ()

创建讨论帖子

登录 后参与评论
系统提示