秦天qintian0303 发表于 2022-8-11 18:10

【AT32WB415测评】03 SPI驱动TFT液晶屏

<div class='showpostmsg'><p><span style="font-size:16px;">03 SPI驱动TFT液晶屏</span></p>

<p><strong><span style="font-size:16px;">前言</span></strong></p>

<p><span style="font-size:16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;上文已经实现MCU的IO口、定时器、外部中断等操作,在此基础上我们来实现TFT液晶屏的驱动,用于后边测试的状态张氏。</span></p>

<p><strong><span style="font-size:16px;">目标</span></strong></p>

<p><span style="font-size:16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;软硬件驱动TFT液晶屏,实现页面展示。</span></p>

<p><strong><span style="font-size:16px;">实现</span></strong></p>

<p><span style="font-size:16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;本次使用的液晶屏是1.54吋,IPS高清显示,分辨率240*240,驱动芯片为ST7789,支持MCU和SPI两种通信方式,本次通过SPI方式驱动液晶屏,相对来说分辨率不低,所以通过软硬件两种方式可以轻松看出来比较明显的区别,液晶屏SPI通信时只能作为从机接收数据,所以只用到了MOSI和SCK,CS和RS通过软件控制,复位和背光控制通过软件控制。</span></p>

<p><span style="font-size:16px;">相应宏定义</span></p>

<pre>
<code>#define MOSI_OUT0       gpio_bits_reset(GPIOB,GPIO_PINS_15)
#define MOSI_OUT1       gpio_bits_set(GPIOB,GPIO_PINS_15)

#define CLK_OUT0      gpio_bits_reset(GPIOB,GPIO_PINS_13)
#define CLK_OUT1      gpio_bits_set(GPIOB,GPIO_PINS_13)

#define CS_OUT0       gpio_bits_reset(GPIOA,GPIO_PINS_4)
#define CS_OUT1       gpio_bits_set(GPIOA,GPIO_PINS_4)

#define TFT_RS_reset            gpio_bits_reset(GPIOA,GPIO_PINS_5)
#define TFT_RS_set            gpio_bits_set(GPIOA,GPIO_PINS_5)
#define TFT_RESET_reset         gpio_bits_reset(GPIOA,GPIO_PINS_3)
#define TFT_RESET_set         gpio_bits_set(GPIOA,GPIO_PINS_3)
#define TFT_BL_SET            gpio_bits_set(GPIOA,GPIO_PINS_2)
#define TFT_BL_RESET            gpio_bits_reset(GPIOA,GPIO_PINS_2)</code></pre>

<p>&nbsp;</p>

<p><span style="font-size:16px;">软件模拟SPI控制:</span></p>

<p><!--5f39ae17-8c62-4a45-bc43-b32064c9388a:W3siYmxvY2tJZCI6IjAwNzAtMTY2MDEzNjc2Mjk2OSIsImJsb2NrVHlwZSI6InBhcmFncmFwaCIsInN0eWxlcyI6eyJ0ZXh0LWluZGVudCI6MCwiYWxpZ24iOiJsZWZ0IiwiaW5kZW50IjowLCJsaW5lLWhlaWdodCI6MS43NSwiYmFjay1jb2xvciI6IiIsInBhZGRpbmciOiIifSwidHlwZSI6InBhcmFncmFwaCIsInJpY2hUZXh0Ijp7ImRhdGEiOlt7ImNoYXIiOiLova8ifSx7ImNoYXIiOiLku7YifSx7ImNoYXIiOiLmqKEifSx7ImNoYXIiOiLmi58ifSx7ImNoYXIiOiJTIn0seyJjaGFyIjoiUCJ9LHsiY2hhciI6IkkifSx7ImNoYXIiOiLmjqcifSx7ImNoYXIiOiLliLYifSx7ImNoYXIiOiLvvJoifV0sImlzUmljaFRleHQiOnRydWUsImtlZXBMaW5lQnJlYWsiOnRydWV9fV0=--></p>

<pre>
<code>void SPI_IOInit(void)
{
gpio_init_type gpio_init_struct;
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);

gpio_init_struct.gpio_drive_strength= GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_out_type      = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode            = GPIO_MODE_OUTPUT;
gpio_init_struct.gpio_pins            = GPIO_PINS_13|GPIO_PINS_15;
gpio_init_struct.gpio_pull            = GPIO_PULL_NONE;
gpio_init(GPIOB, &amp;gpio_init_struct);

gpio_init_struct.gpio_drive_strength= GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_out_type      = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode            = GPIO_MODE_OUTPUT;
gpio_init_struct.gpio_pull            = GPIO_PULL_UP;
gpio_init_struct.gpio_pins            = GPIO_PINS_4|GPIO_PINS_5|GPIO_PINS_3;
gpio_init(GPIOA, &amp;gpio_init_struct);

