官术网_书友最值得收藏!

3.2 STM32單片機程序模塊化設計

圖3.13定義了機器人的前后左右四個方向。在第2章實際上你應該已經發現,如果按照圖3.13前進方向的定義,機器人向前走時,從機器人的左邊看,它向前走時輪子是逆時針旋轉的;從右邊看另一個輪子則是順時針旋轉的。

圖3.13 機器人及其前進方向的定義

任務二 基本巡航動作

發給單片機控制引腳的高電平持續時間決定了伺服舵機旋轉的速度和方向。for循環的參數控制了發送給電機的脈沖數量。由于每個脈沖的時間是相同的,因而for循環的參數也控制了伺服電機運行的時間。下面是使機器人向前走三秒鐘的程序實例。

例程:RobotForwardThreeSeconds.c

● 確??刂破骱退欧姍C都已接通電源;

● 輸入、保存、編譯、下載并運行程序RobotForwardThreeSeconds.c。

      #include "stm32f10x_heads.h"
      #include "HelloRobot.h"
      int main(void)
      {
        int counter;
        BSP_Init();
        USART_Configuration();
        printf("Program Running!\n");
        for(counter=0;counter<130;counter++)//運行3秒
        {
          GPIO_SetBits(GPIOD, GPIO_Pin_10);
          delay_nus(1700);
          GPIO_ResetBits(GPIOD,GPIO_Pin_10);
          GPIO_SetBits(GPIOD, GPIO_Pin_9);
          delay_nus(1300);
          GPIO_ResetBits(GPIOD,GPIO_Pin_9);
          delay_nms(20);
        }
          while(1);
      }

RobotForwardThreeSeconds.c是如何工作的?

理解該例程的運行你應該沒什么問題:for循環體中前三行語句使左側電機逆時針旋轉,接著的三行語句使右側電機順時針旋轉。因此兩個輪子轉向機器人的前端,使機器人向前運動。整個for循環執行130次大約需要3秒鐘,從而機器人也向前運動3秒鐘。

關于例程的一點說明

例程中使用printf函數是為了起提示作用。若你覺得串口線影響了機器人的運動,可以不用此函數;還有一個進行調試的方法:讓機器人的前端懸空,讓伺服電機空轉。這樣調試起來就方便了,機器人不會到處亂跑。后面的例程調試也是這樣。

該你了——調節距離和速度

delay_nus函數的參數n為1700和1300都使電機接近它們的最大速度旋轉。把每個delay_nus函數的參數n設定得更接近讓電機保持停止的值——1500,可以使機器人減速。

向后走,原地轉彎和繞軸旋轉

將delay_nus函數的參數n以不同的值組合就可以使機器人以其他的方式運行,你可以在一個程序中實現機器人向前走、左轉、右轉及向后走。

例程:ForwardLeftRightBackward.c

● 輸入、保存并運行程序ForwardLeftRightBackward.c。

      #include "stm32f10x_heads.h"
      #include "HelloRobot.h"
      int main(void)
      {
        int counter;
        BSP_Init();
        USART_Configuration();
        printf("Program Running!\n");
        for(counter=1;counter<=65;counter++)//向前
        {
          GPIO_SetBits(GPIOD, GPIO_Pin_10);
          delay_nus(1700);
          GPIO_ResetBits(GPIOD,GPIO_Pin_10);
          GPIO_SetBits(GPIOD, GPIO_Pin_9);
          delay_nus(1300);
          GPIO_ResetBits(GPIOD,GPIO_Pin_9);
          delay_nms(20);
        }
        for(counter=1;counter<=26;counter++)//向左轉
        {
          GPIO_SetBits(GPIOD, GPIO_Pin_10);
          delay_nus(1300);
          GPIO_ResetBits(GPIOD,GPIO_Pin_10);
          GPIO_SetBits(GPIOD, GPIO_Pin_9);
          delay_nus(1300);
          GPIO_ResetBits(GPIOD,GPIO_Pin_9);
          delay_nms(20);
        }
        for(counter=1;counter<=26;counter++)//向右轉
        {
          GPIO_SetBits(GPIOD, GPIO_Pin_10);
          delay_nus(1700);
          GPIO_ResetBits(GPIOD,GPIO_Pin_10);
          GPIO_SetBits(GPIOD, GPIO_Pin_9);
          delay_nus(1700);
          GPIO_ResetBits(GPIOD,GPIO_Pin_9);
          delay_nms(20);
        }
        for(counter=1;counter<=65;counter++)//向后
        {
          GPIO_SetBits(GPIOD, GPIO_Pin_10);
          delay_nus(1300);
          GPIO_ResetBits(GPIOD,GPIO_Pin_10);
          GPIO_SetBits(GPIOD, GPIO_Pin_9);
          delay_nus(1700);
          GPIO_ResetBits(GPIOD,GPIO_Pin_9);
          delay_nms(20);
        }
          while(1);
      }

