2149|2

9

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

合:进阶操作IO之软件SPI性能 [复制链接]

0x00 前言

本文对于芯片的裸片进行SPI的测试,使用硬件的定时器进行测试时钟的稳定,因为考虑到实际使用单独使用一个硬件定时器作为时钟太过奢侈,这里使用了简单的软件模拟定时器的实现。这里因为软件定时器的实现并不重要,只要满足当前的一定测试时钟的稳定性和精度满足测试要求即可。

0x10 测试环境

  • demo单板
  • 电脑一台不必多讲
  • IAR 9+,主要是编译器支持会好些
  • 某个不愿意透露具体型号的逻辑分析仪(没打广告)

其中,SPI模拟引脚的选择标准如下:

  1. 为标准的IO接口

  2. 可以用来直接测试,没有外部接入

0x20 测试代码与测试步骤

笔者尝试实现一个简单的Master模式下的简单收发SPI,发送一些指定字符实现当前的SPI模拟。

下为代码

void spi_soft_init()
    {
    
        //TIM -- 模拟当前的频率
        user_timer_init();

    
        spi_soft_obj.config.b.ENABLE = 1;
    
        

    timer_id = timer_add(
                        0,
                        0,
                        0,
                        0,
                        0,
                        1,
                        0,
                        1,
                        0,
                        TIM_IRQHandler
                        );
        
    }

#define CS_HIGH do{gpio_bit_set(GPIOA, GPIO_PIN_1) }while(0)
#define CS_LOW do{gpio_bit_reset(GPIOA, GPIO_PIN_1);}while(0)

#define CLK_SET(state) do{gpio_bit_write(GPIOA, GPIO_PIN_2, state);}while(0)


#define MOSI_SET(state) do{gpio_bit_write(GPIOA, GPIO_PIN_3, state);}while(0)
#define MISO_GET() (gpio_input_bit_get(GPIOA,GPIO_PIN_9))

#define spi_soft_close() timer_stop(timer_id)
#define spi_soft_open() timer_reset(timer_id)

enum
{
	SOFT_SPI_DATA_IN = 0,
	SOFT_SPI_DATA_OUT,
	SOFT_SPI_DATA_MAX
};

typedef union 
{
	unsigned char d8;
	struct
	{
	unsigned CPHA:1;		//0-even-catch|1-odd-catch
	unsigned CPOL:1;		//0-low|1-high
	unsigned DATASIZE:1;	//0-8bit|1-16bit
	unsigned FLASH_BIT:1;	//0-MSB|1-LSB
	unsigned MODE:1;		//0-master|1-slave
	unsigned DIR:2;		//0-Full duplex|1-onlyRX|2-onlyTX|3-Only_listen
	unsigned ENABLE :1; //0-off|1-on
	}b;
	
}S_SPI_CONFIG;
typedef struct
{
	unsigned CLK:1;
	unsigned CS:1;		
	unsigned MOSI:1;	
	unsigned MISO:1;	
	unsigned NU :28; 
}S_SPI_SOFT_PIN;


typedef struct
{
    unsigned short data[SOFT_SPI_DATA_MAX];
    S_SPI_CONFIG config;
    unsigned char line_state;//0-pending|1-sending
    
    unsigned char send_point;
}S_SPI_SOFT_OBJ;

