找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STM32单片机超声波测距程序 原理图PCB文件

[复制链接]
ID:396474 发表于 2022-11-18 15:36 | 显示全部楼层 |阅读模式
STM32超声波测距protel99se画的原理图和PCB图如下:(51hei附件中可下载工程文件)
51hei.png 51hei.png

单片机源程序如下:
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "timer.h"
#include "HCSR04.h"
#include "led.h"
#include "beep.h"
#include "key.h"
#include "lcd1602.h"
#include "stmflash.h"  //包含头文件

unsigned long S=0; //定义超声数据
#define FLASH_SAVE_ADDR  0X0800FF00                //设置FLASH 保存地址(必须为偶数,且其值要大于本代码所占用FLASH的大小+0X08000000)
extern unsigned long Clock_time;   
unsigned char Send_flag=0;

extern u8  TIM3CH1_CAPTURE_STA;                //输入捕获状态                                                   
extern u16        TIM3CH1_CAPTURE_VAL;        //输入捕获值        
u16 fls[4];
u8 k=0;
u32 TL=50;
u8 beep1;
u8 t=0;        
void key() //按键函数
{
        k=KEY_Scan(1); //按键扫描的值给K
        if(k == KEY0_PRES) //如果K等于  KEY0_PRES,就说明是按下加按键
        {
                TL++;     //数据加一,如果大于400,则减一,保持最大400
                if(TL>400)
                        TL--;
                fls[0]=TL;
                STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)fls,1); //存储
        }
        
        if(k == KEY1_PRES)//同上,不过是减
        {
                TL--;
                if(TL<5)
                        TL++;
                fls[0]=TL;
                STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)fls,1);
        }
        
}

void ceju()
{

        Trig=1;                  
        delay_us(20);                                    
        Trig=0;              //启动信号

        S=0;                     //清零距离数据
        Clock_time=0;
        TIM_Cmd(TIM3, DISABLE);  //关定时器,清零计时变量        

        while(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)); //等待检测到高电平

        Clock_time=0;
        TIM_Cmd(TIM3, ENABLE);  //开定时器

        while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)==1&&Clock_time<47058);  //只要是高,一直算时间,如果时间计数超过 47058,所说有问题,直接跳过,47058不一定精确,是一个大概值,

        S=((Clock_time*2)*340/10000)/2;   //时间变量是2us加一,乘以速度,因为时间是us,换成秒是除以1000000,保留两位小数,所以除以 10000,然后除以二得到单方面距离
        TIM_Cmd(TIM3, DISABLE);  //关定时器        
        Clock_time=0;            //清零数据
        printf("Distance:%d cm\r\n",S);//打印总的高点平时间

}

void show()
{        
        LCD1602_Show_Str(0,0,"Distance:");    //显示
        if(S>=100&&S<=400) LCD1602_Write_Dat(S/100%10+0x30); //这里是测速数据
        else LCD1602_Show_Str(9,0," ");
        if(S>=10) LCD1602_Write_Dat(S/10%10+0x30);
        else LCD1602_Show_Str(10,0," ");
        LCD1602_Write_Dat(S%10+0x30);
        LCD1602_Show_Str(12,0,"cm      ");
        
        LCD1602_Show_Str(0,1,"alarm  :"); //这里开始显示报警数据,下面这三段,其实就是判断阈值数据是百位数还是十位数还是个位数,如果是个位数,显示个位数据,百位十位显示空
        if(TL>=100&&TL<=400)
        {
                LCD1602_Write_Dat(TL/100%10+0x30);
                LCD1602_Write_Dat(TL/10%10+0x30);
                LCD1602_Write_Dat(TL%10+0x30);
                LCD1602_Show_Str(12,1,"cm      ");
        }
        
   if(TL>=10&&TL<100)                  
        {
                LCD1602_Show_Str(9,1," ");
                LCD1602_Write_Dat(TL/10%10+0x30);
                LCD1602_Write_Dat(TL%10+0x30);
                LCD1602_Show_Str(12,1,"cm      ");
        }
        if(TL>0&&TL<10)
        {
                LCD1602_Show_Str(9,1," ");
                LCD1602_Show_Str(10,1," ");
                LCD1602_Write_Dat(TL%10+0x30);
                LCD1602_Show_Str(12,1,"cm      ");
        }
}
void problem()  //报警函数
{
        if(S<TL)     //小于阈值,蜂鸣器开始响,对应指示灯亮,否则蜂鸣器不响
        {
                beep1=1;
                LED1=1;
        }
        else
        {
                beep1=0;
                LED1=0;
                LED0=1;
        }
}

int main(void)
{               
        u16 datatemp[1];
        BEEP_Init();
        KEY_Init();
        delay_init();                     //延时函数初始化         
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);         //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
        uart_init(115200);         //串口初始化为115200
        LED_Init();                             //LED端口初始化
        UltrasonicWave_Configuration();  //初始化超声IO
        TIM3_Cap_Init(1,72-1);        //以1Mhz的频率计数,第一个选项,最小只能是1
        LCD1602_Init();
        STMFLASH_Read(FLASH_SAVE_ADDR,(u16*)datatemp,1);
        TL=datatemp[0];
        if(TL<5||TL>400)
        TL=50;
        ceju();
        printf("Distance"); //串口打印一下,调试用
  while(1)
        {
                if(beep1==1) //如果蜂鸣器标志等于1,则开始滴滴叫,指示灯也是闪烁
                {
                        BEEP=!BEEP;
                        LED0=!LED0;
                        
                }
                        else
                                BEEP=0;
                show();   //调用显示函数
                key();    //调用按键函数
                problem();//调用报警处理函数
                t++;      //变量自加,加到5的时候,对5取余会等于0,则启动一次测距函数
                if(t%5==0)
                {
                        t=0;
                        ceju();
                }
        }
}

下载: STM32 超声波测距程序和protel99格式的PCB原理图.7z (343.72 KB, 下载次数: 38)

评分

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

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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