該你了——以一個輪子為支點旋轉

你可以使機器人繞一個輪子旋轉。訣竅是使一個輪子不動而另一個旋轉。例如,保持左輪不動而右輪從前面順時針旋轉,機器人將以左輪為軸旋轉。

      GPIO_SetBits(GPIOD, GPIO_Pin_10);
      delay_nus(1500);
      GPIO_ResetBits(GPIOD,GPIO_Pin_10);
      GPIO_SetBits(GPIOD, GPIO_Pin_9);
      delay_nus(1300);
      GPIO_ResetBits(GPIOD,GPIO_Pin_9);
      delay_nms(20);

如果你想使它從前面向右旋轉,很簡單,停止右輪,左輪從前面逆時針旋轉。

      GPIO_SetBits(GPIOD, GPIO_Pin_10);
      delay_nus(1700);
      GPIO_ResetBits(GPIOD,GPIO_Pin_10);
      GPIO_SetBits(GPIOD, GPIO_Pin_9);
      delay_nus(1500);
      GPIO_ResetBits(GPIOD,GPIO_Pin_9);
      delay_nms(20);

用剛討論過的代碼片段替代前進、左轉、右轉和后退相應的代碼片段,通過更改每個for循環的循環次數來調整每個動作的運行時間,更改注釋來反應每個新的旋轉動作。

運行更改后的程序,驗證上述旋轉運動是否不同。

任務三 勻加速/減速運動

在前面機器人運動過程中,你是否發現機器人在每次啟動和停止的時候,是不是有些太快,從而導致機器人幾乎要傾倒。為什么會這樣呢?回憶一下你學過的物理知識,還記得牛頓第二定律和運動學知識嗎?前面的程序總是直接就給機器人伺服電機輸出最大速度控制命令。根據運動學知識,一個物體要從零加速到最大運動速度時,時間越短,所需加速度就越大。而根據牛頓定律,加速度越大,物體所受的慣性力就越大。因此,前面的程序因為沒有給機器人足夠的加速時間,所以受到的慣性力就比較大,從而導致機器人在啟動和停止有一個較大的前傾力或者后坐力。要消除這種情況,就必須讓機器人速度漸漸增加或漸漸減小。采用均勻加速/減速是一種比較好的速度控制策略,這樣不僅可以讓機器人運動得更加平穩,還可以增加機器人電機的使用壽命。

編寫勻加速運動程序

勻加速運動程序片段示例:

      for(pulseCount=10;pulseCount<=200;pulseCount=pulseCount+10)
      {
        GPIO_SetBits(GPIOD, GPIO_Pin_10);
        delay_nus(1500+pulseCount);
        GPIO_ResetBits(GPIOD,GPIO_Pin_10);
        GPIO_SetBits(GPIOD, GPIO_Pin_9);
        delay_nus(1500-pulseCount);
        GPIO_ResetBits(GPIOD,GPIO_Pin_9);
        delay_nms(20);
      }

