加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入

【LPC845月餅板】+ 圓形LCD屏幕顯示

05/16 10:10
4360
服務(wù)支持:
技術(shù)交流群

完成交易后在“購(gòu)買成功”頁(yè)面掃碼入群,即可與技術(shù)大咖們分享疑惑和經(jīng)驗(yàn)、收獲成長(zhǎng)和認(rèn)同、領(lǐng)取優(yōu)惠和紅包等。

虛擬商品不可退

當(dāng)前內(nèi)容為數(shù)字版權(quán)作品,購(gòu)買后不支持退換且無(wú)法轉(zhuǎn)移使用。

加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論
放大
電路板圖(3)
相關(guān)方案
  • 方案介紹
  • 相關(guān)文件
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

這個(gè)圓形LCD屏幕驅(qū)動(dòng)型號(hào)是GC9A01芯片,使用SPI接口,屏幕大小1.28寸的,分辨率240*240的。價(jià)格在20左右。引腳說(shuō)明如下:

下面來(lái)說(shuō)一說(shuō)如何點(diǎn)亮屏幕。

首先我們要根據(jù)電路圖知道屏幕使用的IO和SPI接口。LPC845有這樣一個(gè)好處,那就是基本所有外設(shè)都可以通過(guò)矩陣方式映射到任意管腳。這樣就可以在電路設(shè)計(jì)中基本可以使用任意IO,而不用為搞錯(cuò)外設(shè)腳位擔(dān)心。

如下圖電路中就可以找到屏幕使用管腳。

接下來(lái)初始化這些管腳以及SPI接口。初始化代碼如下

