打印
[资源分享]

【杰发科技AC7840x测评】硬件SPI驱动LCD屏

[复制链接]
648|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lulugl|  楼主 | 2023-11-29 12:57 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
#申请原创# #有奖活动#[url=home.php?mod=space&uid=760190]@21小跑堂 [/url]
【简介】
AC7840xSPI (Serial Peripheral Interface,串行外设接口)是一种全双工协议的外设总线,通过片选信号(CS0、CS1、CS2、CS3)、时钟线(SCK)、数据线(SIN、SOUT)进行数据传输。SPI 模块支持单主机-单从机 通讯,也支持单主机-多从机通讯,通讯总线通过片选信号最多可连接 4 个从机设备。
此次的实验在官方提供的spi例程上,移植GC9306的驱动程。
【移植要点】
tft的spi的移植,主要是实现spi写一位数据的指令。其次是重写DC(数据、命令),RESET的控制IO,BLK背光的打开与关闭或者是亮度调节。
【实验的硬件】
1、AC7840x开发板
2、GC9306xTFT显示屏
【硬件的连接】
//              ----------------------------------------------------------------
//              GND   电源地
//              VCC   3.3v电源
//              SCL   PB2(SCLK)
//              SDA   PB1(MOSI)
//              RES   PB5  
//              DC    PB4  
//              CS    PE2
//              BLK   PB8  
//              SDI   PB3
//              ----------------------------------------------------------------
【实验步骤】
1、复制一份SPI的例程,并重命名为05_SPI_Master_Polling_tft:

2、复制一份在其他单片机上的tft驱动包到工程目录下面。

3、打开工程,新建bsp分组,把tft下面的两个文件添加进工程,并且,把头文件添加进工程。


4、在spi中添加DC、RST、BLK引脚的端口、引用的宏定义以及写高低电平的宏定义:
<p>#define PORT_TFT_DC         (PORTB)</p><p>#define PORT_TFT_RES        (PORTB)</p><p>#define PORT_TFT_BLK        (PORTB)</p><p>#define GPIO_TFT_DC         (GPIOB)</p><p>#define GPIO_TFT_RES        (GPIOB)</p><p>#define GPIO_TFT_BLK        (GPIOB)</p><p>#define PIN_TFT_DC          (4U)</p><p>#define PIN_TFT_RES         (5U)</p><p>#define PIN_TFT_BLK         (8U)</p><p>//-----------------LCD端口定义----------------</p><p>#define LCD_RES_Clr  do{GPIO_DRV_WritePin(GPIO_TFT_RES, PIN_TFT_RES, 0);}while(0) //RES</p><p>#define LCD_RES_Set  do{GPIO_DRV_WritePin(GPIO_TFT_RES, PIN_TFT_RES, 1);}while(0) </p><p>#define LCD_DC_Clr   do{GPIO_DRV_WritePin(GPIO_TFT_DC, PIN_TFT_DC, 0);}while(0)//DC</p><p>#define LCD_DC_Set   do{GPIO_DRV_WritePin(GPIO_TFT_DC, PIN_TFT_DC, 1);}while(0)</p><p>#define LCD_BLK_Clr  do{GPIO_DRV_WritePin(GPIO_TFT_BLK, PIN_TFT_BLK, 0);}while(0)//BLK</p><p>#define LCD_BLK_Set  do{GPIO_DRV_WritePin(GPIO_TFT_BLK, PIN_TFT_BLK, 1);}while(0)</p>

5、在spi配置与初始化中添加TFT屏的DC、RES、BLK的配置,配置为GPIO复用、输出模式。
/* ====================================  Functions declaration  ===================================== */
<p>/*!</p><p> * [url=home.php?mod=space&uid=247401]@brief[/url] SPI模块引脚初始化配置,主机模式</p><p> *</p><p> * @param none</p><p> *</p><p> * [url=home.php?mod=space&uid=266161]@return[/url] none</p><p> */</p><p>static void SPI_Init_Gpio(void)</p><p>{</p><p>    GPIO_DRV_SetMuxModeSel(PORT_SPI_SCK, PIN_SPI_SCK, PORT_MUX_ALT3);        /*! SCK */</p><p>    GPIO_DRV_SetMuxModeSel(PORT_SPI_SOUT, PIN_SPI_SOUT, PORT_MUX_ALT3);      /*! SOUT */</p><p>    GPIO_DRV_SetMuxModeSel(PORT_SPI_SIN, PIN_SPI_SIN, PORT_MUX_ALT3);        /*! SIN */</p><p>    GPIO_DRV_SetMuxModeSel(PORT_SPI_CS, PIN_SPI_CS, PORT_MUX_ALT2);          /*! CS */</p><p>GPIO_DRV_SetMuxModeSel(PORT_TFT_DC, PIN_TFT_DC, PORT_MUX_AS_GPIO);       /*! DC */</p><p> GPIO_DRV_SetMuxModeSel(PORT_TFT_RES, PIN_TFT_RES, PORT_MUX_AS_GPIO);     /*! RES */</p><p> GPIO_DRV_SetMuxModeSel(PORT_TFT_BLK, PIN_TFT_BLK, PORT_MUX_AS_GPIO);     /*! BLK */</p><p> GPIO_DRV_SetPinDirection(GPIO_TFT_DC, PIN_TFT_DC, 1);                   /*设置DC为输出*/</p><p> GPIO_DRV_SetPinDirection(GPIO_TFT_RES, PIN_TFT_RES, 1);                 /*设置RES为输出*/</p><p> GPIO_DRV_SetPinDirection(GPIO_TFT_BLK, PIN_TFT_BLK, 1);                 /*设置BLK为输出*/</p><p>}</p>