上述for循環語句能使機器人的速度由停止到全速。循環每重復執行一次,變量pulseCount就增加10:第一次循環時,變量pulseCount的值是10,此時發給PD10、PD9的脈沖的寬度分別為1.51ms、1.49ms;第二次循環時,變量pulseCount的值是20,此時發給PD10、PD9的脈沖的寬度分別為1.52ms、1.48ms。隨著變量pulseCount值的增加,電機的速度也在逐漸增加。到執行第20次循環時,變量pulseCount的值是200,此時發給PD10、PD9的脈沖的寬度分別為1.7ms、1.3ms,電機全速運轉。

回顧第2章任務三,for循環也可以由高向低計數。你可以通過使用for(pulseCount=200;pulseCount>=0; pulseCount=pulseCount-10)來實現速度的逐漸減小。下面是一個使用for循環來實現電機速度逐漸增加到全速然后逐步減小的例子。

例程:StartAndStopWithRamping.c

      #include "stm32f10x_heads.h"
      #include "HelloRobot.h"
      int main(void)
      {
        int pulseCount;
        BSP_Init();
        USART_Configuration();
        printf("Program Running!\n");
        for(pulseCount=10;pulseCount<=200;pulseCount=pulseCount+10)
        {
          GPIO_SetBits(GPIOD,GPIO_Pin_10);
          delay_nus(1500+pulseCount);
          GPIO_ResetBits(GPIOD,GPIO_Pin_10);
          GPIO_SetBits(GPIOD,GPIO_Pin_9);
          delay_nus(1500-pulseCount);
          GPIO_ResetBits(GPIOD,GPIO_Pin_9);
          delay_nms(20);
        }
        for(pulseCount=1;pulseCount<=75;pulseCount++)
        {
          GPIO_SetBits(GPIOD,GPIO_Pin_10);
          delay_nus(1700);
          GPIO_ResetBits(GPIOD,GPIO_Pin_10);
          GPIO_SetBits(GPIOD,GPIO_Pin_9);
          delay_nus(1300);
          GPIO_ResetBits(GPIOD,GPIO_Pin_9);
          delay_nms(20);
        }
        for(pulseCount=200;pulseCount>=0;pulseCount=pulseCount-10)
        {
          GPIO_SetBits(GPIOD,GPIO_Pin_10);
          delay_nus(1500+pulseCount);
          GPIO_ResetBits(GPIOD,GPIO_Pin_10);
          GPIO_SetBits(GPIOD,GPIO_Pin_9);
          delay_nus(1500-pulseCount);
          GPIO_ResetBits(GPIOD,GPIO_Pin_9);
          delay_nms(20);
        }
      while(1);
      }

● 輸入、保存并運行程序StartAndStopWithRamping.c;

● 驗證機器人是否逐漸加速到全速,保持一段時間,然后逐漸減速到停止。

任務四 用函數調用簡化運動程序

在第4章,你的機器人將需要執行各種運動來避開障礙物和完成其他動作。不過,無論機器人要執行何種動作,都離不開前面討論的各種基本動作。為了各種應用程序方便使用這些基本動作程序,你可以將這些基本動作放在函數中,供其他函數調用來簡化程序。

C語言提供了強大的函數定義功能。一個C程序就是由一個主函數和若干個其他函數構成,由主函數調用其他函數,其他函數也可以相互調用。同一個函數可以被一個或多個函數調用任意多次。實際上,為了實現復雜的程序設計,在所有的計算機高級語言中都有子程序或者子過程的概念。在C語言程序中,子程序的作用就是由函數來完成的。從函數定義的角度來看,函數有兩種:

(1)標準函數,即庫函數。由開發系統提供。用戶不必自己定義而直接使用,只需在程序前包含有該函數原型的頭文件即可在程序中直接調用,如前面已經用到的串口標準輸出函數(printf)。應該說明,不同的語言編譯系統提供的庫函數的數量和功能會有一些不同,但許多基本函數是共同的。

(2)用戶定義函數,以解決你的專門需要。不僅要在程序中定義函數本身,而且在主調函數模塊中還必須對該被調函數進行類型說明,然后才能使用。

