【前言】
LCD屏是单片机常用的外设。GC9306是一款240*320的彩色显示屏,这次是用spi1驱动它,也是我学习AT32F425的spi外设的题目之一。
【步聚】
1、先下载查看了AT32F425数据手册。
了解spi1的驱动IO是哪些。用于LCD屏的CS、DC、RES、BLK的普通IO是如何驱动的。
2、查看了spi1的驱动示例,学习如何配置spi1为主从模式。
3、上网学习其他网友的驱动LCD屏的例子。学习他们配置外设的方法。
4、用我原来在CH582M的驱动拷贝过来用在AT32F425的工程上。
【具体过程】
1、在RT_Thread Studio的工程目录下面新建一个drives的工程目录,把我原来用在CH582上面的5个文件lcd_init.c、lcd_init.h、lcd.c、lcd.h、lcdfont.h拷贝到这个目录下面。其实单片机学习就象堆积木,用的外设多了,哪怕换一款芯片,使用起来也方便,使用起来没有象以前从头开始、查资料、找驱动===。
2、根据上次驱动gc9306的经验,拷贝文件过来,只需要修改几个参数就行了:
- 1、屏的init,这里主要是改写spi发送数据的这个LCD_Init函数。
- 2、修改DC、RES、CS、BLK四个IO的驱动(宏配置)。
1)定义驱动的IO如下:
// 生成日期 : 2022-3-27
// 最近修改 :
// 功能描述 :AT32F425 GC9306
// 说明:
// ----------------------------------------------------------------
// GND 电源地
// VCC 3.3v电源
// SCL PA5(SCLK)
// SDA PA7(MOSI)
// RES PB0 //复位
// DC PB1 //命令、数据选择位
// CS PA4 //spi片选
// BLK PB2 //背光
// ----------------------------------------------------------------
2)配置spi1的时钟、GPIO等详细见代码注释:
void LCD_GPIO_Init(void)
{
gpio_init_type gpio_init_struct;
spi_init_type spi_init_struct;
/* 使能GPIOA GPIOB时钟 */
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
/* set default parameter */
gpio_default_para_init(&gpio_init_struct);
#if SOFTWARE_SPI_ENABLE //为模拟spi
/* configure the led gpio */
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; //加强的输出能力 跟CH582的 输出20mA与5mA的味道差不多,或者是STM32的推挽输出差不多吧。
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_4|GPIO_PINS_5|GPIO_PINS_7; //选择输出的IO 分别为4、5、7脚 是不是由于专利的问题 我看到这个STM32:GPIO_PIN_0,CH582的GPIO_Pin_0
gpio_init_struct.gpio_pull = GPIO_PULL_NONE; //floating for input, no pull for output 也就是stm32的floating的吧
gpio_init(GPIOA, &gpio_init_struct);
gpio_bits_set(GPIOA,GPIO_PINS_4|GPIO_PINS_5|GPIO_PINS_7); //初始为高电平
#else //为硬件spi
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_pull = GPIO_PULL_UP;
gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_pins = GPIO_PINS_4;
gpio_init(GPIOA, &gpio_init_struct);
gpio_bits_set(GPIOA,GPIO_PINS_4);
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE5, GPIO_MUX_0); //这个muxing 百度翻译也整不明白,是不是管角复用的意思?看到数据手册是乎是5的第1功能为SPI1
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE6, GPIO_MUX_0);
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE7, GPIO_MUX_0);
gpio_default_para_init(&gpio_init_struct);
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_pull = GPIO_PULL_DOWN;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_pins = GPIO_PINS_5 ;
gpio_init(GPIOA, &gpio_init_struct);
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_pull = GPIO_PULL_UP;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_pins = GPIO_PINS_7 | GPIO_PINS_6;
gpio_init(GPIOA, &gpio_init_struct);
crm_periph_clock_enable(CRM_SPI1_PERIPH_CLOCK, TRUE); //使能SPI1的时钟
spi_default_para_init(&spi_init_struct); //复位SPI1
spi_init_struct.transmission_mode = SPI_TRANSMIT_HALF_DUPLEX_TX; //单线双向半双工模式传输(slben=1和slbtd=1)
spi_init_struct.master_slave_mode = SPI_MODE_MASTER; //主机模式
spi_init_struct.mclk_freq_division = SPI_MCLK_DIV_2; //2分频,有空测一下频率是多少
spi_init_struct.first_bit_transmission = SPI_FIRST_BIT_MSB; //MSB 高位在前?
spi_init_struct.frame_bit_num = SPI_FRAME_8BIT; //一帧为8位
spi_init_struct.clock_polarity = SPI_CLOCK_POLARITY_HIGH; //sck在空闲状态下保持高
spi_init_struct.clock_phase = SPI_CLOCK_PHASE_2EDGE; //数据捕获从第二个时钟边缘开始
spi_init_struct.cs_mode_selection = SPI_CS_SOFTWARE_MODE; //CS由软件控制
spi_init(SPI1, &spi_init_struct);
spi_enable(SPI1, TRUE);
#endif
//配置DC、RES、BLK
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_0|GPIO_PINS_1|GPIO_PINS_2;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOB, &gpio_init_struct);
gpio_bits_set(GPIOB,GPIO_PINS_0|GPIO_PINS_1|GPIO_PINS_2);
}
3)改发送函数:
/******************************************************************************
函数说明:LCD串行数据写入函数
入口数据:dat 要写入的串行数据
返回值: 无
******************************************************************************/
void LCD_Writ_Bus(uint8_t dat)
{
gpio_bits_reset( GPIOA, GPIO_PINS_4 ); //CS拉低,开始发送数数
#if SOFTWARE_SPI_ENABLE //模拟发送数据
u8 i;
for(i=0;i<8;i++)
{
LCD_SCLK_LOW();
if(dat&0x80)
{
LCD_MOSI_HIGH();
}
else
{
LCD_MOSI_LOW();
}
LCD_SCLK_HIGH();
dat<<=1;
}
#else //使用硬件SPI发送
spi_i2s_data_transmit(SPI1, dat ); //发送数据
while(spi_i2s_flag_get(SPI1, SPI_I2S_TDBE_FLAG) == RESET) {}; //等待发送完成,我感觉以后要加超时判断,要不会出问题会阻塞在这里
gpio_bits_set(GPIOA, GPIO_PINS_4 ); //CS释放
#endif
}
4)修改DC、RES、BLK的宏配置:
#define RES_PIN GPIO_PINS_0
#define DC_PIN GPIO_PINS_1
#define BLK_PIN GPIO_PINS_2
#define CS_PIN GPIO_PINS_4
//-----------------LCD端口定义----------------
#define LCD_CS_Clr gpio_bits_reset(GPIOA, CS_PIN)//CS
#define LCD_CS_Set gpio_bits_set(GPIOA, CS_PIN)
#define LCD_RES_Clr gpio_bits_reset(GPIOB, RES_PIN)//RES
#define LCD_RES_Set gpio_bits_set(GPIOB, RES_PIN)
#define LCD_DC_Clr gpio_bits_reset(GPIOB, DC_PIN)//DC
#define LCD_DC_Set gpio_bits_set(GPIOB,DC_PIN)
#define LCD_BLK_Clr gpio_bits_reset(GPIOB,BLK_PIN)//BLK
#define LCD_BLK_Set gpio_bits_set(GPIOB,BLK_PIN)
#define LCD_SCLK_LOW() gpio_bits_reset(GPIOA, GPIO_PINS_5)
#define LCD_SCLK_HIGH() gpio_bits_set(GPIOA, GPIO_PINS_5)
#define LCD_MOSI_LOW() gpio_bits_reset(GPIOA, GPIO_PINS_7)
#define LCD_MOSI_HIGH() gpio_bits_set(GPIOA, GPIO_PINS_7)
5)修改延时函数为rt_thread的rt_thread_mdelay()函数。
编译通过在main函数中添加头文件与显示函数,编译通过就OK了:
总结
【感受】AT32F425是ARM M4的核心,使用起来跟STM32、N32G45流程是一样的。这次驱动GC9306还是挺轻松的。不过用过沁恒的CH582M后,感觉ARM 配置外设相双RISC-V就复杂很多。AT32F425的在RT_Thread 驱动LCD很流畅。
【建议】AT32F425没有中文固件库文档,建议官方的固件库文档有中英文的。还有就是开发板的针脚排列不是按顺序的,印刷的字体很小、而且的斜的,特别是夹在中间的,看起来很吃力,建议如果有下一板适当的调整,提高一下舒适度。
项目代码
http://bbs.eeworld.com.cn/forum.php?mod=attachment&aid=NTk2Mzc4fGQ0MzZlZGEwfDE2NzU5MjQyNTZ8MTM4MDMzNXwxMTk4MDE0
原文:【新提醒】【AT-START-F425测评】SPI驱动LCD屏 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)