单片机利用串口通信传送温度

发布者:bobojrt最新更新时间:2018-06-20 来源: eefocus关键字:单片机  串口通信  传送温度 手机看文章 扫描二维码
随时随地手机看文章
/********该程序主要是利用DS18B20采集温度,然后通过数码管显示温度*************/
/*当程序收到上位机发送的命令之后,该程序会将当时的温度值通过串口发送给上位机*/
#include
#define uchar unsigned char
#define uint unsigned int
sbit DQ = P1^0;               //定义DS18B20的信号线端口
uchar i,j;
uchar dis_buffer[4];//定义数据缓冲数组
uchar bit_ser[]={0xfe,0xfd,0xfb,0xf7}; //定义数码管片选数组
uchar seven_seg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
                                                                    //定义数码管段选数组
/****************************延时函数*********************************/
void delay(uint x)
{
 while(x)
 x--;
}
/*************************DS18B20初始化函数***************************/
void Init_DS18B20(void)
{
 unsigned char x=0;
 DQ = 1;         //DQ复位
 delay(8);       //稍做延时
 DQ = 0;               //单片机将DQ拉低
 delay(80);     //精确延时 大于 480us
 DQ = 1;           //拉高总线
 delay(14);
 x=DQ;           //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
 delay(20);
}
/***************************从18B20中读一个字节************************/
uchar ReadOneChar(void)
{
 uchar i=0;
 uchar dat = 0;
 for (i=8;i>0;i--)
         {
                 DQ = 0;   // 给脉冲信号
                 dat>>=1;
                 DQ = 1;   // 给脉冲信号
                 if(DQ)
                 dat|=0x80;
                 delay(8);
         }
         return(dat);
}
/***************************向18B20中写一个字节************************/
Write_OneChar(uchar dat)
{
 uchar i=0;
 for (i=8; i>0; i--)
 {
         DQ = 0;     //给脉冲信号
         DQ = dat & 0x01;
         delay(5);
         DQ = 1;     //给脉冲信号
         dat >>= 1;
 }
 delay(4);
}
/**************************从18B20中读取一个字节***********************/
int Read_Temperature(void)
{
 uchar i = 0,t = 0,a,b;
 int temp;
 Init_DS18B20();
 Write_OneChar(0xcc);   // 跳过读序号列号的操作
 Write_OneChar(0x44);   // 启动温度转换
 Init_DS18B20();
 Write_OneChar(0xcc);   //跳过读序号列号的操作
 Write_OneChar(0xbe);   //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
 i = ReadOneChar();           //读取温度值低位
 t = ReadOneChar();           //读取温度值高位
 a = i & 0x0f;
 b = t;
 i = i >> 4;             //低位右移4位,舍弃小数部分
 t = t << 4;             //高位左移4位,舍弃符号位
 t = t | i;
 temp = (t + a * 0.0625) * 100; //得到一个比实际温度扩到100倍的值,主要是为了更好的显示和传输
 return(temp);                  //返回温度值
}

/***************************初始化定时器0******************************/
void timer0_init(void)                      //
{
 TMOD = 0x21; //由于串口通信需要使用定时器1,因此TMOD的值是0x21
 TL0 = (65536-5000) % 256;
 TH0 = (65536-5000) / 256;
 EA = 1;
 ET0 = 1;
 TR0 = 1;
}
/*************************发送数据的函数********************************/
void txd_data(char send_data)
{
 SBUF = send_data; //将需要发送的数据放入发送缓冲区
 while(!TI);           //等待发送数据
 TI = 0;
}
/********************T0中断处理函数,主要用于显示当前温度***************/
void timer0_isr(void) interrupt 1
{
 int temp;
 TR0 = 0;
 TL0 = (65536-5000) % 256;
 TH0 = (65536-5000) / 256;
 TR0 = 1;
 switch(i)
 {
         case 0:
                 P2 = bit_ser[0];
                 P0 = seven_seg[dis_buffer[0]];
                 break;
         case 1:
                 P2 = bit_ser[1];
                 P0 =seven_seg[dis_buffer[1]] & 0x7f;
                 break;
         case 2:
                 P2 = bit_ser[2];
                 P0 =seven_seg[dis_buffer[2]];
                 break;
         case 3:
                 P2 = bit_ser[3];
                 P0 =seven_seg[dis_buffer[3]];
                 break;
 }
 i++;
 if(i >= 4)
 {
         i = 0;
         j++;
         if(j >= 10)  //如果到200ms就会读取一次温度,并将温度值放入显示缓冲区
         {
                 j = 0;
                 temp = Read_Temperature();
                 dis_buffer[0] = temp / 1000;
                 dis_buffer[1] = temp % 1000 / 100;
                 dis_buffer[2] = temp % 100 / 10;
                 dis_buffer[3] = temp % 10;
         }
 }
}