main函數的返回值

前面說過,main函數是不能被其他函數調用的,那它的返回值類型int是怎么回事呢?

其實不難理解,main函數執行完之后,它的返回值是給操作系統的。雖然在main函數體內并沒有什么語句來指出返回值的大小,但系統默認的處理方式是:當main函數成功執行,它的返回值為1;否則為0。

現在看看下面的函數定義:

      void Forward(void)
      {
        int i;
        for(i=1;i<=65;i++)
          {
      GPIO_SetBits(GPIOD, GPIO_Pin_10);
      delay_nus(1700);
      GPIO_ResetBits(GPIOD,GPIO_Pin_10);
      GPIO_SetBits(GPIOD, GPIO_Pin_9);
      delay_nus(1300);
      GPIO_ResetBits(GPIOD,GPIO_Pin_9);
      delay_nms(20);
          }
      }

Forward函數可以使機器人向前運動約1.5s,該函數沒有形參,也沒有返回值。在主程序中,你可以調用它來讓你的機器人向前運動約1.5s。但是這個函數并沒有太大的使用價值,如果你想讓你的機器人向前運動2s,該怎么辦呢?是重新寫一個函數來實現這個運動嗎?當然不是!通過修改上面的函數,給它增加兩個形式參數,一個是脈沖數量,另一個是速度參數,這樣主程序調用時就可以按照你的要求靈活設置這些參數,從而使函數真正成為一個有用的模塊。重新定義向前運動函數如下:

      void Forward(int PulseCount,int Velocity)   //Velocity should be between 0 and 200
      {
        int i;
        for(i=1;i<=PulseCount;i++)
          {
          GPIO_SetBits(GPIOD, GPIO_Pin_10);
            delay_nus(1500+Velocity);
        GPIO_ResetBits(GPIOD,GPIO_Pin_10);
      GPIO_SetBits(GPIOD, GPIO_Pin_9);
            delay_nus(1500-Velocity);
          GPIO_ResetBits(GPIOD,GPIO_Pin_9);
            delay_nms(20);
          }
      }

函數定義旁有一行注釋,提醒你在調用該函數時,速度參量的值必須在0~200之間。

注釋符

除“//”外,C語言還提供了另一種語句注釋符——“/*”和“ */”。

“/*”和“*/”必須成對使用,在它們之間的內容將被注釋掉。它的作用范圍比“//”大:“//”僅僅對它所在的一行起注釋作用;但“/*…*/”可以對多行注釋。

注釋是你在學習程序設計時要養成的良好習慣。

下面是一個完整的使用向前、左轉、右轉和向后四個函數的例程。

例程:MovementsWithFunctions.c

● 輸入、保存、編譯、下載并運行程序MovementsWithFunctions.c。

      #include "stm32f10x_heads.h"
      #include "HelloRobot.h"
      void Forward(int PulseCount,int Velocity) // Velocity should be between 0 and 200
      {
          int i;
          for(i=1;i<= PulseCount;i++)
            {
                  GPIO_SetBits(GPIOD, GPIO_Pin_10);
                  delay_nus(1500+ Velocity);
              GPIO_ResetBits(GPIOD,GPIO_Pin_10);
                GPIO_SetBits(GPIOD, GPIO_Pin_9);
                  delay_nus(1500- Velocity);
                  GPIO_ResetBits(GPIOD,GPIO_Pin_9);
                  delay_nms(20);
            }
      }
      void Left(int PulseCount,int Velocity)
      {
          int i;
          for(i=1;i<= PulseCount;i++)
            {
                  GPIO_SetBits(GPIOD, GPIO_Pin_10);
                  delay_nus(1500-Velocity);
                GPIO_ResetBits(GPIOD,GPIO_Pin_10);
                GPIO_SetBits(GPIOD, GPIO_Pin_9);
                  delay_nus(1500-Velocity);
                  GPIO_ResetBits(GPIOD,GPIO_Pin_9);
                  delay_nms(20);
            }
      }
      void Right(int PulseCount,int Velocity)
      {
              int i;
              for(i=1;i<= PulseCount;i++)
              {
                  GPIO_SetBits(GPIOD, GPIO_Pin_10);
                delay_nus(1500+Velocity);
                GPIO_ResetBits(GPIOD,GPIO_Pin_10);
                GPIO_SetBits(GPIOD, GPIO_Pin_9);
                delay_nus(1500+Velocity);
                  GPIO_ResetBits(GPIOD,GPIO_Pin_9);
                delay_nms(20);
              }
      }
      void Backward(int PulseCount,int Velocity)
      {
              int i;
              for(i=1;i<= PulseCount;i++)
              {
                GPIO_SetBits(GPIOD, GPIO_Pin_10);
                delay_nus(1500-Velocity);
                GPIO_ResetBits(GPIOD,GPIO_Pin_10);
                GPIO_SetBits(GPIOD, GPIO_Pin_9);
                delay_nus(1500+ Velocity);
                  GPIO_ResetBits(GPIOD,GPIO_Pin_9);
                delay_nms(20);
              }
      }
      int main(void)
      {
        BSP_Init();
        USART_Configuration();
        printf("Program Running!\n");
        Forward(65,200);      Left(26,200);
        Right(26,200);        Backward(65,200);
        while(1);
      }