void drv_spi_gpio_init(void)
{
    CLOCK_EnableClock(kCLOCK_Iocon);
    CLOCK_EnableClock(kCLOCK_Gpio0);
    CLOCK_EnableClock(kCLOCK_Gpio1);
    
    CLOCK_EnableClock(kCLOCK_Spi0);
    CLOCK_EnableClock(kCLOCK_Spi1);
    
    CLOCK_Select(kSPI0_Clk_From_MainClk);
    CLOCK_Select(kSPI1_Clk_From_MainClk);
    
    RESET_PeripheralReset(kSPI0_RST_N_SHIFT_RSTn);
    RESET_PeripheralReset(kSPI1_RST_N_SHIFT_RSTn);

    gpio_pin_config_t SPILCD_IN_config = {
        .pinDirection = kGPIO_DigitalInput,
        .outputLogic = 1U,
    };
    gpio_pin_config_t SPILCD_IOH_config = {
        .pinDirection = kGPIO_DigitalOutput,
        .outputLogic = 1U,
    };
    gpio_pin_config_t SPILCD_IOL_config = {
        .pinDirection = kGPIO_DigitalOutput,
        .outputLogic = 0U,
    };
    /* Initialize GPIO functionality on pin */
    GPIO_PinInit(GPIO, 0, 7, &SPILCD_IOL_config);//LCD_BLK
    GPIO_PinInit(GPIO, 1, 6, &SPILCD_IOH_config);//LCD_DC
    GPIO_PinInit(GPIO, 1, 7, &SPILCD_IOH_config);//LCD_RST
    GPIO_PinInit(GPIO, 1,18, &SPILCD_IOH_config);//LCD_CS
    GPIO_PinInit(GPIO, 1,19, &SPILCD_IOH_config);//LCD_CLK
    GPIO_PinInit(GPIO, 0, 6, &SPILCD_IOH_config);//LCD_MOSI
    
    GPIO_PinInit(GPIO, 1,13, &SPILCD_IOH_config);//RGB_MOSI
    
    GPIO_PinInit(GPIO, 1,8, &SPILCD_IOH_config); //FLASH_CS
    GPIO_PinInit(GPIO, 1,9, &SPILCD_IN_config); //FLASH_MISO
    GPIO_PinInit(GPIO, 0,12, &SPILCD_IOH_config);//FLASH_CLK
    GPIO_PinInit(GPIO, 0,13, &SPILCD_IOH_config);//FLASH_MOSI
    
    const uint32_t spilcd_ioc = (/* Selects pull-up function */
                              IOCON_PIO_MODE_PULLUP |
                              /* Enable hysteresis */
                              IOCON_PIO_HYS_EN |
                              /* Input not invert */
                              IOCON_PIO_INV_DI |
                              /* Disables Open-drain function */
                              IOCON_PIO_OD_DI |
                              /* Bypass input filter */
                              IOCON_PIO_SMODE_BYPASS |
                              /* IOCONCLKDIV0 */
                              IOCON_PIO_CLKDIV0);
    IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO0_7,  spilcd_ioc);
    IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO1_6,  spilcd_ioc);
    IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO1_7,  spilcd_ioc);
    IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO1_18, spilcd_ioc);    
    
    /* Enables clock for switch matrix.: enable */
    const uint32_t SPI_LCD_CLK = (/* Selects pull-up function */
                                    IOCON_PIO_MODE_PULLUP |
                                    /* Enable hysteresis */
                                    IOCON_PIO_HYS_EN |
                                    /* Input not invert */
                                    IOCON_PIO_INV_DI |
                                    /* Disables Open-drain function */
                                    IOCON_PIO_OD_DI |
                                    /* Bypass input filter */
                                    IOCON_PIO_SMODE_BYPASS |
                                    /* IOCONCLKDIV0 */
                                    IOCON_PIO_CLKDIV0);
    IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO1_19, SPI_LCD_CLK);

    const uint32_t SPI_LCD_MOSI = (/* Selects pull-up function */
                                    IOCON_PIO_MODE_PULLUP |
                                    /* Enable hysteresis */
                                    IOCON_PIO_HYS_EN |
                                    /* Input not invert */
                                    IOCON_PIO_INV_DI |
                                    /* Disables Open-drain function */
                                    IOCON_PIO_OD_DI |
                                    /* Bypass input filter */
                                    IOCON_PIO_SMODE_BYPASS |
                                    /* IOCONCLKDIV0 */
                                    IOCON_PIO_CLKDIV0);
    IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO0_6, SPI_LCD_MOSI);
    
    IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO1_13, SPI_LCD_MOSI);  //RGB_IO=MOSI
    
    const uint32_t SPI_MISO = (/* Selects pull-up function */
                                    0 |
                                    /* Enable hysteresis */
                                    IOCON_PIO_HYS_EN |
                                    /* Input not invert */
                                    IOCON_PIO_INV_DI |
                                    /* Disables Open-drain function */
                                    IOCON_PIO_OD_DI |
                                    /* Bypass input filter */
                                    IOCON_PIO_SMODE_BYPASS |
                                    /* IOCONCLKDIV0 */
                                    IOCON_PIO_CLKDIV0);
    IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO1_9, SPI_MISO);   //f_miso

    IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO1_8,   spilcd_ioc);    //f_cs
    IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO0_12,  spilcd_ioc);   //f_clk
    IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO0_13,  spilcd_ioc);   //f_mosi
    
    CLOCK_EnableClock(kCLOCK_Swm);
    
    SWM_SetMovablePinSelect(SWM0, kSWM_SPI0_SCK,   kSWM_PortPin_P1_19);
    SWM_SetMovablePinSelect(SWM0, kSWM_SPI0_MOSI,  kSWM_PortPin_P0_6);
    
    SWM_SetMovablePinSelect(SWM0, kSWM_SPI1_MOSI,  kSWM_PortPin_P1_13);
    
    /* Disable clock for switch matrix. */
    CLOCK_DisableClock(kCLOCK_Swm);
    
    spi_master_config_t userConfig = {0};
    uint32_t srcFreq               = 0U;
    /* Note: The slave board using interrupt way, slave will spend more time to write data
     *       to TX register, to prevent TX data missing in slave, we will add some delay between
     *       frames and capture data at the second edge, this operation will make the slave
     *       has more time to prapare the data.
     */
    
    SPI_MasterGetDefaultConfig(&userConfig);
    userConfig.baudRate_Bps           = 30000000;
    userConfig.sselNumber             = kSPI_Ssel0Assert;
    userConfig.clockPolarity          = kSPI_ClockPolarityActiveHigh;
    userConfig.clockPhase             = kSPI_ClockPhaseFirstEdge;
    userConfig.direction              = kSPI_MsbFirst;
    userConfig.delayConfig.preDelay   = 0x0U;
    userConfig.delayConfig.postDelay  = 0x0U;
    userConfig.delayConfig.frameDelay = 0x0U;
    userConfig.delayConfig.transferDelay = 0x0U;
    srcFreq                           = CLOCK_GetFreq(kCLOCK_MainClk);
    SPI_MasterInit(SPI0, &userConfig, srcFreq);
    
    userConfig.baudRate_Bps           = 6000000;
    SPI_MasterInit(SPI1, &userConfig, srcFreq);

}




SPI_Type * spi_table[2]=
{
    SPI0,
    SPI1,
};

