>_<:功能概述:

通过串口PC和单片机通信,可以询问单片机测得的温度,可以询问声呐测距的测量距离,同时把测量温度显示在数码管上。

>_<:PC部分

这里com.cpp和com.h是串口通信的函数封装,在主函数中:

  • 刚开始调用封装好的串口通信函数,设置打开串口COM4,波特率设置为9600,超时设置:

 if(openport("com4"))
printf("open comport success\n");
if(setupdcb())
printf("setupDCB success\n");
if(setuptimeout(,,,,)) //如果所有写超时参数均为0,那么就不使用写超时
printf("setuptimeout success\n");
clearall();//全清
  • 接着循环接收控制台命令来与串口通信:这里用了串口通信函数WriteChar和ReceiveChar来与串口进行信息传送,注意这里的读写应和单片机的一致,否则就会出现错误。这里举a==5的例子说明:

    [命令5表示改变距离阈值,当输入5时,PC将向串口发送字符’5’,然后等待输入改变后的温度,当输入改变温度时,将该温度传给串口[因为我们这里的范围是0-100]所以一个char类型就能表示,将这个值发送给串口,当单片机改变好距离阈值后会返回改好的命令,所以调用ReceiveChar接收返回信息。其他类似。]
 while(){
scanf("%d",&a);//1表示要温度,2表示要距离,3表示距离警报关闭,4温度警报关闭,5改变距离阈值,6改变温度阈值
if(a==){ m_szWriteBuffer[]='';
WriteChar(m_szWriteBuffer,);
printf("Please enter the num:(0-100cm) \n");
scanf("%d",&a);
m_szWriteBuffer[]=(BYTE)(a);
WriteChar(m_szWriteBuffer,);
ReceiveChar(m_szReceiveBuffer,);
printf("%s\n",m_szReceiveBuffer);
}else if(a==){
m_szWriteBuffer[]='';
WriteChar(m_szWriteBuffer,);
printf("Please enter the num:(0-100℃) \n");
scanf("%d",&a);
m_szWriteBuffer[]=(BYTE)(a);
WriteChar(m_szWriteBuffer,);
ReceiveChar(m_szReceiveBuffer,);
printf("%s\n",m_szReceiveBuffer);
}else{
m_szWriteBuffer[]=(BYTE)(a+'');
WriteChar(m_szWriteBuffer,); ReceiveChar(m_szReceiveBuffer,);
printf("%s\n",m_szReceiveBuffer);
}
}

>_<:单片机部分

设备:

  • 18B20温度传感器
  • 8位数码管显示
  •  串口通信
  • HC-SR04超声波测距仪
  • STC89C52[11.0952MHz]
  • 蜂鸣器

连线:

  这里选用11.0592MHz的晶振,将8位7段数码管公共线接P0的8个端口,P2.3接位码,P2.2接段码;串口通信采用MAX232连接如图所示。

main函数介绍:

#初始化部分介绍:

1 unsigned int TempH,TempL,temp;
2 Init_Timer0();
3 UART_Init(); // 串口初始化
4 Init_Timer1();
5
6 ReadTemperature();//这里放置3个温度读取,防止出现初始化温度不稳定情况
7 ReadTemperature();
8 ReadTemperature();
  • 第2行:初始定时器:MOD |= 0x01---T0定时16位模式
  • 第3行:串口初始化:具体信息见注释
 void UART_Init(void)
{
SCON = 0x50; // 设定串行口工作方式,8位数据位,允许接收
T2CON = 0x34; //设置定时器2,作为波特率发生器
RCAP2L = 0XDC; //9600波特率的低8位
RCAP2H = 0XFF; //9600波特率的高8位
ES = ; //允许串口中断
EA = ; //允许总中断
}
  • 第6-8行: 在系统初始前先读取3次温度,防止系统初始时温度的值不正常而触发报警

