STM32 GPIO输出高低电平转换速率测试

时间:2023-02-20 11:00:31
最近对STM32 GPIO的输出端高低电平变化速率产生兴趣,于是用我所知道的控制GPIO的不同方法做了测试。

单片机CPU:STM32F103ZET6
软件平台:kEIL MDK
逻辑分析仪:金沙滩 LA2016

源程序

#include "stm32f10x.h"

#define PA0  GPIOA ->ODR

//位绑定操作开始
#define GPIOA_ODR_ADDR (GPIOA_BASE + 0x0C)  //0x0C是ODR的地址偏移,见数据手册
#define GPIOA_IDR_ADDR (GPIOA_BASE + 0x08)    //0x08是IDR的地址偏移

#define BitBand(Addr,BitNum)  *(volatile unsigned long *)((Addr&0xF0000000)+0x02000000 + ((Addr&0xFFFFF)<<5) + (BitNum<<2) )

#define PAout(n)   BitBand(GPIOA_ODR_ADDR,n)
#define PAin(n)    BitBand(GPIOA_IDR_ADDR,n)
//位绑定结束,如要绑定其他IO口,只需把GPIOA换成GPIOB  GPIOC.....GPIOF即可,n(0~31)表示第几个IO

u32 *PAO0 = (u32 *)(0x42000000+(0x40000000 + 0x10000      + 0x0800  +  0x0C -0x40000000 )*32+4*0);
u32 *PAI0 = (u32 *)(0x42000000+(0x40000000 + 0x10000      + 0x0800  +  0x08 -0x40000000 )*32+4*1);

int main(void)
{
    GPIOA ->CRL = 0xC3;    //因为要把PA.1作为输入,所以有C,如果不用可设置为 0x03

    while(1)
    {
        //*PAO0 = !*PAO0 ;

        //*PAO0=1;
        //*PAO0=0;

        GPIOA ->ODR = 0x1;
        GPIOA ->ODR = 0x0;

        //GPIO_SetBits (GPIOA,GPIO_Pin_0 );
        //GPIO_ResetBits (GPIOA,GPIO_Pin_0 );        

        //PA0 = 0x01;
        //PA0 = 0x00;

        //PA0 =!PA0;

        //GPIOA ->BSRR = 0x01;
        //GPIOA ->BRR = 0x01; 

        //PAout(0)=1;
        //PAout(0)=0; 
        
    }

        return(1);
}





测试结果截图
STM32 GPIO输出高低电平转换速率测试STM32 GPIO输出高低电平转换速率测试STM32 GPIO输出高低电平转换速率测试
STM32 GPIO输出高低电平转换速率测试
STM32 GPIO输出高低电平转换速率测试
STM32 GPIO输出高低电平转换速率测试
STM32 GPIO输出高低电平转换速率测试
STM32 GPIO输出高低电平转换速率测试

从图中看出,最快的是
       GPIOA ->ODR = 0x1;  GPIOA ->ODR = 0x0;
和   PA0 = 0x01;PA0 = 0x00;   
和   GPIOA ->BSRR = 0x01;         GPIOA ->BRR = 0x01; 
转换周期是220ns,4.55Mhz


最慢的是  *PAO0 = !*PAO0 ;  和  PA0 =!PA0;  取反操作浪费不少时间
转换周期是900ns  1.11Mhz


用位绑定函数操作最方便,速度稍微慢一点,是320ns,见最后一张图

如果有更快的操作方法请指教。

4 个解决方案

#1


本帖最后由 woshi_ziyu 于 2014-09-28 10:41:40 编辑
这个对比汇编指令就可以了 查看运行了多少个时钟周期

#2


好好研读下,一定的

#3


从汇编就知道哪些周期长了。

 *PAO0 = !*PAO0 
1 读PAO0 
2 取反
3 写PAO0 

GPIOA ->ODR = 0x1
1 写PAO0
注意 每个过程有1个或者多个机器周期 

#4


本帖最后由 wangfan027 于 2014-10-14 01:03:21 编辑
我还以为楼主想测波形的突变时间,这个响应时间可以看会变代码估算,就和楼上几位说的一样,倒是那个电平转换时下降沿或者上升沿的时间,那个测起来麻烦点,需要高速示波器

#1


本帖最后由 woshi_ziyu 于 2014-09-28 10:41:40 编辑
这个对比汇编指令就可以了 查看运行了多少个时钟周期

#2


好好研读下,一定的

#3


从汇编就知道哪些周期长了。

 *PAO0 = !*PAO0 
1 读PAO0 
2 取反
3 写PAO0 

GPIOA ->ODR = 0x1
1 写PAO0
注意 每个过程有1个或者多个机器周期 

#4


本帖最后由 wangfan027 于 2014-10-14 01:03:21 编辑
我还以为楼主想测波形的突变时间,这个响应时间可以看会变代码估算,就和楼上几位说的一样,倒是那个电平转换时下降沿或者上升沿的时间,那个测起来麻烦点,需要高速示波器