void spi_pre_h(void)
{
    CLOCK_EnableClock(kCLOCK_Swm);
    SWM_SetMovablePinSelect(SWM0, kSWM_SPI1_MISO,  kSWM_PortPin_P1_9);  //F_MISO
    SWM_SetMovablePinSelect(SWM0, kSWM_SPI1_MOSI,  kSWM_PortPin_P0_13); //F_MOSI
    SWM_SetMovablePinSelect(SWM0, kSWM_SPI1_SCK ,  kSWM_PortPin_P0_12); //F_CLK
    CLOCK_DisableClock(kCLOCK_Swm);
    SPI_MasterSetBaudRate(SPI1,30000000, CLOCK_GetFreq(kCLOCK_MainClk));
}

void spi_pre_l(void)
{
    CLOCK_EnableClock(kCLOCK_Swm);
    SWM_SetMovablePinSelect(SWM0, kSWM_SPI1_MOSI,  kSWM_PortPin_P1_13); //RGB_IO
    SWM_SetMovablePinSelect(SWM0, kSWM_SPI1_MISO,  0XFF);  //
    SWM_SetMovablePinSelect(SWM0, kSWM_SPI1_SCK ,  0XFF);  //
    CLOCK_DisableClock(kCLOCK_Swm);
    SPI_MasterSetBaudRate(SPI1,6000000, CLOCK_GetFreq(kCLOCK_MainClk));
}

void spi_writebyte(uint8_t index,uint8_t TxData)
{
    spi_table[index]->TXDATCTL = TxData | 0X077E0000;
    while ((spi_table[index]->STAT & SPI_STAT_TXRDY_MASK) == 0U){;}
}

uint8_t spi_readbyte(uint8_t index)
{
    uint8_t re;
    spi_table[index]->TXDATCTL = 0xff | 0X073E0000;
    while ((spi_table[index]->STAT & SPI_STAT_RXRDY_MASK) == 0U){;}
    re = spi_table[index]->RXDAT & 0XFF;
    return re;
}

屏幕也要初始,再來(lái)初始化lcd屏幕,初始化代碼都是網(wǎng)上找的,找準(zhǔn)型號(hào)就行。

void spilcd_init(void)
{
        spilcd_gpio_init();
        
        LCD_RST_CLR();
        delay_ms(10);
        LCD_RST_SET();
        delay_ms(10);
        
        LCD_BLK_SET();
    delay_ms(10);
    
//        LCD_CS_CLR();
    
    LCD_WR_REG(0xFE);
        LCD_WR_REG(0xEF);

        LCD_WR_REG(0x84);
        LCD_WR_DATA8(0x40);


        LCD_WR_REG(0xB6);
        LCD_WR_DATA8(0x00);
        LCD_WR_DATA8(0x20);

        LCD_WR_REG(0x36);
        if(USE_HORIZONTAL==0)LCD_WR_DATA8(0x08);
        else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC8);
        else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x68);
        else LCD_WR_DATA8(0xA8);

        LCD_WR_REG(0x3A);
        LCD_WR_DATA8(0x05);

        LCD_WR_REG(0xC3);
        LCD_WR_DATA8(0x13);
        LCD_WR_REG(0xC4);
        LCD_WR_DATA8(0x13);

        LCD_WR_REG(0xC9);
        LCD_WR_DATA8(0x22);


        LCD_WR_REG(0xF0);
        LCD_WR_DATA8(0x45);
        LCD_WR_DATA8(0x09);
        LCD_WR_DATA8(0x08);
        LCD_WR_DATA8(0x08);
        LCD_WR_DATA8(0x26);
         LCD_WR_DATA8(0x2A);

         LCD_WR_REG(0xF1);
         LCD_WR_DATA8(0x43);
         LCD_WR_DATA8(0x70);
         LCD_WR_DATA8(0x72);
         LCD_WR_DATA8(0x36);
         LCD_WR_DATA8(0x37);
         LCD_WR_DATA8(0x6F);


         LCD_WR_REG(0xF2);
         LCD_WR_DATA8(0x45);
         LCD_WR_DATA8(0x09);
         LCD_WR_DATA8(0x08);
         LCD_WR_DATA8(0x08);
         LCD_WR_DATA8(0x26);
         LCD_WR_DATA8(0x2A);

         LCD_WR_REG(0xF3);
         LCD_WR_DATA8(0x43);
         LCD_WR_DATA8(0x70);
         LCD_WR_DATA8(0x72);
         LCD_WR_DATA8(0x36);
         LCD_WR_DATA8(0x37);
         LCD_WR_DATA8(0x6F);

        LCD_WR_REG(0xE8);
        LCD_WR_DATA8(0x34);

        LCD_WR_REG(0x66);
        LCD_WR_DATA8(0x3C);
        LCD_WR_DATA8(0x00);
        LCD_WR_DATA8(0xCD);
        LCD_WR_DATA8(0x67);
        LCD_WR_DATA8(0x45);
        LCD_WR_DATA8(0x45);
        LCD_WR_DATA8(0x10);
        LCD_WR_DATA8(0x00);
        LCD_WR_DATA8(0x00);
        LCD_WR_DATA8(0x00);

        LCD_WR_REG(0x67);
        LCD_WR_DATA8(0x00);
        LCD_WR_DATA8(0x3C);
        LCD_WR_DATA8(0x00);
        LCD_WR_DATA8(0x00);
        LCD_WR_DATA8(0x00);
        LCD_WR_DATA8(0x01);
        LCD_WR_DATA8(0x54);
        LCD_WR_DATA8(0x10);
        LCD_WR_DATA8(0x32);
        LCD_WR_DATA8(0x98);

        LCD_WR_REG(0x35);
        LCD_WR_REG(0x21);

        LCD_WR_REG(0x11);
    LCD_CS_SET();
        delay_ms(120);
        LCD_WR_REG(0x29);
    LCD_CS_SET();
        delay_ms(20);
}