#主循环介绍:

 while ()
{
if(isInclude || isAbove){
//LED_Show(2);
//if(freq==200);
SPK=!SPK;
}
if(uart_flag==) //接收到
{
ES=; //关串口中断
if(come==''){//接收并改变距离阈值
maxJuLi=(unsigned int)a;
come='';
UART_Send_Byte('O');
UART_Send_Byte('K');
UART_Send_Byte('#');
UART_Send_Byte('\n');
}else if(come==''){//接收并改变温度阈值
maxWenDu=(unsigned int)a;
come='';
UART_Send_Byte('O');
UART_Send_Byte('K');
UART_Send_Byte('#');
UART_Send_Byte('\n');
}else//其他操作
switch(a){//要温度
case '':
for(i=;i<;i++)
{
UART_Send_Byte(SendData[i]);//将数据发给串口
}
UART_Send_Byte('\n');
break;
case ''://要距离
for(i=;i<;i++)
{
UART_Send_Byte(SendData1[i]);//将数据发给串口
}
UART_Send_Byte('\n');
break;
case '':
if(isInclude){
isInclude=;
UART_Send_Byte('c');
UART_Send_Byte('l');
UART_Send_Byte('o');
UART_Send_Byte('s');
UART_Send_Byte('e');
UART_Send_Byte('#');
UART_Send_Byte('\n');
}else{
UART_Send_Byte('n');
UART_Send_Byte('o');
UART_Send_Byte(' ');
UART_Send_Byte('p');
UART_Send_Byte('e');
UART_Send_Byte('r');
UART_Send_Byte('s');
UART_Send_Byte('o');
UART_Send_Byte('n');
UART_Send_Byte('#');
UART_Send_Byte('\n');
}
break;
case '':
if(isAbove){
isAbove=;
UART_Send_Byte('c');
UART_Send_Byte('l');
UART_Send_Byte('o');
UART_Send_Byte('s');
UART_Send_Byte('e');
UART_Send_Byte('#');
UART_Send_Byte('\n');
}else{
UART_Send_Byte('n');
UART_Send_Byte('o');
UART_Send_Byte(' ');
UART_Send_Byte('f');
UART_Send_Byte('i');
UART_Send_Byte('r');
UART_Send_Byte('e');
UART_Send_Byte('#');
UART_Send_Byte('\n');
}
break;
case '':
come='';
break;
case '':
come='';
break;
default://错误操作
for(i=;i<;i++)
{
UART_Send_Byte(SendData2[i]);//将数据发给串口
}
UART_Send_Byte('\n');
break;
}
ES=; //允许串口中断
uart_flag=; //中断标志位置0
}
else if(ReadTempFlag==)//通过定时器,每隔1200ms扫描一次温度
{
ReadTempFlag=;
temp=ReadTemperature();
if(temp&0x8000)//第一位为1就表示为负要取反加1第一位弄个负号
{
TempData[]=0x40;//负号标志
temp=~temp; // 取反加1
temp +=;
}
else
TempData[]=;//其他情况就该显示负号的不显示 TempH=temp>>;//去除低四位
TempL=temp&0x0F;//获取温度低四位
TempL=TempL*/;//小数近似处理! if(TempH> && TempH>maxWenDu)isAbove=;//界限判断 if(TempH/==)//百位数据
TempData[]=;
else
TempData[]=DuanMa[TempH/]; //百位温度
if((TempH%)/==)//十位温度
TempData[]=;
else
TempData[]=DuanMa[(TempH%)/];
TempData[]=DuanMa[(TempH%)%]|0x80; //个位温度,带小数点
TempData[]=DuanMa[TempL];
TempData[]=0x39; //显示C符号 SendData[]=(unsigned char)(TempH/+'');
SendData[]=(unsigned char)(TempH%/+'');
SendData[]=(unsigned char)(TempH%%+'');
SendData[]='.';
SendData[]=(unsigned char)(TempL+'');
}else if(ReadTempFlag==){
ReadTempFlag=;
StartModule(); //测距
while(!RX); //当RX为零时等待
TR1=; //开启计数
while(RX); //当RX为1计数并等待
TR1=; //关闭计数
Conut(); //计算
}
}
  • 第3-7行:当温度在阈值外或者距离在阈值内时就响铃
  • 第8-103行:当串口通信发生串口中断时,会把uart_flag标志位置1,然后主程序就会处理PC端传送过来的数据,这里采用串口中断来检测是否收到PC发来的数据的:
 void UART(void) interrupt
{
if(RI) //检测接收完成标志位置1
{
RI=; //清零接收完成标志位
a=SBUF; //读取接收到的数据
uart_flag = ; //中断标志位置1
}
}
  • 第11-25行:这里是要修改温度或者距离的阈值时用到的特殊处理,因为当收到修改阈值的命令之后还要等待要改成的值,为了区别这个值和命令值,于是用come标记是否是要修改阈值,如果不是修改阈值,就正常判断命令,否则就做相应的阈值修改。
  • 第27-33行:将温度发送给PC,最后要发送一个换行,当做结束标志位[这是和PC端的接收程序有关,2个通信的协议要一致],其他类似,不做详解。
  • 第41-86行:关闭报警命令,如果正在报警,就关闭报警,返回给电脑已经关闭的信息;如果没有报警,就回复电脑相应信息。
  • 第87-92行:要修改阈值,就把come置成相应的值,等待接受要修改值,与第11-25行相对应
  • 第104-141行:如果没有电脑命令传过来就进行温度采集和距离测试:
 void Timer0_isr(void) interrupt
{
static unsigned int num;
TH0=(-)/;//重新赋值 2ms
TL0=(-)%; Display(,); // 调用数码管扫描
num++;
if(num==){
ReadTempFlag=;//读温度标志位置2
}else if(num==)
{
num=;
ReadTempFlag=;//读距离标志位置1
}
}
  • 第143-147行:测量时间差[用定时器TH1,TL1]
  • 第148行:计算超声波测距的距离[根据上面计算的声波来回的时差]
 void Conut(void)
{
time=TH1*+TL1;
TH1=;
TL1=;
S=(time*1.87)/; //算出来是CM
if(flag==) //超出测量
{
flag=;
//printf("-----\n");
}
if(S<maxJuLi)isInclude=;//界限判断
//.......
}

