【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;"> 上文已经实现MCU的IO口、定时器、外部中断等操作,在此基础上我们来实现TFT液晶屏的驱动,用于后边测试的状态张氏。</span></p>
<p><strong><span style="font-size:16px;">目标</span></strong></p>
<p><span style="font-size:16px;"> 软硬件驱动TFT液晶屏,实现页面展示。</span></p>
<p><strong><span style="font-size:16px;">实现</span></strong></p>
<p><span style="font-size:16px;"> 本次使用的液晶屏是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> </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, &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, &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, &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 < 8;i++)
{
if ((Data << i) & 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, &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, &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, &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, &gpio_initstructure);
crm_periph_clock_enable(CRM_SPI2_PERIPH_CLOCK, TRUE);
spi_default_para_init(&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, &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> 在软件模拟驱动成功后切换到硬件SPI时出现了一个小插曲,居然驱动失败了,通过不断的修改测试发现出现在了CS_OUT1;这个操作,可能上升太快导致异常,在之前加了一个delay_us(1);后驱动正常。 </p>
<p> 直接使用#if + #elif + #endif进行选择性代码编写,方便切换。</p>
<p> 具体的tft的驱动代码可以结合实际使用的屏进行设计,这块一般都是使用的厂家提供的驱动代码。</p>
<p> 驱动成功:</p>
<p></p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </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> <p>只看到背光亮了,没见有显示,是不是上传图片有误?</p>
lugl4313820 发表于 2022-8-11 21:38
只看到背光亮了,没见有显示,是不是上传图片有误?
<p>只是点亮了,验证SPI功能正常</p>
页:
[1]