arduino nano 的引脚输出脉冲,到底有多快?蚂蚁指挥大象,脉冲控制伺服电机走位的测试。

arduino nano 的引脚输出脉冲,到底有多快?

在loop里只写
digitalWrite(LED_BUILTIN, HIGH);  
digitalWrite(LED_BUILTIN, LOW);
试试效果


测试结果出乎意料16M的晶振啊,什么都不干,
只有145.7kHz?


看来digitalWrite不单纯啊,耗能忒大!

查到有玩家用端口控制的方式比较快。
PORTB = B100000;  
PORTB = B000000;

一下上到2.672MHz

看图说明 loop本身也有一定的内耗

写个goto 死循环
_s: PORTB = B100000;  PORTB = B000000;
goto _s;


4.009MHz效率提升近一倍
while死循环跟这个是一样的
循环本身也有耗能

如果不用循环,直接代码控制会怎么样呢
  PORTB = B100000;  
  PORTB = B000000;
  PORTB = B100000;  
  PORTB = B000000;
  PORTB = B100000;  
  PORTB = B000000;
  PORTB = B100000;  
  PORTB = B000000;
  PORTB = B100000;  
  PORTB = B000000;
...

运行直接上8M

到达1/2晶振频率,这应该是极限了

蚂蚁指挥大象arduino控制伺服电机

测试一下脉冲控制伺服电机
发送脉冲需要
控制延时

//参考 https://www.arduino.cn/thread-12468-1-5.html

//關於delay(), millis(), micros(),delayMicroseconds與定时器(教程)計時  

硬件上单片机接伺服要隔离

手工做了个隔离板,没有高速光耦器件,pc817一堆,频率不能太高,做个测试也足够了,下面效果图示波器上部一个通道是单片机的输出信号,下面是隔离输出给伺服驱动的信号

先上效果,这里有视频

图片

上代码
虽然没有细致打磨误差,基本做到辞能达意了


//参考 https://www.arduino.cn/thread-12468-1-5.html
#define ddtick  __asm__("nop\n\t"); 
#define dd2tick  __asm__("nop\n\t""nop\n\t");
#define dd4tick  __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t"); 
// the Macro dd4tick will delay 0.25us exactly on 16MHz Arduino
#define delayOneUs()  { dd4tick; dd4tick; dd4tick; dd4tick; }

//16M 
//ddtick 执行一个nop 是一个周期0.0625us (62.5ns)
//dd4tick 执行4个nop 是0.25us (250ns)
//delayOneUs 4个dd4tick 0.25*4=1us