全部资源连接:http://pan.baidu.com/s/1ntukZ8l

51单片机-PC数据传输 温度 距离 监控系统设计的更多相关文章

  1. 51单片机PC程序计数器

    PC是一个16位的计数器.用于存放和指示下一条要执行的指令的地址.寻址范围达64KB.PC有自动加1功能,以实现程序的顺序执行.PC没有地址,是不可寻址的,无法用指令对它进行读写.但在执行转移.调用. ...

  2. [新概念51单片机C语言教程·郭天祥] 1、 基础知识必备

    目录: 单片机的大致介绍         1-1.通俗定义         1-2.51系列产品         1-3.标号意思         1-4.引脚介绍         1-5.用C语言开 ...

  3. 51单片机C语言学习笔记3: 存储器结构

    MCS-51单片机在物理结构上有四个存储空间: 1.片内程序存储器2.片外程序存储器3.片内数据存储器4.片外数据存储器 但在逻辑上,即从用户的角度上,8051单片机有三个存储空间: 1.片内外统一编 ...

  4. 51单片机引脚ALE/PROG/PSEN/EA/Vpp

    51单片机的4个控制引脚,其中一个引脚是复位引脚(RST/Vpd),RST是复位引脚,当RST输入端保持2个机器周期以上高电平时,就实现复位. ALE/PROG是地址锁存允许信号输出端,在读写外部存储 ...

  5. ET 与RETI 基于51单片机中断跳出指令“RETI”浅议

    最近在基于51单片机编程的过程中出现了个很奇怪的问题“程序执行中在寄存器EA=1,ET0=1,TR0=1条件下,单TF0=1时并没有执行中断”.在有过单片机中断编程经历者都知道当EA=1,ET0=1的 ...

  6. 51单片机和STM32单片机区别在那里

    ​大部分朋友可能都知道51单片机和stm32单片机也知道一般入门会先学习51单片机在学习stm32单片机会简单一些,但是对于51单片机和stm32单片机的具体区别却不知道了,有些人觉得没必要,但是我个 ...

  7. 51单片机学习笔记(郭天祥版)(1)——单片机基础和点亮LED灯

    关于单片机型号的介绍: STC89C52RC40C-PDIP 0721CV4336..... STC:STC公司 89:89系列 C:COMS 52(还有51,54,55,58,516,):2表示存储 ...

  8. 51单片机——My-Clock项目

    技术:51单片机.光敏传感器.PCF8591.DHT11.DS1302.OLED显示屏   概述 项目My-Clock是一个环境监测时钟,接入光敏传感器和温湿度传感器监测环境信息,加入DS1302模块 ...

  9. STM32单片机和51单片机区别

    单片机 / AVR / PIC / STM32 / 8051803189C5189S51 6905 单片机简介 单片微型计算机简称单片机,简单来说就是集CPU(运算.控制).RAM(数据存储-内存). ...

随机推荐

  1. java异常和spring事务注解

    http://www.techferry.com/articles/spring-annotations.html http://www.oschina.net/question/2367675_23 ...

  2. ExtJs弹出窗口

    1.Ext.Msg.alert(String title, String msg, [Function fn], [Object scope]) 显示一个标准的带有一个"确定"按钮 ...

  3. 2.1 LibCurl编程流程(转)

    转载地址:http://blog.chinaunix.net/u/17660/showart_1822514.html2 LibCurl编程2.1 LibCurl编程流程在基于LibCurl的程序里, ...

  4. Android 环境通过国内映像快速搭建

    Android 环境通过国内映像快速搭建 转眼大半年没有写android程序了,回顾从环境搭建开始. 因为google受国内限制,因此下载android的SDK相当慢,因此寻找国内的镜像进行搭建. 首 ...

  5. Html模板

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 5.0 Transitional//EN"> <!-- saved from ur ...

  6. Block的copy和循环引用的问题

    在实际开发中,发现使用Block有着比delegate和notification更简洁的优势.于是在目前的项目中大量的使用block. 在我的头文件我是这样声明使用block的. 我将block声明为 ...

  7. VS发布网站详细步骤

    1.打开你的VS2012网站项目,右键点击项目>菜单中 重新生成一下网站项目:再次点击右键>发布: 2.弹出网站发布设置面板,点击<新建..>,创建新的发布配置文件: 输入你自 ...

  8. SQL Server 扩展一个支持类似。net 时间格式化的标量函数~

    * FROM sys.objects WHERE name=N'uF_DateFormat' AND [type]='FN') DROP FUNCTION uF_DateFormat GO SET A ...

  9. mysql 4种启动方式

    mysql 4种启动方式 都是去调用mysqld文件 1. mysqld 启动 进入mysqld文件所在目录(/../libexec/mysqld) ./mysqld --defaults-file= ...

  10. 0801 am使用tp框架对数据库增删改查

    增添数据,3种方法 function Text3() { $m=D("info"); //1.使用数组 $attr = array( "code"=>&q ...