基于PIC单片机的实时温度控制系统

发布者:740322lwj最新更新时间:2016-11-02 来源: eefocus关键字:PIC单片机  实时温度  控制系统 手机看文章 扫描二维码
随时随地手机看文章
//*********************************************************

// 实现的功能:数码管显示实时温度,支持负温度
// 芯片PIC16F877
// XT:4MHZ
//*********************************************************
#include        //包含单片机内部资源预定义
#define LVP 0x3f39

// 晶振:XT;代码:没有代码保护;上电延时定时器关闭;
// 低电压复位禁止;看门狗关闭 ;低电压编程禁止
__CONFIG (XT & UNPROTECT & PWRTDIS & BORDIS & WDTDIS & LVP);

#define uch unsigned char                     //给unsigned char起别名 uch
#define DQ RA2                                //定义18B20数据端口 
#define DQ_DIR TRISA2                         //定义18B20D口方向寄存器 
#define DQ_HIGH() DQ_DIR =1                   //设置数据口为输入
#define DQ_LOW() DQ_DIR = 0;DQ = 0            //设置数据口为输出

const unsigned char ledcode[12]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40};
//不带小数点的共阴极数码管0123456789段码,正负符号位
const unsigned char ledcode1[12]={0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x00,0x40};   
//带小数点的共阴极数码管0123456789段码 ,正负符号位

void init_port(void);
void delay(char x,char y); 
void delay_1ms(void);
void delay_ms(unsigned int time);
void interrupt dealtime();
void tmint(void);
void timetoseg(uch fh_temp,uch bai_temp,uch shi_temp,uch ge_temp,uch sf_temp,uch bf_temp,uch qf_temp,uch wf_temp);
void binary_temp(uch TL , signed char TH);
void reset(void);
void write_byte(uch val);
uch read_byte(void);
void get_temp(void);

unsigned char display_data[8];
unsigned char intcount=0; 
uch TLV=0 ;                        //采集到的温度高8位
uch THV=0;                         //采集到的温度低8位

union temp                         //定义一个联合体
{
int T; 
uch TV[2]; 
}temp;

signed char TZ=0;                     //转换后的温度值整数部分,有符号位
uch TX=0;                            //转换后的温度值小数部分

unsigned int wd;                              //转换后的温度值BCD码形式

unsigned char fh;                               //符号位
unsigned char bai;                             //整数百位
unsigned char shi;                             //整数十位
unsigned char ge;                              //整数个位
unsigned char shifen;                          //十分位
unsigned char baifen;                          //百分位
unsigned char qianfen;                         //千分位
unsigned char wanfen;                          //万分位


//*********************************************************
//    主程序
//*********************************************************
void main(void)
{
init_port();
tmint();
while(1)
{         
   get_temp();
   timetoseg(fh,bai,shi,ge,shifen,baifen,qianfen,wanfen); 
         
}
}
//*********************************************************
// 端口初始化
// PORTD作为数码管段驱动(高有效)
// PORTE作为数码管位选择驱动(低有效)
//*********************************************************
void init_port(void)
{
RBPU=0;
// PORTB=0xFF;
TRISB=0xFF; 
PORTD=0x00;           //
TRISC=0x00;           //C口控制LED指示灯,设置成输出
TRISD=0;            //D口当作数码管段,设置成输出
ADCON1=0x07;         //使A口,E口全为数字I/O口
TRISE=0x00;   //E口当作数码管位选择控制脚,设置成输出   
PORTE=0x00; 
}
//*********************************************************
//   延时程序
//*********************************************************
void delay(char x,char y) 
{
char z;
do{
      z=y;
      do{;}while(--z);
     }while(--x);
}
//其指令时间为:7+(3*(Y-1)+7)*(X-1)如果再加上函数调用的call 指令、页面设定、传递参数花掉的7 个指令。
//则是:14+(3*(Y-1)+7)*(X-1)。
//*********************************************************
//   延迟程序
//*********************************************************
void delay_1ms(void)
{
unsigned int n;
for(n=0;n<50;n++)
   {
    NOP();
   }
}
//*********************************************************
void delay_ms(unsigned int time)
{
for(;time>0;time--)
   {
    delay_1ms();
   }
}

//-----------------------------------------------
//复位DS18B20函数
void reset(void)
{
uch presence=1;
while(presence)

    DQ_LOW() ;                                //主机拉至低电平
    delay(2,90);                              //延时>480503us
    DQ_HIGH();                                //释放总线等电阻拉高总线,并保持15~60us
    delay(2,8);                               //延时>60us
    if(DQ==1) presence=1;                     //没有接收到应答信号,继续复位
    else presence=0;                          //接收到应答信号
    delay(2,70);                              //延时>240us
   }
}

