• 硬件SPI与软件模拟SPI速率对比


    1、前言

    本文使用AT32F425驱动RC522来测试SPI1的速率,关于RC522的详细代码操作可查帖子【GD32L233C-START】硬件SPI1驱动RC522。

    2、关于AT32F425的SPI

    在这里插入图片描述
    在这里插入图片描述AT32F425系列最多有3个spi,本文使用SPI1。

    3、SPI1的最大速率

    在这里插入图片描述
    SPI1挂在APB2总线上,APB2总线的最大速率是96MHz;
    在这里插入图片描述SPI的最大速率为fPCLK/2,即48Mhz。

    4、代码实现

    /*SPI1 :  
        PA4/CS  
        PA5/SCK    
        PA6/MISO   
        PA7/MOSI    
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (1)模拟SPI

    #define SET_SPI_CS()  gpio_bits_set(GPIOA, GPIO_PINS_4)
    #define CLR_SPI_CS() gpio_bits_reset(GPIOA, GPIO_PINS_4) 
    
    #define SET_SPI_SCLK() gpio_bits_set(GPIOA,GPIO_PINS_5)
    #define CLR_SPI_SCLK() gpio_bits_reset(GPIOA,GPIO_PINS_5)//SCL=SCLK
    
    #define SET_SPI_MOSI() gpio_bits_set(GPIOA,GPIO_PINS_7)
    #define CLR_SPI_MOSI() gpio_bits_reset(GPIOA,GPIO_PINS_7)//SDO=MOSI
    
    #define READ_SPI_MISO() gpio_input_data_bit_read(GPIOA,GPIO_PINS_6) //SDI=MISO
    
    void SpiIoInit(void)
    {	
    	crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
    
    	gpio_init_type gpio_initstructure;
    	
        /* configure the lcd gpio */
    	gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    	gpio_initstructure.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
    	gpio_initstructure.gpio_mode = GPIO_MODE_OUTPUT;
    	gpio_initstructure.gpio_pins = GPIO_PINS_4|GPIO_PINS_5|GPIO_PINS_7;
    	gpio_initstructure.gpio_pull = GPIO_PULL_NONE;
    	gpio_init(GPIOA, &gpio_initstructure);
    	
    	gpio_bits_set(GPIOA,GPIO_PINS_4|GPIO_PINS_5|GPIO_PINS_7);
    	
    	gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    	gpio_initstructure.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
    	gpio_initstructure.gpio_mode = GPIO_MODE_INPUT;
    	gpio_initstructure.gpio_pins = GPIO_PINS_6;
    	gpio_initstructure.gpio_pull = GPIO_PULL_NONE;
    	gpio_init(GPIOA, &gpio_initstructure);
    	
    	gpio_bits_set(GPIOA,GPIO_PINS_6);
    	
    }
    
    uint8_t  SPIWriteByte(uint8_t dat)
    {
    	uint16_t ret=0;
    
    	u8 i;
    	
    	CLR_SPI_CS();
    	for(i=0;i<8;i++)
    	{			  
    		if(dat&0x80)
    		{
    		   SET_SPI_MOSI();
    		}
    		else
    		{
    		   CLR_SPI_MOSI();
    		}
    		dat<<=1;
    //		delay_us(1);
    	
    		SET_SPI_SCLK();
    		ret<<=1;
    		
    		if(READ_SPI_MISO())
    		{
    			ret+=1;
    		}
    //		delay_us(1);
    		CLR_SPI_SCLK();
    	}
    	SET_SPI_CS();
    
    	return (ret&0x0ff);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    (2)硬件SPI

    void SpiIoInit(void)
    {	
    	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_init(GPIOA, &gpio_initstructure);
      
    	gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE5, GPIO_MUX_0);
    	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_initstructure);
    
    	gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;
    	gpio_initstructure.gpio_pull           = GPIO_PULL_DOWN;
    	gpio_initstructure.gpio_mode           = GPIO_MODE_MUX;
    	gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    	gpio_initstructure.gpio_pins = GPIO_PINS_5;
    	gpio_init(GPIOA, &gpio_initstructure);
    
    	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_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    	gpio_initstructure.gpio_pins = GPIO_PINS_6;
    	gpio_init(GPIOA, &gpio_initstructure);
    
    	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_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    	gpio_initstructure.gpio_pins = GPIO_PINS_7;
    	gpio_init(GPIOA, &gpio_initstructure);
    	
    	spi_init_type spi_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_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_LOW;
    	spi_init_struct.clock_phase = SPI_CLOCK_PHASE_1EDGE;
    	spi_init_struct.cs_mode_selection = SPI_CS_SOFTWARE_MODE;
    	spi_init(SPI1, &spi_init_struct);
    	spi_enable(SPI1, TRUE);
    }
    
    uint8_t  SPIWriteByte(uint8_t dat)
    {
    	uint16_t ret=0;
    
        CLR_SPI_CS();
    	while(spi_i2s_flag_get(SPI1, SPI_I2S_TDBE_FLAG) == RESET) {};
        spi_i2s_data_transmit(SPI1, dat);
    		
        while(spi_i2s_flag_get(SPI1, SPI_I2S_RDBF_FLAG) == RESET) {};
        ret=spi_i2s_data_receive(SPI1);
        SET_SPI_CS();		
    	return (ret&0x0ff);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    使用硬件SPI测试时,RC522的最大速率只能到12MHZ,也就是8分频,速率再大会导致通信不上。

    5、速率测量

    这里直接用示波器抓CLK的波形,用逻辑分析抓整个SPI的波形。

    (1)模拟SPI
    在这里插入图片描述
    在这里插入图片描述
    可以看出,使用模拟SPI的时候是1.8MHz,用逻辑分析仪抓取也是这个结果。

    (2)硬件SPI
    在这里插入图片描述
    在这里插入图片描述
    可以看出,使用硬件SPI的时候是12MHz,与软件设定的一致,用逻辑分析仪抓取也是这个结果。

    综合对比测量,可以发现,硬件SPI速率远大于软件SPI,因此为了提高cpu的利用率,应尽量选择使用硬件SPI。

  • 相关阅读:
    【vue.js】vue中的Ajax——json-server
    天软特色因子看板 (2023.09 第09期)
    【微信小程序】携带参数跳转,参数中 = 部分参数丢失?数据传输过程中丢失/不全,遇 ‘=‘ 和 ‘?‘ 被截取
    MobLink Android端快速集成文档
    YOLOv8 C2f模块融合shuffleAttention注意力机制
    Flutter 上传文件和保存在应用程序存储目录
    【Docker-k8s学习和实战】(七)详解docker容器管理---容器的相关操作
    问题 U: 推箱子游戏-广度优先搜索版本
    Linux CentOS7 添加网卡
    iOS 17 Simulator Failed with HTTP status 400:bad request
  • 原文地址:https://blog.csdn.net/freemote/article/details/124278345