static S_SPI_SOFT_OBJ spi_soft_obj = {0};
S_SPI_SOFT_PIN spi_pin = {0};



    void TIM_IRQHandler()
    {
        {
            if(spi_soft_obj.config.b.ENABLE == 1)
            {
                //normal-no send
                if(spi_soft_obj.line_state == 0)
                {
                    if(spi_soft_obj.config.b.CPOL)
                    {
                        spi_pin.CLK = 1;
                    }
                    else
                    {
                        spi_pin.CLK = 0;
                    }
                    //spi_pin.MOSI = 0;
                    if(spi_pin.CS == 1)
                    {
                        //MSB
                        if(spi_soft_obj.config.b.FLASH_BIT == 0)
                        {
                            spi_soft_obj.data[SOFT_SPI_DATA_IN] |= MISO_GET();
                        }
                        //LSB
                        else
                        {   //no debug
                            spi_soft_obj.data[SOFT_SPI_DATA_IN] |= MISO_GET()<<((8*(spi_soft_obj.config.b.DATASIZE+1)));
                        }
                    }
                    spi_pin.CS = 0;
                    update_bit =0;
                    clock_count = 0;
                    spi_bit_count = 0;
                }
                //send-once byte
                else
                {
                        if((clock_count == 0))
                        {
                            spi_soft_obj.data[SOFT_SPI_DATA_IN] = 0;
                        }
                    //0-CPHA=0 
                    if((!spi_soft_obj.config.b.CPHA) && (clock_count == 0))
                    {
                        update_bit = 1;
                        spi_pin.CLK = 0;
                    }
                    else
                    {
                        spi_pin.CLK = !spi_pin.CLK;
                        if((clock_count % 2) == (spi_soft_obj.config.b.CPHA))
                        {
                            update_bit = 1;
                        }
                        else
                            update_bit = 0;
                    }
                    clock_count++;
                    //send_finish
                    if((8*(spi_soft_obj.config.b.DATASIZE+1)) <= spi_bit_count)
                    {
    
                        spi_soft_obj.line_state = 0;
                        //spi_pin.MOSI = 0;
                        spi_pin.CS = 1;
                        update_bit =0;
                        clock_count = 0;
                        spi_bit_count = 0;
                    }
                    if(update_bit)
                    {
                        spi_pin.MISO = MISO_GET();
                        //MSB
                        if(spi_soft_obj.config.b.FLASH_BIT == 0)
                        {
                            spi_pin.MOSI = spi_soft_obj.data[SOFT_SPI_DATA_OUT] >> ((8*(spi_soft_obj.config.b.DATASIZE+1)) - spi_bit_count - 1 ) & 0x01;
                            spi_soft_obj.data[SOFT_SPI_DATA_IN] |= MISO_GET()<<((8*(spi_soft_obj.config.b.DATASIZE+1))- spi_bit_count );
                        }
                        //LSB
                        else
                        {   //no debug
                            spi_pin.MOSI = spi_soft_obj.data[SOFT_SPI_DATA_OUT] >> (spi_bit_count) & 0x01;
                            spi_soft_obj.data[SOFT_SPI_DATA_IN] |= MISO_GET()<<(spi_bit_count);
                        }
                        spi_bit_count++;
                    }
                    
                    
                }
                CLK_SET(spi_pin.CLK);
                MOSI_SET(spi_pin.MOSI);
                
            }
            else
            {
                CLK_SET(0);
                MOSI_SET(0);
            }
        }
    }

 

需要提出的一点,这里的代码某些引脚与笔者现在的实际引脚相对不同,主要是官方的单板与这边测试的一些原因影响。不影响代码的实现

直接使用逻辑分析仪进行测试当前的协议是否正常发送数据。

这里笔者选反了数据输出,但是因为也是随手写的,也就不怎么重要的一个事情了。

0x30 测试结果与总结

可以看到,在稳定发送数据的情况下,芯片可以实现12.5KHz的时钟,还是可以使用的,虽说肯定不如硬件的SPI速度快或者方便,但是还是很满足兼容性的。而且这个速度还是在比较不影响当前系统的执行效率下的实现。

 

此帖出自GD32 MCU论坛

最新回复

楼主用的什么逻辑分析仪,截的图,感觉比我的漂亮多了!  详情 回复 发表于 2022-2-6 08:46
点赞 关注
 

回复
举报

7048

帖子

11

TA的资源

版主

沙发
 
楼主用的什么逻辑分析仪,截的图,感觉比我的漂亮多了!
此帖出自GD32 MCU论坛

点评

梦源,本身这个逻辑分析仪是开源的,但是实际的上位机似乎是梦源自己的  详情 回复 发表于 2022-2-6 14:37
 
 
 

回复

9

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
lugl4313820 发表于 2022-2-6 08:46 楼主用的什么逻辑分析仪,截的图,感觉比我的漂亮多了!

梦源,本身这个逻辑分析仪是开源的,但是实际的上位机似乎是梦源自己的

此帖出自GD32 MCU论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表