這個程序的運行結果與程序ForwardLeftRightBackward.c產生的效果是相同的。你有沒有發現四個函數的具體實現是不是有些啰嗦。四個函數的具體實現部分幾乎完全一樣,有沒有可能將這些函數進一步歸納,用一個函數來實現所有這些功能呢?當然有,前面的四個函數都用了兩個形式參數,一個是控制時間的脈沖個數,另一個是控制運動速度的參數,而四個函數實際上代表了四個不同的運動方向。如果能夠通過參數控制運動方向,顯然這四個函數就完全可以簡化成為一個更為通用的函數,它不僅可以涵蓋以上四個基本運動,同時還可以使機器人朝你希望的方向運動。

由于機器人由兩個輪子驅動,實際上兩個輪子的不同速度組合控制著機器人的運動速度和方向,因此可以直接用兩個車輪的速度作為形式參數,就可以將所有的機器人運動用一個函數來實現。

例程:MovementsWithOneFuntion.c

這個例子使你的機器人做同樣動作,但是它只用了一個子函數來實現。

      #include "stm32f10x_heads.h"
      #include "HelloRobot.h"
      void Move(int counter,int PC1_pulseWide,int PC0_pulseWide)
      {
        int i;
        for(i=1;i<=counter;i++)
          {
            GPIO_SetBits(GPIOD, GPIO_Pin_10);
            delay_nus(PC1_pulseWide);
          GPIO_ResetBits(GPIOD,GPIO_Pin_10);
          GPIO_SetBits(GPIOD, GPIO_Pin_9);
            delay_nus(PC0_pulseWide);
            GPIO_ResetBits(GPIOD,GPIO_Pin_9);
            delay_nms(20);
          }
      }
      int main(void)
      {
        BSP_Init();
        USART_Configuration();
        printf("Program Running!\n");
          Move(65,1700,1300);     Move(26,1300,1300);
          Move(26,1700,1700);     Move(65,1300,1700);
          while(1);
      }

● 輸入、保存并運行程序MovementsWithOneFuntion.c;

● 你的機器人是否執行了你熟悉的前、左、右、后運動呢?

任務五 高級主題——用數組建立復雜運動

到目前為止你已經試過三種不同的編程方法來使機器人向前走,左轉,右轉和向后走。每種方法都有它的優點,但是如果你要讓機器人執行一個更長,更復雜的動作時用這些方法都很麻煩。下面要介紹的兩個例子將用子函數來實現每個簡單的動作,將復雜的運動存儲在數組中,然后在程序執行過程中讀出并解碼。避免了重復調用一長串子函數。這里,你要用到C語言的數據類型——數組。

