打印
[AT32F423]

【AT-START-F423测评】 硬件SPI与模拟spi中时钟信号与分频之疑惑

[复制链接]
4750|56
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lulugl|  楼主 | 2023-11-7 12:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
@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的。如果大佬们能给我指点一下,不胜感谢!

使用特权

评论回复
沙发
muyichuan2012| | 2023-11-7 13:05 | 只看该作者
SPI时钟源可以到150M,但SPI最高速度不能超过36M。如下图,423数据手册有SPI的最高速度为36M。你workbench的配置的主频是150M,APB也是150M。所以SPI要8除频才可以。
如果想SPI跑快一点,可以将主频配置为144M,APB为144M,SPI使用4除频,即36M。


使用特权

评论回复
板凳
lulugl|  楼主 | 2023-11-7 14:30 | 只看该作者
muyichuan2012 发表于 2023-11-7 13:05
SPI时钟源可以到150M,但SPI最高速度不能超过36M。如下图,423数据手册有SPI的最高速度为36M。你workbench ...

但是事实上,我配置为8时他时序乱了,需要配置2-4才能正常工作。

使用特权

评论回复
地板
muyichuan2012| | 2023-11-7 14:55 | 只看该作者
可以跑一下BSP里SPI example

使用特权

评论回复
5
lulugl|  楼主 | 2023-11-7 20:18 | 只看该作者
muyichuan2012 发表于 2023-11-7 14:55
可以跑一下BSP里SPI example

我有两块开发板,有空跑一下互相通信,看看情况怎么样。

使用特权

评论回复
6
fxyc87| | 2023-11-8 09:06 | 只看该作者
你的逻辑分析仪采样率调的太低了,20M采样来读取3M时钟有点低,看样子波形不太好,估计上升沿,下降沿有些时间长,用示波器看一下。

使用特权

评论回复
7
lulugl|  楼主 | 2023-11-8 09:39 | 只看该作者
fxyc87 发表于 2023-11-8 09:06
你的逻辑分析仪采样率调的太低了,20M采样来读取3M时钟有点低,看样子波形不太好,估计上升沿,下降沿有些 ...

好的,我回去试试用200M来采一下样看看。模拟的时钟5M的时序是非常好的。

使用特权

评论回复
8
xu@xupt| | 2023-11-8 18:54 | 只看该作者
学习,围观

使用特权

评论回复
9
Jon495323976| | 2023-11-9 17:40 | 只看该作者
那是因为你的逻辑分析仪分辨率不够,抓不到高频的波形,所以出现那种不规律的显示

使用特权

评论回复
10
lulugl|  楼主 | 2023-11-10 08:02 | 只看该作者
Jon495323976 发表于 2023-11-9 17:40
那是因为你的逻辑分析仪分辨率不够,抓不到高频的波形,所以出现那种不规律的显示 ...

有道理,我回去再试试高频抓包,我的逻辑分析好象可以抓400M的,这个我没有注意到,多谢大佬的指点!

使用特权

评论回复
11
abotomson| | 2023-12-7 21:23 | 只看该作者
在硬件SPI中,时钟信号是由SPI控制器产生的。

使用特权

评论回复
12
pixhw| | 2023-12-7 21:59 | 只看该作者
硬件SPI可以实现更高的速度和稳定性,因为它依赖于精确的硬件组件来控制时钟信号 。

使用特权

评论回复
13
uytyu| | 2023-12-8 08:42 | 只看该作者
需要降低时钟信号的频率,以适应软件的处理速度。

使用特权

评论回复
14
adolphcocker| | 2023-12-8 09:10 | 只看该作者
MCU需要将内部系统时钟分频后,再通过外部时钟引脚发送给SPI设备。

使用特权

评论回复
15
timfordlare| | 2023-12-8 09:31 | 只看该作者
模拟SPI是一种通过软件模拟SPI协议的通信方式,通常用于在没有硬件SPI接口的情况下实现SPI通信。

使用特权

评论回复
16
tifmill| | 2023-12-8 10:00 | 只看该作者
硬件SPI通常具有较高的通信速度。

使用特权

评论回复
17
linfelix| | 2023-12-8 10:10 | 只看该作者
时钟信号的产生和传输都是硬件级别的操作,通常由专门的硬件电路来完成。

使用特权

评论回复
18
fengm| | 2023-12-8 15:52 | 只看该作者
不需要极高的传输速率,模拟SPI也可以满足需求。

使用特权

评论回复
19
timfordlare| | 2023-12-8 16:20 | 只看该作者
在SPI 通信中,时钟信号和分频都是非常重要的组成部分

使用特权

评论回复
20
chenjun89| | 2023-12-8 20:47 | 只看该作者
硬件和软件模拟肯定有区别啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

145

主题

715

帖子

9

粉丝