//-----------------------------------------------
//写18b20写字节函数
void write_byte(uch val)
{
uch i;
uch temp;
for(i=8;i>0;i--)
{
   temp=val&0x01;                            //最低位移出
   DQ_LOW(); 
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();                                    //从高拉至低电平,产生写时间隙
   if(temp==1) DQ_HIGH();                   //如果写1,拉高电平
   delay(2,7);                               //延时63us
   DQ_HIGH(); 
   NOP();
   NOP();
   val=val>>1;                               //右移一位
}
}

//------------------------------------------------
//18b20读字节函数
uch read_byte(void)
{
uch i;
uch value=0;                                //读出温度
static bit j;
for(i=8;i>0;i--)
{
   value>>=1; 
   DQ_LOW();          //每次读时隙由主机发起,拉低总线至少1μs。
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();                                   //6us
   DQ_HIGH();          //读时隙开始后的15μs内释放总线,拉至高电平,准备采样总线。
   NOP(); 
   NOP();
   NOP(); 
   NOP(); 
   NOP();                                  //5us
   j=DQ;               //采样总线
   if(j) value|=0x80; //把采样到的数据放入value
   delay(2,7);               //所有读时隙至少60μs,这里大约63us
}
return(value);
}

//-------------------------------------------------
//启动温度转换函数
void get_temp()

int i;
DQ_HIGH();
reset();                                 //复位等待从机应答 
write_byte(0XCC);                        //忽略ROM匹配 
write_byte(0X44);                        //发送温度转化命令 
for(i=10;i>0;i--)
    {    
        delay(201,132);                       
    }   

reset();                                 //再次复位,等待从机应答 
write_byte(0XCC);                        //忽略ROM匹配 
write_byte(0XBE);                        //发送读温度命令

TLV=read_byte();                  //读出温度低8位 
THV=read_byte();                  //读出温度高8位

DQ_HIGH();                               //释放总线

                                          
TZ=(TLV>>4)|(THV<<4);           //温度整数部分
TX=TLV<<4;                      //温度小数部分,注意TX的后四位无效码
binary_temp(TX, TZ );   //将相应的温度二进制值转换成十进制数
}

//将相应的温度温度整数部分和小数部分的二进制值转换成十进制数

void binary_temp(char TL , signed char TH)
{
if(TH>=0)                          //如果是正温度
{
    fh=0x0A;                                 //正数符号位
    bai=TH/100;                               //整数部分百位
    shi=(TH%100)/10;//十位                   //整数十位
    ge=(TH%100)%10;//个位                          //整数部分个位

    wd=0; 
    if (TL & 0x80) wd=wd+5000;
    if (TL & 0x40) wd=wd+2500;
    if (TL & 0x20) wd=wd+1250;
    if (TL & 0x10) wd=wd+625;                //以上4条指令把小数部分转换为BCD码形式            

    shifen=wd/1000;                          //十分位                    
    baifen=(wd%1000)/100;                    //百分位
    qianfen=(wd%100)/10;                     //千分位
    wanfen=wd%10;                            //万分位
    NOP();
   }
else                                       //否则,是负温度,要求补码
{
temp.TV[0]=TL;temp.TV[1]=TH ;
temp.T=(~temp.T)+0x0010;              //补码形式,起反加1       
TL=temp.TV[0];
TH=temp.TV[1];

    fh=0x0B;                                //负数符号位
    bai=TH/100;                               //整数部分百位
    shi=(TH%100)/10;//十位                   //整数十位
    ge=(TH%100)%10;//个位                          //整数部分个位

    wd=0; 
    if (TL & 0x80) wd=wd+5000;
    if (TL & 0x40) wd=wd+2500;
    if (TL & 0x20) wd=wd+1250;
    if (TL & 0x10) wd=wd+625;                //以上4条指令把小数部分转换为BCD码形式            

    shifen=wd/1000;                          //十分位                    
    baifen=(wd%1000)/100;                    //百分位
    qianfen=(wd%100)/10;                     //千分位
    wanfen=wd%10;                            //万分位
    NOP();
}  
}

//          温度值各位转换成段码
//*********************************************************
void timetoseg(uch fh_temp,uch bai_temp,uch shi_temp,uch ge_temp,uch sf_temp,uch bf_temp,uch qf_temp,uch wf_temp)
{
   display_data[0] = ledcode[wf_temp];
   display_data[1] = ledcode[qf_temp];
   display_data[2] = ledcode[bf_temp];
   display_data[3] = ledcode[sf_temp];
   display_data[4] = ledcode1[ge_temp];
   display_data[5] = ledcode[shi_temp];
   display_data[6] = ledcode[bai_temp];
   display_data[7] = ledcode[fh_temp];
}


