C语言单片机项目实战超声波雷达测距
本实验是基于MSP430利用HC-SR04超声波传感器进行测距,测距范围是3-65cm,讲得到的数据显示在LCD 1602液晶屏上。

模块工作原理如下
(1)采用 IO 触发测距,给至少 10us 的高电平信号;
(2)模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回;
(3)有信号返回,通过 IO 输出一高电平,高电平持续的时间就是超声波从发射到返回的时间
(4计算测试距离测试距离=(高电平时间*声速(340M/S))/2;
根据工作原理,我们可以选择两种模式驱动
1. 采用中断+定时器方式,将ECHO定义为上升沿下降沿都能触发中断,trig触发之后,echo高电平进中断打开定时器,echo低电平关闭定时器并统计定时器计数值
2. 采用普通IO+定时器模式,触发之后等待echo响应,响应时打开定时器,直到echo恢复低关闭定时器,获取时间
此处我采用的是第一种模式,利用MSP430的timerA 的捕获比较模式,在程序的中断中处理得到的数据,并转化成距离。
1:此模块不宜带电连接,如果要带电连接,则先让模块的 Gnd 端先连接。否则会影响
模块工作。
2:测距时,被测物体的面积不少于0.5平方米且要尽量平整。否则会影响测试结果。在下载程序的时候建议将连接echo的一端断开,避免出现不必要的问题。
可以参考这个视频资料
/**********************************************************下边是代码***************************************************/
//功能说明: 1602显示 超声波模块测距 串口发送至上位机
#include
#include "Config.h"
#include "1602.c"
#include "UART.h"
int count = 0;
int flag = 0;
#define uchar unsigned char
#define uint unsigned int
/***************????*******************************/
#define trig_H P2OUT|=BIT0 //????
#define trig_L P2OUT&=~BIT0
#define echo P2IN & BIT1 //????
uint cnt;
unsigned long int tim_data,dista_data,dista_data_all,dista_data_sum;
/***************??*******************************/
void delay(uint n)
{
uchar i;
for(;n>0;n--)
for(i=10;i>0;i--);
}
/********************??,????????***************/
void dista_f(unsigned long int distance_data)
{
dista_data_all=dista_data_all+distance_data;
cnt=cnt+1;
if(cnt==16)
{
cnt=0;
dista_data_sum=dista_data_all>>4;
dista_data_all=0;
LCD1602_write_double(13,1,dista_data_sum); //?1602?????
LCD1602_write_char(14,1,'m');
LCD1602_write_char(15,1,'m');
//Print_float(dista_data_sum, 2);
}
}
/**************???io?********************/
void Init_IO()
{
P2DIR = 0XFD;
P2OUT |= 0XFF;
P2IE |= BIT1; //??P2????
P2IES &=~BIT1; //????????
}
/**************??????******************/
void Init_Timer()
{
TACTL|=TACLR+TASSEL_2+ID_3; //???A???
//TACTL |= TASSEL1 + TACLR + ID0 + ID1 + MC0 + TAIE;
//TACCR0 = 9999;
}
void InitTimerB(){
TBCTL=TBSSEL1+ID1+ID0+MC0+TBCLR;//选择1/8SMCLK 增计数 清除TAR
TBCCTL0=CCIE;//CCR0中断允许 比较模式
TBCCR0=10000;//时间间隔10ms
}
/************???**************************/
void main( void )
{
WDTCTL = WDTPW + WDTHOLD; //?????
Clock_Init();
InitTimerB();
Init_IO();
UART_Init();
Start_1602(); //??1602
tim_data=0;cnt=0;dista_data=0;
delay(1000); //????
uchar string[] = "distance:";
LCD1602_write_str(0, 0, string);
_EINT(); //?????
while(1)
{
/*if(flag == 1)
{
Print_float(dista_data_sum, 2);
flag = 0;
}*/
trig_H; //?????
delay(2); //??15us
trig_L; //?????
delay(50); //????
while(echo); //????
delay(1000); //????
}
}
/*****************************P2???*******************/
#pragma vector=PORT2_VECTOR
__interrupt void port_init(void)
{
if(echo) //?????
{
TACTL|=TACLR+TASSEL_2+ID_3;
TACTL|=MC_2; //?????,?????????
P2IES|=BIT1; //??P2??????
}
else //?????
{
TACTL=0; //????,????
TACTL|=TASSEL_2+ID_3;
P2IES&=~BIT1; //??P2??????
tim_data=TAR; //????
dista_data=(tim_data*1000/58); //?????(??=us/58)
//dista_data=(tim_data*17/100);
dista_f(dista_data); //??????
}
P2IFG&=~BIT1; // P2???????
}
#pragma vector=TIMERB0_VECTOR
__interrupt void TimerBINT()
{
count++;
if(count>=300)
{
Print_float(dista_data_sum, 2);
//flag = 1;
count = 0;
}
}
/*********************************clock.c**********************************/
//****************************************************
//*************时钟源模块
//****************************************************
#include
#include "config.h"
#include "clock.h"
/********************系统时钟初始化****************/
void init_clk(void) //初始化系统时钟
{
uchar i;
BCSCTL1 &=~XT2OFF; //打开XT2振荡器
BCSCTL2 |=SELM_2+SELS;
do
{
IFG1 &=~OFIFG; //清除错误标志
for(i=0;i<0xff;i++); //延时等待
}
while((IFG1 & OFIFG)!=0);
IFG1 &=~ OFIFG;
}
/*******************************************1602.c***********************************/
#include
#include "Config.h"
#include "clock.h"
#include "1602.h"
//*************************************************************************
// 初始化IO口子程序
//*************************************************************************
void LCD1602Port_init()
{
P4SEL = 0x00;
P4DIR = 0xFF; //数据口输出模式
P5SEL = 0x00;
P5DIR|= BIT5 + BIT6 + BIT7; //控制口设置为输出模式
}
//***********************************************************************
// 显示屏命令写入函数
//***********************************************************************
void LCD1602_write_com(unsigned char com)
{
RS_CLR;
RW_CLR;
EN_SET;
DataPort = com; //命令写入端口
delay_ms(5);
EN_CLR;
}
//***********************************************************************
// 显示屏数据写入函数
//***********************************************************************
void LCD1602_write_data(unsigned char data)
{
RS_SET;
RW_CLR;
EN_SET;
DataPort = data; //数据写入端口
delay_ms(5);
EN_CLR;
}
//***********************************************************************
// 显示屏清空显示
//***********************************************************************
void LCD1602_clear(void)
{
LCD1602_write_com(0x01); //清屏幕显示
delay_ms(5);
}
//***********************************************************************
// 显示屏字符串写入函数
//***********************************************************************
void LCD1602_write_str(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0)
{
LCD1602_write_com(0x80 + x); //第一行显示
}
else
{
LCD1602_write_com(0xC0 + x); //第二行显示
}
while (*s)
{
LCD1602_write_data( *s);
s ++;
}
}
//***********************************************************************
// 显示屏单字符写入函数
//***********************************************************************
void LCD1602_write_char(unsigned char x,unsigned char y,unsigned char data)
{
if (y == 0)
{
LCD1602_write_com(0x80 + x); //第一行显示
}
else
{
LCD1602_write_com(0xC0 + x); //第二行显示
}
LCD1602_write_data( data);
}
//***********************************************************************
// 显示屏初始化函数
//***********************************************************************
void LCD1602_init(void)
{
LCD1602_write_com(0x38); //显示模式设置
delay_ms(5);
LCD1602_write_com(0x08); //显示关闭
delay_ms(5);
LCD1602_write_com(0x01); //显示清屏
delay_ms(5);
LCD1602_write_com(0x06); //显示光标移动设置
delay_ms(5);
LCD1602_write_com(0x0C); //显示开及光标设置
delay_ms(5);
}
void LCD1602_write_double(unsigned char x,unsigned char y,unsigned int data)
{
uchar i;
for(i=0;i<6;i++)
{
if(i==2)
LCD1602_write_char( x--, y, '.');
else
{
LCD1602_write_char( x--, y, 0x30+data%10);
data=data/10;
}
}
}
void LCD1602_write_int(unsigned char x,unsigned char y,unsigned int data)
{
uchar i;
for(i=0;i<2;i++)
{
LCD1602_write_char( x--, y, 0x30+data%10);
data=data/10;
}
}
void Start_1602()
{
LCD1602Port_init(); //系统初始化,设置IO口属性
delay_ms(100); //延时100ms
LCD1602_init(); //液晶参数初始化设置
}
uart.h
#ifndef _UART_H_
#define _UART_H_
#include "msp430x14x.h"
void Print_Str(uchar *s);
//*************************************************************************
// MSP430?????
//*************************************************************************
void UART_Init()
{
U0CTL|=SWRST + CHAR; //??SWRST,8?????
U0TCTL|=SSEL1; //SMCLK?????
U0BR1=baud_h; //BRCLK=8MHZ,Baud=BRCLK/N
U0BR0=baud_l; //N=UBR+(UxMCTL)/8
U0MCTL=0x00; //??????0,???9600bps
ME1|=UTXE0; //UART0????
ME1|=URXE0; //UART0????
U0CTL&=~SWRST;
IE1|=URXIE0; //???????
P3SEL|= BIT4 + BIT5; //??IO????????,??UART??
P3DIR|= BIT4; //??TXD0??????
}
//*************************************************************************
// ??0??????
//*************************************************************************
void Send_Byte(uchar data)
{
while(!(IFG1&UTXIFG0)); //?????????????
U0TXBUF=data;
}
//***************************************//
void Print_float(unsigned int t, unsigned char position)//????? position ???????
{
unsigned int s_int[5] = {0};
int i = 0;
while(t>0)
{
s_int[i++] = t%10;
t=t/10;
}
for(i=4;i>=0;i--)
{
if(i==position)
{
Send_Byte(0x30 + s_int[i]);
Send_Byte(0x2E);
}
else
{
Send_Byte(0x30 + s_int[i]);
}
}
//delay_ms(100);
Send_Byte('m');
Send_Byte('m');
Send_Byte(' ');
delay_ms(100);
}
//*************************************************************************
// ??0??int???
//*************************************************************************
void Print_int(unsigned int t)
{
unsigned int s_int[5];
unsigned int i = 1;
while(t>0)
{
s_int[i] = t%10;
t=t/10;
i++;
}
i--;
while(i)
{
Send_Byte(0x30 + s_int[i]);
i--;
}
}
//*************************************************************************
// ??0???????
//*************************************************************************
void Print_Str(uchar *s)
{
while(*s != '\0')
{
Send_Byte(*s++);
}
}
#endif
也欢迎进球球裙技术交流
点击链接加入群聊【嵌入式单片机Linux C交流群②】https://jq.qq.com/?_wv=1027&k=FW2qSMZ4
C语言单片机项目实战超声波雷达测距的更多相关文章
- 基于Linux下的C语言项目实战--本地账号管理系统
C语言开发项目实战: C语言是一门通用计算机编程语言,广泛应用于底层开发.C语言的设计目标是提供一种能以简易的方式编译.处理低级存储器.产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言.尽 ...
- 树莓派控制HC-SR04超声波模块测距(新手向+C语言向)
因为作业要求使用c语言代码,这里先附上一段摘自网上的代码 感谢KalaerSun的c语言代码,摘自https://blog.csdn.net/qq_25247589/article/details/6 ...
- 手把手和你一起实现一个Web框架实战——EzWeb框架(二)[Go语言笔记]Go项目实战
手把手和你一起实现一个Web框架实战--EzWeb框架(二)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 上一篇文章我们实现了框架的雏形,基本地 ...
- 手把手和你一起实现一个Web框架实战——EzWeb框架(三)[Go语言笔记]Go项目实战
手把手和你一起实现一个Web框架实战--EzWeb框架(三)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 本篇代码,请选择demo3 这一篇文章 ...
- 手把手和你一起实现一个Web框架实战——EzWeb框架(四)[Go语言笔记]Go项目实战
手把手和你一起实现一个Web框架实战--EzWeb框架(四)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 这一篇文章主要实现路由组功能.实现路由 ...
- 手把手和你一起实现一个Web框架实战——EzWeb框架(五)[Go语言笔记]Go项目实战
手把手和你一起实现一个Web框架实战--EzWeb框架(五)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 本篇代码,请选择demo5 中间件实现 ...
- 彩虹女神跃长空,Go语言进阶之Go语言高性能Web框架Iris项目实战-项目入口与路由EP01
书接上回,我们已经安装好Iris框架,并且构建好了Iris项目,同时配置了fresh自动监控项目的实时编译,万事俱备,只欠东风,彩虹女神蓄势待发.现在我们来看看Iris的基础功能,如何编写项目入口文件 ...
- 给缺少Python项目实战经验的人
我们在学习过程中最容易犯的一个错误就是:看的多动手的少,特别是对于一些项目的开发学习就更少了! 没有一个完整的项目开发过程,是不会对整个开发流程以及理论知识有牢固的认知的,对于怎样将所学的理论知识应用 ...
- Asp.Net Core 项目实战之权限管理系统(3) 通过EntityFramework Core使用PostgreSQL
0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...
随机推荐
- Nginx总结(九)Nginx服务器高性能优化的配置--轻松实现10万并发访问量
前面讲了如何配置Nginx虚拟主机,如何配置服务日志等很多基础的内容,大家可以去这里看看nginx系列文章:https://www.cnblogs.com/zhangweizhong/category ...
- 网站URL如何SEO优化
前言 本文讲解网站的URL如何进行SEO优化,并在自己的WordPress博客echeverra中优化URL. 起因 对于SEO我了解的并不多,只知道SEO做的好,那么各大搜索网站搜索你网站相关内容时 ...
- 【OI】C++STL 不定长数组 vector
Vector 本来是向量的意思,只不过在用法上类似于一个不限长度的数组. 定义语法:vector<数据类型> 名称; 一.头文件:<vector> (bits/stdc++请忽 ...
- 记录不存在则插入,存在则更新 → MySQL 的实现方式有哪些?
开心一刻 今天我爸.我.我女儿一起吃饭,我们每人一个鸡腿 女儿问道:爸爸,你吃鸡腿吗 我以为她要把她的鸡腿给我吃,倍感欣慰地说道:我不吃,宝贝 女儿一把抓起我的鸡腿放进了她爷爷的碗里,说道:不吃给爷爷 ...
- 【PHP数据结构】在学数据结构和算法的时候我们究竟学的是啥?
一说到数据结构与算法,大家都会避之不及.这本来是一门专业基础课,但是大部分人都并没有学好,更不用说我这种半路出家的码农了.说实话,还是很羡慕科班出身的程序员,因为你们在日常工作或者面试中,只需要复习一 ...
- 动态查看及加载PHP扩展
在编译并完成 php.ini 的配置之后,我们就成功的安装了一个 PHP 的扩展.不过, PHP 也为我们提供了两个在动态运行期间可以查看扩展状态以及加载未在 php.ini 中进行配置的扩展的函数. ...
- Java基础系列(41)- 冒泡排序
冒泡排序 冒泡排序无疑是最为出名的排序算法之一,总共有八大排序 冒泡的代码还是相当简单的,两层循环,外层冒泡轮数,里层依次比较,江湖中人人尽皆知 我们看到的嵌套循环,应该立马就可以得出这个算法的时间复 ...
- centos 7 & 6 优化脚本
简单优化 ,未涉及安全优化,如有需求请自行修改脚本实现 1 #!/bin/bash 2 SysVer=`cat /etc/redhat-release | awk -F'release' '{prin ...
- bzoj#2407-探险【最短路,二进制分组】
正题 题目链接:https://darkbzoj.tk/problem/2407 题目大意 \(n\)个点的一张无向图(但是正反权值不同),求一个从\(1\)出发回到\(1\)且不经过重复边的最短路径 ...
- PyCharm中文下载与安装教程【2021年更新】
第一章:下载与安装 1.1 [版本介绍]多个版本的介绍与选择 Jetbrain 公司是一家专业的 IDE 生产商,只要是市面上主流的编程语言,Jetbrain 都有相应的产品. 比如:Python ...