6、修改spi发送一个数据、命令的函数:
<p>/******************************************************************************</p><p>      函数说明:LCD串行数据写入函数</p><p>      入口数据:dat  要写入的串行数据</p><p>      返回值:  无</p><p>******************************************************************************/</p><p>void LCD_Writ_Bus(uint8_t dat)</p><p>{</p><p>//status_t ret = STATUS_ERROR;</p><p>g_spiTxBuff1[0] = dat;</p><p>//SPI_DRV_MasterTransferBlocking(SPI_INSTANCE, g_spiTxBuff1, g_spiRxBuff1, 1, 1);     /*! SPI通信 */</p><p>SPI_DRV_MasterTransfer(SPI_INSTANCE, g_spiTxBuff1, g_spiRxBuff1, 1);    /*! SPI通信 */</p><p>  while (SPI_DRV_MasterGetTransferStatus(SPI_INSTANCE, NULL) == STATUS_BUSY);</p><p>}</p><p>/******************************************************************************</p><p>      函数说明:LCD写入数据</p><p>      入口数据:dat 写入的数据</p><p>      返回值:  无</p><p>******************************************************************************/</p><p>void LCD_WR_DATA8(uint8_t dat)</p><p>{</p><p>LCD_Writ_Bus(dat);</p><p>}</p><p>/******************************************************************************</p><p>      函数说明:LCD写入数据</p><p>      入口数据:dat 写入的数据</p><p>      返回值:  无</p><p>******************************************************************************/</p><p>void LCD_WR_DATA(uint16_t dat)</p><p>{</p><p>//LCD_Writ_Bus(dat>>8);</p><p>//LCD_Writ_Bus(dat);</p><p>LCD_DC_Set;//写数据</p><p>g_spiTxBuff1[0] = dat>>8;</p><p>g_spiTxBuff1[1] = dat;</p><p>//SPI_DRV_MasterTransferBlocking(SPI_INSTANCE, g_spiTxBuff1, g_spiRxBuff1, 2, 1);     /*! SPI通信 */</p><p>SPI_DRV_MasterTransfer(SPI_INSTANCE, g_spiTxBuff1, g_spiRxBuff1, 2);    /*! SPI通信 */</p><p>  while (SPI_DRV_MasterGetTransferStatus(SPI_INSTANCE, NULL) == STATUS_BUSY);</p><p>}</p>

7、修改spi配置函数,根据屏的用户手册,修改为设置数据采样相位,第2个边沿采样数据、设置SCK工作时极性,工作时SCK为低。
<p>spi_master_config_t spiMasteConfig =</p><p>{</p><p>    .bitsPerSec = 20000000UL,                    /*! 设置SPI波特率*/</p><p>    .whichPcs = SPI_PCS2,                       /*! 设置SPI片选引脚*/</p><p>    .pcsPolarity = SPI_ACTIVE_LOW,              /*! 设置SPI片选低有效*/</p><p>    .isPcsContinuous = true,                    /*! 设置片选连续模式*/</p><p>    .bitcount = 8UL,                            /*! SPI 帧长度,支持 4~32 bits*/</p><p>    .spiSrcClk = 60000000UL,                    /*! SPI时钟源频率*/</p><p>    .clkPhase = SPI_CLOCK_PHASE_2ND_EDGE,       /*! 设置数据采样相位,第2个边沿采样数据*/</p><p>    .clkPolarity = SPI_SCK_ACTIVE_LOW,         /*! 设置SCK工作时极性,工作时SCK为低*/</p><p>    .msbFirst = true,                           /*! 选择从最高位开始收发*/</p><p>    .transferType = SPI_USING_INTERRUPTS,       /*! 选择通信类型为中断方式*/</p><p>    .rxDMAChannel = 1UL,                        /*! 设置SPI DMA接收通道,若未使用DMA方式传输,则该配置可忽略*/</p><p>    .txDMAChannel = 0UL,                        /*! 设置SPI DMA发送通道,若未使用DMA方式传输,则该配置可忽略*/</p><p>    .callback = NULL,                           /*! 注册回调函数 */</p><p>    .callbackParam = NULL,                      /*! 回调函数参数 */</p><p>};</p>

8、在主函数中添加头文件的引用,并加入测函数如下:
int main(void)
<p>{</p><p>    SystemClock_Config();                                                                                           /*! 时钟初始化 */</p><p>    InitDebug();                                                                                                    /*! 初始化调试串口 */</p><p>    GPIO_Init();                                                                                                    /*! GPIO Init */</p><p>    SPI_Master_Init();                                                                                              /*! SPI主机初始化 */</p><p>IVO28_GC9306_P4();</p><p>LCD_Fill(0,0,LCD_W,LCD_H,BLACK);</p><p>LCD_Fill(0,0,LCD_W,LCD_H,WHITE);</p><p>LCD_ShowString(10,10, "HELLO AC7840x",BLUE,WHITE,32,0);</p><p>    while (1)</p><p>    {</p><p>    }</p><p>}</p>

【实验效果】

【讨论】
官方的示例给出spi发送的三种方式,我测试了中断与阻塞式的发送,速度差不多,spi最高可以设置40M的速度。建议在发送数据是要用块来发送,如果一位一位的发送,速度会慢得吓人,用逻辑分析仪看了一下时序,间隔1ms多,分析了一下原因,因为官方的spi驱动库进行了封装,有很多的判断,所以效率不高。
如果要追求速度,还需要自己用寄存器进行读写操作才能达到最好的效果。
附工程源码:
Master_Polling_tft.zip (107.38 KB)

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

138

主题

675

帖子

6

粉丝