//*********************************************************
//    定时中断初始化(OPTION_REG)
//*********************************************************
void tmint(void)
{
T0CS=0;      //时钟源为内部指令周期            
PSA=0;           //分频器分配给TMR0 
// 
PS2=0;          //TMR0的分频比为1:16          
PS1=1;
PS0=1;
//
GIE=1;          //允许总中断 
T0IE=1;         //允许定时器0溢出中断
T0IF=0;         //清楚定时器0中断标志
TMR0=0X06;      //预置初值 T=(256-6)x16=4000uS
}
//*********************************************************
void interrupt dealtime()   //中断入口,该中断完成数码管的动态扫描
{                          //每中断一次的时间为4毫秒
    T0IF=0;
    TMR0=0X06;

    PORTD = 0x00;            //先关闭显示
   if(intcount==0)
     {
      PORTD = display_data[0];
      PORTE=0x00;
      intcount+=1;
     }
   else if(intcount==1)
     {
      PORTD = display_data[1];
      PORTE=0x01;
      intcount+=1;
     }
   else if(intcount==2)
     {
      PORTD = display_data[2];
      PORTE=0x02;
      intcount+=1;
     }
   else if(intcount==3)
     {
      PORTD = display_data[3];
      PORTE=0x03;
      intcount+=1;
     }
   else if(intcount==4)
     {
      PORTD = display_data[4];
      PORTE=0x04;
      intcount+=1;
     }
   else if(intcount==5)
     {
      PORTD = display_data[5];
      PORTE=0x05;
      intcount+=1;
     } 
   else if(intcount==6)
     {
      PORTD = display_data[6];
      PORTE=0x06;
      intcount+=1;
     }   
    else if(intcount==7)
     {
      PORTD = display_data[7];
      PORTE=0x07;
      intcount = 0;
     }   

}

仿真图:基于PIC单片机的实时温度控制系统 - Hope - Hope的世界

 
关键字:PIC单片机  实时温度  控制系统 引用地址:基于PIC单片机的实时温度控制系统

上一篇:PIC18F的CCP模块的捕捉模式实现电机测速的方法
下一篇:PIC IIC读写

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