在程序設計中,為了處理方便,可以把具有相同類型的若干變量按有序的形式組織起來。這些按序排列的同類數據元素的集合稱為數組。一個數組可以分解為多個數組元素,根據數組元素數據類型的不同,數組可以分為多種不同類型。數組又分為一維數組、二維數組甚至三維數組。本節只會用到一維數組。例如,下面的語句定義了一個字符型數組,該數組有10個元素,并對這10個元素進行了初始化。

char Navigation[10]={'F','L','F','F','R','B','L','B','B','Q'};

字符串和字符串結束標志

在C語言中沒有專門的字符串變量,通常用一個字符數組或字符指針來存放一個字符串。字符串常量在存儲時,系統自動在字符串的末尾加一個“串結束標志”,即ASCII碼值為0的字符NULL,常用“\0”表示。因此在程序中,長度為n字符的字符串常量在內存中占有n+1個字節的存儲空間。C語言允許用字符串的方式對數組作初始化賦值,如Navigation[10]的初始化賦值可寫為:

char Navigation[10]={“FLFFRBLBBQ”};

或者去掉“{}”,寫為:char Navigation[10]=“FLFFRBLBBQ”;

要特別注意字符與字符串的區別,除了表示形式不同外,其存儲性質也不相同,字符“A”只占1字節,而字符串“A”占2字節。

下面的例程采用字符數組定義一系列復雜的運動。

例程:NavigationWithSwitch.c

● 輸入、保存、編譯、下載并運行程序NavigationWithSwitch.c。

      #include "stm32f10x_heads.h"
      #include "HelloRobot.h"
      void Forward(void)
      {
        int i;
        for(i=1;i<=65;i++)
          {
          GPIO_SetBits(GPIOD, GPIO_Pin_10);
        delay_nus(1700);
        GPIO_ResetBits(GPIOD,GPIO_Pin_10);
          GPIO_SetBits(GPIOD, GPIO_Pin_9);
          delay_nus(1300);
          GPIO_ResetBits(GPIOD,GPIO_Pin_9);
          delay_nms(20);
          }
      }
      void Left_Turn(void)
      {
        int i;
        for(i=1;i<=26;i++)
          {
          GPIO_SetBits(GPIOD, GPIO_Pin_10);
          delay_nus(1300);
        GPIO_ResetBits(GPIOD,GPIO_Pin_10);
          GPIO_SetBits(GPIOD, GPIO_Pin_9);
          delay_nus(1300);
          GPIO_ResetBits(GPIOD,GPIO_Pin_9);
          delay_nms(20);
          }
      }
      void Right_Turn(void)
      {
        int i;
        for(i=1;i<=26;i++)
          {
          GPIO_SetBits(GPIOD, GPIO_Pin_10);
          delay_nus(1700);
        GPIO_ResetBits(GPIOD,GPIO_Pin_10);
          GPIO_SetBits(GPIOD, GPIO_Pin_9);
          delay_nus(1700);
          GPIO_ResetBits(GPIOD,GPIO_Pin_9);
          delay_nms(20);
          }
      }
      void Backward(void)
      {
        int i;
        for(i=1;i<=65;i++)
          {
          GPIO_SetBits(GPIOD, GPIO_Pin_10);
          delay_nus(1300);
        GPIO_ResetBits(GPIOD,GPIO_Pin_10);
          GPIO_SetBits(GPIOD, GPIO_Pin_9);
          delay_nus(1700);
          GPIO_ResetBits(GPIOD,GPIO_Pin_9);
          delay_nms(20);
          }
      }
      int main(void)
      {
        char Navigation[10]={'F','L','F','F','R','B','L','B','B','Q'};
        int address=0;
        BSP_Init();
        USART_Configuration();
        printf(" Program Running!\n");
        while(Navigation[address]!='Q')
          {
            switch(Navigation[address])
            {
                  case 'F':Forward();break;
                  case 'L':Left_Turn();break;
                  case 'R':Right_Turn();break;
                  case 'B':Backward();break;
            }
            address++;
          }
          while(1);
      }

