找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2790|回復: 0
收起左側(cè)

STM32超聲波測距-printf重定向 源程序

[復制鏈接]
ID:313060 發(fā)表于 2019-3-5 16:16 | 顯示全部樓層 |閱讀模式
通過超聲波模塊測距,然后把結(jié)果打印到串口助手上。
dbf7712737f9419dce583eee6cfa6db.jpg c87f1bf97a7b8b92ad3fa1aff146ac2.png

單片機源程序如下:
  1. #include "system.h"
  2. #include "SysTick.h"
  3. #include "led.h"
  4. #include "usart.h"
  5. //位帶操作,實現(xiàn)51類似的GPIO控制功能
  6. //具體實現(xiàn)思想,參考<<CM3權(quán)威指南>>第五章(87頁~92頁).
  7. //IO口操作宏定義
  8. #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
  9. #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
  10. #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))
  11. //IO口地址映射
  12. #define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C
  13. #define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C
  14. #define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C
  15. #define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C
  16. #define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C
  17. #define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C   
  18. #define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C   

  19. #define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808
  20. #define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08
  21. #define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008
  22. #define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408
  23. #define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808
  24. #define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08
  25. #define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08

  26. //IO口操作,只對單一的IO口!
  27. //確保n的值小于16!
  28. #define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //輸出
  29. #define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //輸入

  30. #define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //輸出
  31. #define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //輸入

  32. #define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //輸出
  33. #define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //輸入

  34. #define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //輸出
  35. #define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //輸入

  36. #define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //輸出
  37. #define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //輸入

  38. #define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //輸出
  39. #define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //輸入

  40. #define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //輸出
  41. #define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //輸入


  42. #define RX  PFin(3)
  43. #define TX  PFout(4)

  44. /*通用延時函數(shù)*/
  45. #define TIME_MS 12000                        //@72M
  46. #define TIME_US 10                                //@72M
  47. /********聲明*********/
  48. void StartModule(void);//啟動模塊       
  49. void Timer_Count(void);//開關(guān)定時器
  50. void Conut(void);//計算距離       
  51. void dispaly(void);//打印函數(shù)
  52. void clear(void);//清零函數(shù)
  53. /*長延時函數(shù)*/
  54. void Delay_ms(u16 n)
  55. {
  56.         u16 i,j;
  57.        
  58.         for(i=n;i>0;i--)
  59.                 for(j=TIME_MS;j>0;j--);
  60. }

  61. /*短延時函數(shù)*/
  62. void Delay_us(u16 n)
  63. {
  64.         u16 i,j;
  65.        
  66.         for(i=n;i>0;i--)
  67.                 for(j=TIME_US;j>0;j--);
  68. }

  69. unsigned int  time=0;
  70. unsigned long S=0;
  71. unsigned int  flag =0;
  72. unsigned int num;
  73. unsigned int average;
  74. unsigned int sum;
  75. /* 配置定時器2 */
  76. void TIM2_Init(void)
  77. {
  78.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  79.         NVIC_InitTypeDef   NVIC_InitStructure;
  80.        
  81.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE );
  82.         TIM_DeInit(TIM2);                                                                                        //缺省復位TIM2定時器
  83.         TIM_TimeBaseStructure.TIM_Period = 65535;                                        //周期65536 自動重裝寄存器        65356us
  84.         TIM_TimeBaseStructure.TIM_Prescaler = 71;                                 //分頻值71+1        預(yù)分頻器
  85.         TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;                                //采樣分割(濾波,外部才要,因為有很多毛刺)
  86.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;        //計數(shù)模式:向上計數(shù)
  87.         TIM_TimeBaseInit(TIM2, & TIM_TimeBaseStructure);
  88.        
  89.         TIM_ClearFlag(TIM2, TIM_FLAG_Update);                                                //清除TIM2溢出中斷標志
  90.         TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);                                         //TIM2溢出中斷允許
  91.        
  92. //        TIM_Cmd(TIM2, ENABLE);                                                                                //TIM2使能

  93.         /* 中斷優(yōu)先級分組配置 */
  94.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
  95.        
  96.         /* 設(shè)置中斷嵌套控制器 */
  97.           NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;                                //設(shè)置TIM2中斷
  98.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//主優(yōu)先級
  99.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;                //從優(yōu)先級
  100.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                //中斷通道使能
  101.           NVIC_Init(&NVIC_InitStructure);
  102.                
  103.                 TIM_Cmd(TIM2, DISABLE);
  104. }

  105. /*GPIO初始化函數(shù)*/
  106. void GPIOF_Init(void)
  107. {
  108.         GPIO_InitTypeDef        GPIO_InitStructure;//定義結(jié)構(gòu)體變量
  109.         
  110.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);//使能GPIOF時鐘
  111.        
  112.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;//選擇你要設(shè)置的IO口
  113.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;        //設(shè)置
  114.        
  115.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;//選擇你要設(shè)置的IO口
  116.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;        //設(shè)置推挽輸出模式
  117.         GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//設(shè)置傳輸速率               
  118.         
  119.         GPIO_Init(GPIOF,&GPIO_InitStructure);        //初始化GPIO
  120.                
  121. }
  122. /*******************************************************************************
  123. * 函 數(shù) 名         : main
  124. * 函數(shù)功能                   : 主函數(shù)
  125. * 輸    入         : 無
  126. * 輸    出         : 無
  127. *******************************************************************************/
  128. int main()
  129. {
  130.         SysTick_Init(72);
  131.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中斷優(yōu)先級分組 分2組
  132.         USART1_Init(9600);
  133.         GPIOF_Init();
  134.         TIM2_Init();

  135.         while(1)
  136.         {       
  137.                 while(num<5)        //每五次算平均數(shù)
  138.                 {
  139.                 RX = 1;
  140.                 StartModule();                 //啟動模塊       
  141.                 Timer_Count();        //開關(guān)定時器
  142.                 Conut();                                //計算距離       
  143.                 num++;
  144.                 sum+=S;                        //總數(shù)
  145.                 }
  146.                 average=sum/num;        //平均數(shù)
  147.                 dispaly();                //打印函數(shù)
  148.                 clear();                        //清零函數(shù)
  149.         }

  150. }
  151. void StartModule(void)                //啟動模塊
  152. {
  153.         TX=1;
  154.         Delay_us(20);
  155.         TX=0;
  156. }
  157. void Timer_Count(void)        //開啟關(guān)閉定時器模塊
  158. {
  159.                 while(RX==0);       
  160.                 TIM_Cmd(TIM2, ENABLE);                                                                                //TIM2使能
  161.                 while(RX==1);
  162.                 TIM_Cmd(TIM2, DISABLE);                                                                                //TIM2使能       
  163. }
  164. /********************************************************/
  165.   void Conut(void)                        //超聲波距離計算函數(shù)
  166.         {
  167.                 time = TIM2->CNT;                                                                  //讀計數(shù)器值
  168.                 TIM2->CNT = 0;                                                                          //清除計數(shù)器
  169.                 S=(time*1.7)/10;     //算出來是MM
  170.                 if(S>=10)                                                        //校準
  171.                         S=S-10;
  172.         }
  173.         /*******************************************************************************
  174. * 函 數(shù) 名         : TIM2_IRQHandler
  175. * 函數(shù)功能                   : TIM2中斷函數(shù)
  176. * 輸    入         : 無
  177. * 輸    出         : 無
  178. *******************************************************************************/
  179. void TIM2_IRQHandler(void)
  180. {
  181.         if(TIM_GetITStatus(TIM2,TIM_IT_Update))
  182.         {
  183.                 RX=0;
  184.                 flag=1;//超出量程標志
  185.         }
  186.         TIM_ClearITPendingBit(TIM2,TIM_IT_Update);       
  187. }
  188. /********打印函數(shù)*******/
  189. void dispaly(void)
  190. {
  191.         if(average>=4000||flag==1)
  192.                 printf("超出量程\n");
  193.         else
  194.                 printf("測距:%dMM\r\n",average);       
  195. }
  196. /********清零函數(shù)*******/
  197. void clear(void)
  198. {
  199.                 flag=0;       
  200.                 num=0;
  201.                 sum=0;
  202.                 average=0;       
  203. }
復制代碼

所有資料51hei提供下載:
超聲波測距-printf重定向.7z (182.84 KB, 下載次數(shù): 47)


評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表