@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的。如果大佬们能给我指点一下,不胜感谢!
|