void setup() {
  // initialize digital pin LED_BUILTIN as an output.13号针
  pinMode(LED_BUILTIN, OUTPUT);  
  digitalWrite(LED_BUILTIN,LOW);
  //初始化串口连接波特率
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB, on LEONARDO, MICRO, YUN, and other 32u4 based boards.
    //等待串口连接。需要LEONARDO, MICRO, YUN, 或其他 32u4板子上的usb接口
  }

  Serial.println("pwm ok");
}
unsigned int i=1;
void maichong500ns(){
  PORTB = B100000; 
  dd4tick; 
  dd2tick;
  ddtick;
  PORTB = B000000;//2tick
  //约500ns高电平9tick=562.5ns
}
void maichong1000ns(){
  PORTB = B100000; 
  dd4tick; 
  dd4tick;
  dd4tick;  
  dd2tick;
  ddtick;
  PORTB = B000000;//2tick
  //约1000ns高电平17tick=1062.5
}
void maichong2000ns(){
  PORTB = B100000; 
  delayOneUs();//16ticks
  dd4tick; 
  dd4tick;
  dd4tick;  
  dd2tick;
  //ddtick;
  PORTB = B000000;//2tick
  //约2000ns高电平33tick=2062.5
}
// 
void F250kHz(unsigned long  i){
  while(i>0){    
      maichong2000ns();
      i--;
      delayOneUs();
      dd4tick; 
      //dd4tick;
      dd2tick;  
      ddtick;
      
  }
      
}
void F200kHz(unsigned long  i){
  while(i>0){       
      i--;
      PORTB = B100000; 
      
      delayOneUs();
      delayOneUs();
      
      dd2tick;
      dd2tick;
      ddtick;

      PORTB = B000000;//2tick
        
      delayOneUs();
      delayOneUs();
      dd2tick; 
      
  }
      
}
//误差
void F100kHz(unsigned long  i){
  while(i>0){       
      i--;
      PORTB = B100000; 
      delayOneUs();
      delayOneUs(); 
      delayOneUs();
      delayOneUs();
      delayOneUs(); 
      ddtick;
      //delayOneUs();

      PORTB = B000000;//2tick
      delayOneUs();
      delayOneUs(); 
      delayOneUs();
      delayOneUs();
      dd2tick; 
      dd2tick;
      dd2tick; 
      ddtick;
      //delayOneUs();
      
  }
      
}
//精度不高10.21
void F10kHz(unsigned long  i){
  while(i>0){    
      
      i--;
      PORTB = B100000; 
      delayMicroseconds(50); 
      PORTB = B000000;//2tick
      delayMicroseconds(50);  
  }
      
}
void F5kHz(unsigned long  i){
  while(i>0){    
      
      i--;
      PORTB = B100000; 
      delayMicroseconds(100); 
      PORTB = B000000;//2tick
      delayMicroseconds(100);  
  }
      
}
void F1kHz(unsigned long  i){
  while(i>0){    
      
      i--;
      PORTB = B100000; 
      delayMicroseconds(500); 
      PORTB = B000000;//2tick
      delayMicroseconds(500);  
  }
      
}
void F500Hz(unsigned long  i){
  while(i>0){    
      
      i--;
      PORTB = B100000; 
      delay(1); 
      PORTB = B000000;//2tick
      delay(2);  
  }
      
}
void loop() {
  //unsigned  long i=4294967295;
  //F250kHz(1000000);
  //F200kHz(100000);
  //F100kHz(10000);
  //F10kHz(10000);
  F500Hz(2000);
  Serial.println("F500Hz over");
  F1kHz(5000);
  Serial.println("F1kHz over");
  F5kHz(50000);
  Serial.println("F5kHz over");
  F10kHz(50000);
  Serial.println("F10kHz over");
  /*while(i>0){
    if(1){
      maichong2000ns();
      i--;
      dd4tick; 
      dd4tick;
      dd4tick;  
      ddtick;
      //delayOneUs();
    }else{
      //delay(10);
      //i=1024;
    }
    
  }*/
  //i=1024;
  //145.7kHz
  //digitalWrite(LED_BUILTIN, HIGH);  
  //digitalWrite(LED_BUILTIN, LOW);
  //看来执行digitalWrite本身就浪费很多时间
  
  //2.672MHz
  //PORTB = B100000;  
  //PORTB = B000000;
  //用这种方式要快近十几倍,loop循环是瓶颈

  
  //4.009MHz
  //_s: PORTB = B100000;  PORTB = B000000;
  //goto _s;
  //跳转死循比上面再快一倍
  
  //4.009MHz
  //while(true){
  //PORTB = B100000;  
  //PORTB = B000000;
  //}
  //循环与跳转测量结果一样

  
  //8.009MHz
  /*while(true){  
  PORTB = B100000;  
  PORTB = B000000;
  PORTB = B100000;  
  PORTB = B000000;
  PORTB = B100000;  
  PORTB = B000000;
  PORTB = B100000;  
  PORTB = B000000;
  PORTB = B100000;  
  PORTB = B000000;
  
  PORTB = B100000;  
  PORTB = B000000;
  PORTB = B100000;  
  PORTB = B000000;
  PORTB = B100000;  
  PORTB = B000000;
  PORTB = B100000;  
  PORTB = B000000;
  PORTB = B100000;  
  PORTB = B000000;

  }*/
  //直接操作端口高达8M,16M的晶振的一半?


}
发布了78 篇原创文章 · 获赞 76 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/qq_38288618/article/details/90116254