/***************************串口通信初始化函数***************************/
void uart_init(void)
{
 SCON = 0x50;         //方式1,充许接收
 TMOD = 0x21;         //T1方式2定时,T0方式是1
 TH1 = 0xFd;          //波特率9600,Fosc=11.0592MHz
 TL1 = 0xFd;
 TR1 = 1;
 ES = 1;                    // 打开串口中断
}
/**************************串口中断处理函数*****************************/
void uart() interrupt 4
{
 char y,i;
 while(!RI);
 y = SBUF;                       //读取接收的信息,然后判断是否为发送温度命令
 if(y == '0')             //如果为发送命令,就将当前数据缓冲数组内的数据发送给上位机
 {
         for(i = 0;i <= 3;i++)
         {
                 txd_data(dis_buffer[i] + 48);
         }
 }
 RI = 0;
}
/*******************************主函数*********************************/
void main()
{
 timer0_init();           //调用T0初始化函数
 uart_init();             //调用串口初始化函数
 while(1)
 {}

}


关键字:单片机  串口通信  传送温度 引用地址:单片机利用串口通信传送温度

上一篇:单片机实时温度采集并通过串口通信上传电脑显示
下一篇:DS18B20温度传感器+12864液晶串口显示

推荐阅读最新更新时间:2024-03-16 16:06