你的機器人是否走了一個矩形?如果它走得更像一個梯形,你可能需要調節轉動程序中for循環的循環次數,使其旋轉精確的90度。

在程序主函數中定義了一個字符數組,這個數組中存儲的是一些命令:F表示向前運動,L表示向左轉,R表示向右轉,B表示向后退,Q表示程序結束。之后,定義了一個int型變量address,用來作為訪問數組的索引。接著是一個while循環,注意到這個循環的條件表達式與前面的不同:只有當前訪問的數組值不為Q時,才執行循環體內的語句。在循環內,每次執行switch語句后,都要更新address,以使下次循環時執行新的運動。

當Navigation[address]為“F”時,執行向前運動的函數Forward();當Navigation[address]為“L”時,執行向左轉的函數Left_Turn();當Navigation[address]為“R”時,執行向右轉的函數Right_Turn();當Navigation[address]為“B”時,執行向后運動的函數Backward()。你可以增加或刪除數組中的字符來獲取新的運動路線。記?。簲到M中的最后字符應該是“Q”。

例程:NavigationWithValues.c

在本例程中,將不使用子函數,而是使用三個整型數組來存儲控制機器人運動的三個變量,即循環的次數和控制左右電機運動的兩個參數。具體定義如下:

int Pulses_Count[5]={65,26,26,65,0};

int Pulses_Left[4]={1700,1300,1700,1300};

int Pulses_Right[4]={1300,1300,1700,1700};

int型變量address作為訪問數組的索引值,每次用address提取一組數據:Pulses_Count[address],Pulses_Left[address],Pulses_Right[address],這些變量值被放在下面的代碼塊中,作為機器人運動一次的參數。

      for(int counter=1;counter<=Pulses_Count[address];counter++)
      {
      GPIO_SetBits(GPIOD, GPIO_Pin_10);
      delay_nus(Pulses_Left[address]);
      GPIO_ResetBits(GPIOD,GPIO_Pin_10);
      GPIO_SetBits(GPIOD, GPIO_Pin_9);
      delay_nus(Pulses_Right[address]);
      GPIO_ResetBits(GPIOD,GPIO_Pin_9);
      delay_nms(20);
      }

address加1,再提取一組數據,作為機器人下次運動的參數。以此繼續直至Pulses_Count[address]=0時,機器人停止運動。具體程序如下:

      #include "stm32f10x_heads.h"
      #include "HelloRobot.h"
      int main(void)
      {
        int Pulses_Count[5]={65,26,26,65,0};
        int Pulses_Left[4]={1700,1300,1700,1300};
        int Pulses_Right[4]={1300,1300,1700,1700};
        int address=0;
        int counter;
        BSP_Init();
        USART_Configuration();
        printf("Program Running!\n");
        while(Pulses_Count[address]!=0)
        {
        for(counter=1;counter<=Pulses_Count[address];counter++)
        {
        GPIO_SetBits(GPIOD, GPIO_Pin_10);
        delay_nus(Pulses_Left[address]);
        GPIO_ResetBits(GPIOD,GPIO_Pin_10);
      GPIO_SetBits(GPIOD, GPIO_Pin_9);
        delay_nus(Pulses_Right[address]);
        GPIO_ResetBits(GPIOD,GPIO_Pin_9);
        delay_nms(20);
        }
        address++;
      }
      while(1);
      }
主站蜘蛛池模板: 潼南县| 万盛区| 镇雄县| 吐鲁番市| 固镇县| 荣昌县| 永城市| 定安县| 河南省| 博客| 尼玛县| 新蔡县| 江口县| 文昌市| 溧水县| 三门县| 陕西省| 惠来县| 宣化县| 信阳市| 昭通市| 高淳县| 横峰县| 乐陵市| 汕尾市| 泗水县| 金山区| 梅州市| 青海省| 措美县| 霞浦县| 虎林市| 梧州市| 靖西县| 宜都市| 平山县| 五河县| 新龙县| 洛扎县| 沁水县| 邵阳县|