基于C8051F040的模型车无线控制系统的设计
0 引 言 汽车耐久性试验是汽车试验的重要组成部分,而在试验过程中试验人员驾驶行为的变化,往往导致实验结果不一致,从而降低了实验数据的有效性。因此各大汽车公司相继采用驾驶机器人代替试验人员进行汽车试验。利用驾驶机器人进行试验对于减轻人类劳动强度,降低试验环境对试验人员的伤害,提高试验效率、试验结果的客观性和准确度,节省试验费用,进而加速汽车研发进度都有重要的意义。 为了测试驾驶机器人以及驾驶算法的可靠性,必须有一个仿真驾驶系统能满足驾驶机器人的要求。本文所设计模型车无线控制系统则是实现机器人仿真驾驶的主要环节,为驾驶机器人及其驾驶算法提供了实验平台。 系统采用了1:10电动模型车,速度的调节由电子调速器和一个无刷直流电机
[单片机]
基于C8051F040的模型车无线<font color='red'>控制系统</font>的设计
基于51单片机的太阳能路灯控制系统设计方案
简介:太阳能路灯控制系统:51单片机练手项目,简单可复制。 带太阳能充电功能,oled显示, 白天根据光强判断开关灯晚上开灯,二级菜单可以设置时间日期。 太阳能充电:传统锂电池充电芯片TP4056,使用6V太阳能板,给3.7V18650电池充电。 经过资料显示 18650电池尽量不要让其电压低于2.7V,所以后级供电电路(5V升压电路)MT3608启动引脚EN脚 连接了LM393制成的电压比较器。和电池电压比较,电池电压低于2.7v,MT3608启动脚拉低关断。 供电:使用升压芯片MT3608给单片机供电,让电池电压稳定在5.1V,来提供稳定电压。 #include reg52.h #include oled.h #i
[单片机]
基于51单片机的太阳能路灯<font color='red'>控制系统</font>设计方案
机车空调逆变电源控制系统及其实现
引言:  随着电力电子学科的发展,逆变器控制技术与工业现场总线应用范围越来越广,本系统成功应用这两项技术,设计了机车空调电源用逆变器控制系统。原有空调电源逆变器控制系统的缺点是:不能根据设定温度控制空调机组变频运行,体积大,各逆变器协调控制困难。本文设计了一种机车空调机组用多逆变器控制系统,与原有空调电源逆变器控制系统相比,有体积小、重量轻、数据交换方便、运行可靠、利于维修等优点。  1 系统工作原理:  由图1可知,上位微机控制电路是该系统的核心控制部分,通过CAN总线将控制指令传给逆变器控制电路,逆变器控制电路根据控制指令产生不同频率的SPWM信号控制逆变器工作;逆变器控制电路将各逆变器实际工作状态、故障信号等通过C
[嵌入式]
基于单片机的模拟路灯控制系统设计方案
0 引言 本文采用高效节能环保的LED 灯作为光源,利用传感器模块、光控路灯模块、恒流源模块来实现,根据环境、交通等因素,单片机采集光敏电阻或光电开关的信号控制路灯的亮灭,实现了光电和时间控制; 同时具有交通情况检测、故障自动检测与报警等功能,实现了路灯的智能化控制,节省了电力能源和人力资源。 1 系统设计要求方案 1.1 系统设计要求。 设计并制作一套模拟路灯控制系统,路灯布置如图1 所示。要求实现模拟路灯控制系统的时钟功能,设定显示开关灯时间,并能控制支路按时开灯和关灯;根据环境明暗的变化自动控制开灯和关灯; 根据交通情况自动调节亮灯状态; 独立控制每只路灯的开灯和关灯时间; 当路灯出现故障时,支路控制器发出滴答的报警
[单片机]
基于单片机的模拟路灯<font color='red'>控制系统</font>设计方案
PIC单片机的C语言使用(一)
在MPLAB-IDE中使用HitechC编译器 一、装入编译器: 1、启动MPLAB-IDE,如下图所示选择Project-》Install Language Tool 2、在弹出的安装语言工具对话框里“Language Suite”选项现在显示的是Microchip,点击后面的箭头来选择语言。 我使用的工具是HI-TECH PICCME,所以选择为“HI-TECH PICC”。 3、接下来在“Tool Name”里选择编译器组件的调用路径,这里有“PICC Compiler”(C编译器)、“PICC Assembler”(汇编器)和“PICC Linker”(链接器)3项都需要设置。 用
[单片机]
<font color='red'>PIC单片机</font>的C语言使用(一)
基于ARM的APT控制系统设计
空间光通信是以光波作为载波,在空间中进行信息无线传输的一种新型通信技术,其具有保密性高,抗干扰性强,通信速率高等优点,将会在卫星与卫星、卫星与地面控制站的无线通信领域发挥重要的作用,具有广阔的应用前景。但是由于光波波束窄,空间环境又比较复杂,而给通信链路的建立造成了极大的困难,所以对于空间光通信,必须先使用一套捕获、瞄准与跟踪(Acquisition,Pointing and Tracking,APT)系统来建立和维持光通信链路。嵌入式系统具有高性能、低功耗、低成本的优点,使其在运动控制上的应用具有很大优势,以ARM嵌入式处理器为基础的控制系统现在已经得到了广泛应用。针对目前卫星通信终端必须具有高实时性、高集成度、低功耗、体积
[工业控制]
基于ARM的APT<font color='red'>控制系统</font>设计
基于PLC的液压脉冲试验机控制系统设计
1 引言 在汽车、飞机和工程机械等设备上的液压传动系统的管路受到不同工况的振动冲击。随着人们对产品可靠性要求的提高,以及各种行业发展的需要,管路的抗冲击和抗挠曲性能将越来越受到重视,因而管路的抗冲击性能成为反映其质量和可靠性的重要指标。随着我国汽车工业的迅速发展,需要液压脉冲设备来进行检测软管在不同环境和工况下的性能。 液压脉冲试验机用于汽车刹车管、燃油管、转向管、冷却水管、散热软管和暖风软管等软管脉冲压力的寿命试验,该试验机能方便、稳定的检测出设备所用的软管是否符合标准的要求。 液压脉冲试验机控制系统是基于plc的二级混合控制系统,下位机采用rockwell automation的slc500作为核心处理器的实时控制器,上位
[嵌入式]
基于AT89S52与PIC16F877A的在线编程控制系统的设计
l 引 言 通常进行单片机的实验或开发时,传统的并行编程方法中,编程器是必不可少的。仿真、调试完的程序需要借助编程器烧到单片机内部或外接的程序存储器中。在开发过程中,程序每改动一次就要拔下电路板上的芯片,编程后再插上。随着计算机技术的发展,许多公司推出了带有片内FLASH存储器的MCU,FLASH存储器具有电可擦除、无需后备电源保护数据、可在线编程等特点。在线编程目前有两种实现方法:在线系统编程(ISP)和在线应用编程(IAP)。ISP一般是通过单片机专用的串行编程接口对单片机内部的FLASH存储器进行编程,例如AT-MEL公司的单片机AT89S52就提供了一个SPI串行接口对内部程序存储器编程(ISP)。 在线编程(ISP)
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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