屏幕初始化之后,暫時(shí)還看不到屏幕效果,下面就是對(duì)屏幕填充顏色和繪制圖片了,代碼:

void spilcd_draw_bitmap(uint16_t x,uint16_t y,uint16_t w,uint16_t h,const uint8_t *pbuff)
{
    uint8_t data[4];
    uint16_t x1,y1,x2,y2;
    uint32_t send_size   = w * h * 2;
    x1 = x;
    y1 = y;
    x2 = x+w-1;
    y2 = y+h-1;
//    LCD_CS_CLR();
    /*Column addresses*/
    SPILCD_WriteCmd(0x2A);
    data[0] = (x1 >> 8) & 0xFF;
    data[1] = x1 & 0xFF;
    data[2] = (x2 >> 8) & 0xFF;
    data[3] = x2 & 0xFF;
    SPILCD_WriteData(data[0]);
    SPILCD_WriteData(data[1]);
    SPILCD_WriteData(data[2]);
    SPILCD_WriteData(data[3]);

    /*Page addresses*/
    SPILCD_WriteCmd(0x2B);
    data[0] = (y1 >> 8) & 0xFF;
    data[1] = y1 & 0xFF;
    data[2] = (y2 >> 8) & 0xFF;
    data[3] = y2 & 0xFF;
    SPILCD_WriteData(data[0]);
    SPILCD_WriteData(data[1]);
    SPILCD_WriteData(data[2]);
    SPILCD_WriteData(data[3]);

    /*Memory write*/
    SPILCD_WriteCmd(0x2C);
    SPILCD_WriteMultiData(pbuff, send_size);
    LCD_CS_SET();
}

void spilcd_fill(uint16_t x,uint16_t y,uint16_t w,uint16_t h,uint16_t color)
{
    uint8_t data[4];
    uint16_t x1,y1,x2,y2;
    uint32_t send_size   = w * h;
    x1 = x;
    y1 = y;
    x2 = x+w-1;
    y2 = y+h-1;

    /*Column addresses*/
    SPILCD_WriteCmd(0x2A);
    data[0] = (x1 >> 8) & 0xFF;
    data[1] = x1 & 0xFF;
    data[2] = (x2 >> 8) & 0xFF;
    data[3] = x2 & 0xFF;
    SPILCD_WriteData(data[0]);
    SPILCD_WriteData(data[1]);
    SPILCD_WriteData(data[2]);
    SPILCD_WriteData(data[3]);

    /*Page addresses*/
    SPILCD_WriteCmd(0x2B);
    data[0] = (y1 >> 8) & 0xFF;
    data[1] = y1 & 0xFF;
    data[2] = (y2 >> 8) & 0xFF;
    data[3] = y2 & 0xFF;
    SPILCD_WriteData(data[0]);
    SPILCD_WriteData(data[1]);
    SPILCD_WriteData(data[2]);
    SPILCD_WriteData(data[3]);

    /*Memory write*/
    SPILCD_WriteCmd(0x2C);
    LCD_DC_SET();
    while(send_size--)
    {
        SPI0->TXDATCTL = ((color>>8)&0xff) | 0X077E0000;
        while ((SPI0->STAT & SPI_STAT_TXRDY_MASK) == 0U){;} 
        SPI0->TXDATCTL = (color&0xff) | 0X077E0000;
        while ((SPI0->STAT & SPI_STAT_TXRDY_MASK) == 0U){;} 
    }
    LCD_CS_SET();
}

