找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2113|回复: 0
收起左侧

STM32超声波测距-printf重定向 源程序

[复制链接]
ID:313060 发表于 2019-3-5 16:16 | 显示全部楼层 |阅读模式
通过超声波模块测距,然后把结果打印到串口助手上。
dbf7712737f9419dce583eee6cfa6db.jpg c87f1bf97a7b8b92ad3fa1aff146ac2.png

单片机源程序如下:
  1. #include "system.h"
  2. #include "SysTick.h"
  3. #include "led.h"
  4. #include "usart.h"
  5. //位带操作,实现51类似的GPIO控制功能
  6. //具体实现思想,参考<<CM3权威指南>>第五章(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. /*通用延时函数*/
  45. #define TIME_MS 12000                        //@72M
  46. #define TIME_US 10                                //@72M
  47. /********声明*********/
  48. void StartModule(void);//启动模块       
  49. void Timer_Count(void);//开关定时器
  50. void Conut(void);//计算距离       
  51. void dispaly(void);//打印函数
  52. void clear(void);//清零函数
  53. /*长延时函数*/
  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. /*短延时函数*/
  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        预分频器
  85.         TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;                                //采样分割(滤波,外部才要,因为有很多毛刺)
  86.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;        //计数模式:向上计数
  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.         /* 中断优先级分组配置 */
  94.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
  95.        
  96.         /* 设置中断嵌套控制器 */
  97.           NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;                                //设置TIM2中断
  98.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//主优先级
  99.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;                //从优先级
  100.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                //中断通道使能
  101.           NVIC_Init(&NVIC_InitStructure);
  102.                
  103.                 TIM_Cmd(TIM2, DISABLE);
  104. }

  105. /*GPIO初始化函数*/
  106. void GPIOF_Init(void)
  107. {
  108.         GPIO_InitTypeDef        GPIO_InitStructure;//定义结构体变量
  109.         
  110.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);//使能GPIOF时钟
  111.        
  112.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;//选择你要设置的IO口
  113.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;        //设置
  114.        
  115.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;//选择你要设置的IO口
  116.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;        //设置推挽输出模式
  117.         GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//设置传输速率               
  118.         
  119.         GPIO_Init(GPIOF,&GPIO_InitStructure);        //初始化GPIO
  120.                
  121. }
  122. /*******************************************************************************
  123. * 函 数 名         : main
  124. * 函数功能                   : 主函数
  125. * 输    入         : 无
  126. * 输    出         : 无
  127. *******************************************************************************/
  128. int main()
  129. {
  130.         SysTick_Init(72);
  131.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组 分2组
  132.         USART1_Init(9600);
  133.         GPIOF_Init();
  134.         TIM2_Init();

  135.         while(1)
  136.         {       
  137.                 while(num<5)        //每五次算平均数
  138.                 {
  139.                 RX = 1;
  140.                 StartModule();                 //启动模块       
  141.                 Timer_Count();        //开关定时器
  142.                 Conut();                                //计算距离       
  143.                 num++;
  144.                 sum+=S;                        //总数
  145.                 }
  146.                 average=sum/num;        //平均数
  147.                 dispaly();                //打印函数
  148.                 clear();                        //清零函数
  149.         }

  150. }
  151. void StartModule(void)                //启动模块
  152. {
  153.         TX=1;
  154.         Delay_us(20);
  155.         TX=0;
  156. }
  157. void Timer_Count(void)        //开启关闭定时器模块
  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)                        //超声波距离计算函数
  166.         {
  167.                 time = TIM2->CNT;                                                                  //读计数器值
  168.                 TIM2->CNT = 0;                                                                          //清除计数器
  169.                 S=(time*1.7)/10;     //算出来是MM
  170.                 if(S>=10)                                                        //校准
  171.                         S=S-10;
  172.         }
  173.         /*******************************************************************************
  174. * 函 数 名         : TIM2_IRQHandler
  175. * 函数功能                   : TIM2中断函数
  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. /********打印函数*******/
  189. void dispaly(void)
  190. {
  191.         if(average>=4000||flag==1)
  192.                 printf("超出量程\n");
  193.         else
  194.                 printf("测距:%dMM\r\n",average);       
  195. }
  196. /********清零函数*******/
  197. void clear(void)
  198. {
  199.                 flag=0;       
  200.                 num=0;
  201.                 sum=0;
  202.                 average=0;       
  203. }
复制代码

所有资料51hei提供下载:
超声波测距-printf重定向.7z (182.84 KB, 下载次数: 47)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表