@21小跑堂
今天在调试spi驱动TFT屏,发现spi的硬件spi时钟时序与软件的时序的波形是有大的差别。
【测试环境】
IDE:MDK5.38
spi的驱动,使用摸拟与硬件通过条件编译来选择切换,代码如下:
// 作 者 : 刘建华
// 生成日期 : 2023-11-7
// 最近修改 :
// 功能描述 :AT32F435 GC9306
// 说明:
// ----------------------------------------------------------------
// GND 电源地
// VCC 3.3v电源
// SCL PA13(SCLK)
// SDA PA14(MOSI)
// RES PA0
// DC PA1
// CS PA12
// BLK PA3
// ----------------------------------------------------------------
// 修改历史 :
// 日 期 :
//All rights reserved
//******************************************************************************/
#define SOFTWARE_SPI_ENABLE 0
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
/* configure the led gpio */
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_4|GPIO_PINS_5|GPIO_PINS_7;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOA, &gpio_init_struct);
gpio_bits_set(GPIOA,GPIO_PINS_4|GPIO_PINS_5|GPIO_PINS_7);
#else
/*SPI1 :
PA4/CS
PA5/SCK
PA6/MISO
PA7/MOSI
*/
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_5);
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE6, GPIO_MUX_5);
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE7, GPIO_MUX_5);
gpio_default_para_init(&gpio_init_struct);
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
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_6;
// gpio_init(GPIOA, &gpio_init_struct);
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
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);
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_2;
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_CLOCK_POLARITY_HIGH
spi_init_struct.clock_phase = SPI_CLOCK_PHASE_2EDGE; //SPI_CLOCK_PHASE_2EDGE
spi_init_struct.cs_mode_selection = SPI_CS_SOFTWARE_MODE;
spi_init(SPI1, &spi_init_struct);
spi_enable(SPI1, TRUE);
#endif
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);
}
/******************************************************************************
函数说明:LCD串行数据写入函数
入口数据:dat 要写入的串行数据
返回值: 无
******************************************************************************/
void LCD_Writ_Bus(uint8_t dat)
{
LCD_CS_Clr;
//gpio_bits_reset( GPIOA, GPIO_PINS_4 );
#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_i2s_data_transmit(SPI1, dat );
while(spi_i2s_flag_get(SPI1, SPI_I2S_TDBE_FLAG) == RESET) {};
#endif
}
测试结果:
使用软件摸的SPI,时钟可以达到5MHz显示图像正常,用逻辑分仪器捕获时序如下:
使用硬件spi配置 分频配置为时时钟正常,也可以正常驱动屏幕,捕获时序如下:
配置为spi_init_struct.mclk_freq_division = SPI_MCLK_DIV_4;时,SCK的时钟信号就不是很规律了,但是可以驱动屏,时序如下:
配置为spi_init_struct.mclk_freq_division = SPI_MCLK_DIV_8;时序乱了,cs信号也跟着乱了,屏点不亮,捕获的时序如下:
如果我们使用图形配置工具,它是不能配置低于8倍分频的:
【讨论】
在使用spi中,图形化配置好的代码,不能用于spi屏的驱动,时序会乱。而如果配置为2倍频,spi只能跑到2MHz,而摸拟的却可以跑到5MHz。我看数据手册spi是可以跑到120MHz的。如果大佬们能给我指点一下,不胜感谢!
|