gpio_init_struct.gpio_drive_strength= GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_out_type      = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode            = GPIO_MODE_OUTPUT;
gpio_init_struct.gpio_pull            = GPIO_PULL_DOWN;
gpio_init_struct.gpio_pins            = GPIO_PINS_2;
gpio_init(GPIOA, &amp;gpio_init_struct);

CLK_OUT0;
MOSI_OUT0;
CS_OUT0;
TFT_RS_reset;
TFT_RESET_reset;
TFT_BL_RESET;
}

void SPI_Send_Data(uint8_t Data)
{

CS_OUT0;                                                            //选中该从机
delay_us(2);

uint8_t i;
for (i = 0;i &lt; 8;i++)
{
    if ((Data &lt;&lt; i) &amp; 0x80)
    {
      MOSI_OUT1;
      CLK_OUT0;//rising edge
      CLK_OUT1;
    }
    else
    {
      MOSI_OUT0;
      CLK_OUT0;//rising edge
      CLK_OUT1;
    }
}

CS_OUT1;                                                            

}</code></pre>

<p>硬件SPI控制:</p>

<pre>
<code>void SPI_IOInit(void)
{
gpio_init_type gpio_initstructure;
spi_init_type spi_init_struct;

crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);

/* software cs, pa4 as a general io to control flash cs */
gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;
gpio_initstructure.gpio_pull         = GPIO_PULL_UP;
gpio_initstructure.gpio_mode         = GPIO_MODE_OUTPUT;
gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_initstructure.gpio_pins         = GPIO_PINS_4|GPIO_PINS_5|GPIO_PINS_3;
gpio_init(GPIOA, &amp;gpio_initstructure);

gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;
gpio_initstructure.gpio_mode         = GPIO_MODE_OUTPUT;
gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_initstructure.gpio_pull         = GPIO_PULL_DOWN;
gpio_initstructure.gpio_pins         = GPIO_PINS_2;
gpio_init(GPIOA, &amp;gpio_initstructure);

CS_OUT0;
TFT_RS_reset;
TFT_RESET_reset;
TFT_BL_RESET;
/* sck */
gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;
gpio_initstructure.gpio_pull         = GPIO_PULL_UP;
gpio_initstructure.gpio_mode         = GPIO_MODE_MUX;
gpio_initstructure.gpio_pins         = GPIO_PINS_13;
gpio_init(GPIOB, &amp;gpio_initstructure);
/* mosi */
gpio_initstructure.gpio_pull         = GPIO_PULL_DOWN;
gpio_initstructure.gpio_mode         = GPIO_MODE_MUX;
gpio_initstructure.gpio_pins         = GPIO_PINS_15;
gpio_init(GPIOB, &amp;gpio_initstructure);

crm_periph_clock_enable(CRM_SPI2_PERIPH_CLOCK, TRUE);
spi_default_para_init(&amp;spi_init_struct);
spi_init_struct.transmission_mode   = SPI_TRANSMIT_FULL_DUPLEX;
spi_init_struct.master_slave_mode   = SPI_MODE_MASTER;
spi_init_struct.mclk_freq_division    = SPI_MCLK_DIV_8;
spi_init_struct.first_bit_transmission = SPI_FIRST_BIT_MSB;
spi_init_struct.frame_bit_num         = SPI_FRAME_8BIT;
spi_init_struct.clock_polarity      = SPI_CLOCK_POLARITY_HIGH;
spi_init_struct.clock_phase         = SPI_CLOCK_PHASE_2EDGE;
spi_init_struct.cs_mode_selection   = SPI_CS_SOFTWARE_MODE;
spi_init(SPI2, &amp;spi_init_struct);
spi_enable(SPI2, TRUE);
}

void SPI_Send_Data(uint8_t Data)
{

CS_OUT0;                                                            //选中该从机
delay_us(1);

spi_i2s_data_transmit(SPI2, Data);
while(spi_i2s_flag_get(SPI2, SPI_I2S_TDBE_FLAG) == RESET);

delay_us(1);
CS_OUT1;                                                            

}</code></pre>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 在软件模拟驱动成功后切换到硬件SPI时出现了一个小插曲,居然驱动失败了,通过不断的修改测试发现出现在了CS_OUT1;这个操作,可能上升太快导致异常,在之前加了一个delay_us(1);后驱动正常。&nbsp;</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;直接使用#if + #elif + #endif进行选择性代码编写,方便切换。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 具体的tft的驱动代码可以结合实际使用的屏进行设计,这块一般都是使用的厂家提供的驱动代码。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 驱动成功:</p>

<p></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

lugl4313820 发表于 2022-8-11 21:38

<p>只看到背光亮了,没见有显示,是不是上传图片有误?</p>

秦天qintian0303 发表于 2022-8-11 23:03

lugl4313820 发表于 2022-8-11 21:38
只看到背光亮了,没见有显示,是不是上传图片有误?

<p>只是点亮了,验证SPI功能正常</p>
页: [1]
查看完整版本: 【AT32WB415测评】03 SPI驱动TFT液晶屏