×
单片机 > 单片机程序设计 > 详情

PIC16F877单片机DS18B20数码管温度计仿真程序 可显示负温度

发布时间:2020-06-18 发布时间:
|

电路原理图如下:

//*********************************************************

//        实现的功能:数码管显示实时温度,支持负温度

//        芯片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



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ARM 汇编的必知必会