基于单片机μPD780822的客车CAN总线灯光节点的设计及实现
1 引言 CAN(Controller Area Network)是德国Bosch公司最先提出的,是目前汽车控制器局域网中最流行、最常用的总线。它的主要特点是:CAN总线为多主站总线,各节点均可在任意时刻主动向网络上的其他节点发送信息,不分主从,通信灵活;CAN总线采用独特的非破坏性总线仲裁技术,优先级高的节点先传送数据,能满足实时性要求;CAN总线具有点对点、一点对多点及全局广播传送数据的功能;CAN总线上每帧有效字节数最多为8个,并有CRC及其他校验措施,数据出错率极低,某个节点出现严重错误,可自动脱离总线,总线上的其他操作不受影响;CAN总线只有2条导线,系统扩充时可直接将新节点挂在总线上,因此走线少,系
[单片机]
基于<font color='red'>单片机</font>μPD780822的客车CAN总线灯光节点的设计及实现
单片机软件UART的设计思想
目前扩展串口的方法主要有以下方法, ①、采用串口扩展芯片实现,如ST16C550、ST16C554、SP2538、MAX3110等,虽然成本较高, 但系统的可靠性得到了保证,适用于数据量较大、串口需求较多的系统;②、采用分时切换的方法将一个串口扩展与多个串口设备通信,分时复用的方法成本低, 但只适用于数据量不大的场合, 并且只能由这个单片机主动和多个设备通信,实时性差;③、用软件模拟的方法扩展串口,其优势也是成本低、实时性好, 但要占用一些CPU时间。 一般的软件模拟扩展串口方法,使用1个I/O端口、1个INT外部中断和定时器,该方法扩展的串口有2个缺点,①、由于使用了INT外部中断,故只能使用2个INT外部中断扩展2个串口。②
[单片机]
单片机时钟中断的应用
本文以6MHz时钟的单片机AT89C51系统为例,说明时钟中断的应用: 定时器初值与中断周期 时钟中断无需过于频繁,一般取20mS(50Hz)即可。如需要百分之一秒的时基信号,可取10mS(100Hz)。这里取20mS,用定时器T0工作于16位定时器方式(方式1)。T0的工作方式为:每过一个机器周期自动加1,当计满0FFFFh,要溢出时,便会产生中断,并由硬件设置相应的标志位供软件查询。即中断时比启动时经过了N+1个机器周期。所以,我们只要在T0中预先存入一个比满值0FFFFh小N的数,然后启动定时器,便会在N个机器周期后产生中断。这个值便是所谓的“初值”。下面计算我们需要的初值:时钟为6MHz,12个时钟周期为一个机器周期,2
[单片机]
基于AT89C52单片机实时时钟程序编写
#include‘reg52.h’ //包含单片机寄存器的头文件 #include‘intrins.h’ //包含_nop_()的头文件 sbit RS=P2^0; //LCD读写选择位 sbit RW=P2^1; //LCD读写选择位 sbit E=P2^2; //LCD使能端 sbit BF=P0^7; //忙信号 sbit SCLK=P1^0; //1302时钟输出端 sbit DATA=P1^1; //1302数据端 sbit RST=P1^2; //1302复位端 unsigned char code digit[]=“0123456789”; void delay1ms(unsigned int n) { un
[单片机]
基于AT89C52<font color='red'>单片机</font>实时时钟程序编写
单片机C语言程序设计:定时器控制交通指示灯
/* 名称:定时器控制交通指示灯 说明:东西向绿灯亮 5s 后,黄灯闪烁,闪烁 5 次亮红灯, 红灯亮后,南北向由红灯变成绿灯,5s 后南北向黄灯闪烁, 闪烁 5 次后亮红灯,东西向绿灯亮,如此往复。 */ #include reg51.h #define uchar unsigned char #define uint unsigned int sbit RED_A=P0^0; //东西向指示灯 sbit YELLOW_A=P0^1; sbit GREEN_A=P0^2; sbit RED_B=P0^3; //南北向指示灯 sbit YELLOW_B=P0^4; sbit
[单片机]
<font color='red'>单片机</font>C语言程序设计:定时器控制交通指示灯
一个由单片机管脚中断功能复用引发的bug
使用单片机控制ZL30151输出时钟,引脚连接关系如下: 其中A1、A0是作为复用器的地址线信号,ZL30151 SPI模式下的有用管脚如下: CSN(IF0)、SCLK(SCL)、RSTN、MOSI(SDA)、MISO(IF1)、AC0(GPIO0)、AC1(GPIO1)(这些管脚中的RSTN、AC0、AC1由FPGA控制),括号内是管脚的第二功能,主要用于芯片复位时的模式设置,具体到SPI模式:在RSTN的上升沿,IF1、IF0要置1,AC0、AC1置0。另外RSTN在上电之后要有一个复位的过程,需要拉低至少100ns。而RSTN是在FPGA端控制的,所以需要单片机和FPGA共同控制,方法是单片机项FPGA的寄存器写一个值
[单片机]
一个由<font color='red'>单片机</font>管脚中断功能复用引发的bug
STC15单片机6路专用PWM
(1)STC例程分析 /* STC15Fxx 系列 输出任意周期和任意占空比的PWM实例*/ #define CYCLE 0x1000L //定义PWM周期(最大值为32767) #define DUTY 10L //定义占空比为10% void pwm() { P0M0 = 0x00; //因PWM模块相关IO口初始状态为高阻,需要将IO口设置为准双向或推挽输出才能正常输出波形; P0M1 = 0x00; P1M0 = 0x00; P1M1 = 0x00; P2M0 = 0x00; P2M1 = 0x00; P3M0 = 0x00; P3M1 = 0x00; P4
[单片机]
51单片机P0口的特性及使用方法解析
一、P0口特性: P0口为三态双向I/O口。对于内部有程序存贮器的单片机基本系统(如定制的8051),P0口可以作为输入/输出口使用,直接连外部的输入/输出设备;也可以作为系统扩展的地址/数据总线口。对于内部没有程序存贮器的单片机(如8031),P0口只能作为地址/数据总线口使用。 1、P0口的输出驱动器中也有一个多路电子开关。输出驱动器转接至口锁动器的Q端时,P0口作为双向I/O口使用。 这时,CPU发来的控制信号为低电平,使输出驱动电路的上拉场效应管T1截止。P0口的锁存器为“1”时,输出驱动器中的两个场效应管均截止,引脚浮空;由于P0口输出电路是漏极开路的电路,必须外接10kΩ拉高电阻才能有高电平输出。而写入“0”时,下
[单片机]
51<font color='red'>单片机</font>P0口的特性及使用方法解析
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved