查看: 687|回复: 0

SAM4L Xplained Pro starter kit硬件SPI刷屏幕

[复制链接]
  • TA的每日心情
    奋斗
    2015-10-5 14:38
  • 签到天数: 175 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2014-12-11 09:35:07 | 显示全部楼层 |阅读模式
    分享到:
    今天用硬件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);}好长的代码;来看看显示效果吧,还是挺赞的:
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-4-20 07:09 , Processed in 0.121238 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.