好了,下面就可以調(diào)用填充顏色和繪制圖片測(cè)試了。

main函數(shù):

#include <stdio.h>
#include "main.h"

#include "board.h"
#include "clock_config.h"
#include "pin_mux.h"

#include "drv_gpio.h"
#include "drv_spi.h"
#include "drv_i2c.h"

#include "drv_spilcd.h"
#include "picture.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/


/*******************************************************************************
 * Prototypes
 ******************************************************************************/


/*******************************************************************************
 * Variables
 ******************************************************************************/
volatile uint32_t g_systickCounter;
volatile uint32_t rgb_number;
fsm_pt_t    pt_key_scan;
/*******************************************************************************
 * Code
 ******************************************************************************/
void SysTick_Handler(void)
{
    if(pt_key_scan.time)    pt_key_scan.time--;
    if (g_systickCounter)   g_systickCounter--;
}

void SysTick_DelayTicks(uint32_t n)
{
    g_systickCounter = n;
    while (g_systickCounter != 0U){;}
}


void keyscan_fsm(fsm_pt_t *pt)
{

    PT_BEGIN(pt);
    //init

    //loop
    while(1)
    {
        if(GPIO->B[1][4] == 0)  //SW0
        {
            if(rgb_number < 1000)  rgb_number ++;
            DbgConsole_Printf("key:%drn",rgb_number);
        }
        
        if(GPIO->B[0][15] == 0)  //SW1
        {
            if(rgb_number)  rgb_number --;
            DbgConsole_Printf("key:%drn",rgb_number);
        }
        PT_WAIT_TIME(pt,10);        
    }
    PT_END(pt);
}


/*!
 * @brief Main function
 */
int main(void)
{
    BOARD_InitBootClocks();
    SysTick_Config(SystemCoreClock / 1000U);
    init_cycle_counter(true);
    
    BOARD_InitBootPins();
    drv_gpio_init();
    BOARD_InitDebugConsole();
    
    drv_spi_gpio_init();
    drv_i2c_gpio_init();
    
    DbgConsole_Printf("LPC845 Mooncake Board Test!rn");
    
    spilcd_init();
    
    __cycleof__("lcd_fresh_time(n/30000=X ms):")
    {
        spilcd_fill(0,0,240,240,LCD_RED);
    }
    delay_ms(500);
    __cycleof__("lcd_fresh_time(n/30000=X ms):")
    {
        spilcd_fill(0,0,240,240,LCD_GREEN);
    }
    delay_ms(500);
    __cycleof__("lcd_fresh_time(n/30000=X ms):")
    {
        spilcd_fill(0,0,240,240,LCD_BLUE);
    }
    delay_ms(500);
    __cycleof__("show 40*40 picture time:")
    {
        spilcd_draw_bitmap(100,100,40,40,(uint8_t *)gImage_1);
    }
    delay_ms(500);
        
        while(1)
        {
        keyscan_fsm(&pt_key_scan);
        GPIO_PortToggle(GPIO, 0, 1u << 0);  //led燈
        }
}

效果如下:

順便對(duì)刷屏?xí)r間做了測(cè)量,填充整屏花了123ms左右。LPC845使用30MHz。刷屏比較慢。需要多優(yōu)化一下了。下面測(cè)量的數(shù)據(jù)是時(shí)鐘周期數(shù),刷屏?xí)r間根據(jù)周期數(shù)除以時(shí)鐘頻率30MHz。由于LPC845的falsh不夠,就沒有刷整屏圖片了。

所有資料都在下面壓縮包了。有些需要安裝一下pack。

lpc845_mooncake.zip (16.41 MB)

  • lpc845_mooncake.zip

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊(cè) ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
LTC6993CS6-2#TRMPBF 1 Analog Devices Inc LTC6993CS6-2#TRMPBF

ECAD模型

下載ECAD模型
$3.63 查看
CC3100MODR11MAMOBT 1 Texas Instruments SimpleLink&trade; Wi-Fi CERTIFIED&trade; network processor module for Internet-of-Things with 2 TLS/SSL 63-QFM -20 to 70
$17.55 查看
S29AL016J70TFI020 1 Cypress Semiconductor Flash, 1MX16, 70ns, PDSO48, TSOP-48
$10.3 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