⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 毛璐可用程序备份.c

📁 单片机访问多片DS18B20,同时显示在SPI控制的8位8段数码管上,其中用到DS18B20的单总线技术,还有演示程序截图,其中主控单片机为MEGA16
💻 C
字号:

#include <mega16.h>
#include "delay.h"
// SPI functions
#include <spi.h> 

#define data_out PORTA.0      //定义18B20所用的数据线
#define data_en DDRA.0
#define data_in PINA.0 
// Declare your global variables here 
unsigned char code[8];         //18b20序列号临时寄存器
//eeprom unsigned char DS_mount;   //18B20个数
//eeprom unsigned char ds1820_rom_codes[MAX_DS1820][8];  //18b20的序列号
unsigned char DS_mount;   //18B20个数      //正式使用时用存在EEPROM,就不用每次都初使化
unsigned char ds1820_rom_codes[8][8];  //18b20的序列号
unsigned char disp[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
             //数码管显示的编码     
float w=0.0;   
//*******************************************
//            74HC595驱动程序
//*******************************************     
unsigned char SPI_W_R(unsigned char data)    //SPI口读写程序
{
	SPCR=0x50;                  //SPI为查询方式,系统时钟四分频
	SPDR=data;                  //写入数据
	while((SPSR>>7)==0x00);     //等待数据发送完毕
	return SPDR;                //返回收到的数据  
}

//*******************************************************************
//                     温度测量
void init18b20()                 //初始化18B20,即复位18B20
{data_en=1;//置位输出状态
 data_out=1;
 data_out=0;
 delay_us(490);
 data_out=1;
 data_en=0;
 delay_us(20);
 while(data_in);
 data_en=1;
 data_out=1;
 delay_us(140);
 }
void write18b20(unsigned char n)   //写一个字节到18b20程序
{ unsigned char m;  
    for(m=0;m<8;m++)  
    {  
       data_out=0;  
       data_out=n&1; 
       delay_us(40);   //15~60us  
       data_out=1; 
       n=n>>1; 
    }  
     data_out=1;  
 }
unsigned char read18b20()        //从18b20读一个字节程序
{unsigned char temp,k,n;  
 temp=0;
 data_en=1;  
 for(n=0;n<8;n++)  
   {  
   data_out=0;  
   data_out=1;  
   data_en=0;  
   k=(data_in);    //读数据,从低位开始  
   if(k)  
   temp|=(1<<n);  
   else  
   temp&=~(1<<n);  
   delay_us(100); //60~120us      
   data_en=1;  
     }  
   return (temp);  
 }
 

 
unsigned int gettemperature(char codes[8])  //从相应序列号读转换温度
{unsigned char k,temh,teml;//wm0,wm1,wm2,wm3;  
     init18b20();        //复位18b20   
     write18b20(0xcc);      
     write18b20(0x44);   // 发出转换命令  
     delay_ms(800); 
     init18b20();
     write18b20(0x55);      //送序列号
     for(k=0;k<8;k++) {write18b20(codes[k]);delay_us(6);}
     write18b20(0xbe);  
     teml=read18b20();  //读数据  
     temh=read18b20(); 
     return (unsigned int)temh*256+(unsigned int)teml; 
   }  

void main(void)
{bit flag;   //初始化18B20时,开关开着,且没有读到一个18b20时为0
 int value;  
 char i;  
 DDRB=0xff;
 PORTB=0xff;
 DDRC=0x00;
 PORTC=0xff; 
 for(i=0;i<8;i++)          //初始化数码管,让数码管不显示什么值
  {
   SPI_W_R(0xff);
   PORTB.0=0;
   delay_us(10);
   PORTB.0=1; 
   }   

   while(PINC.1==0)             //初始化18B20,把每一个18B20的序列号
   {                            //读入到ds1820_rom_codes[DS_mount]数组中
                                //后面就可以根据序列号来读18B20了
     if(PINC.0==1&&flag==0)
      {
       init18b20();
       write18b20(0x33);
       for(i=0;i<8;i++){code[i]=read18b20();}
       for(i=0;i<8;i++){ds1820_rom_codes[DS_mount][i]=code[i];}
       DS_mount++;
       flag=1;
       }
     if(PINC.0==0)flag=0;
    }    

 while (1)
      {
  
     for(i=0;i<DS_mount;i++)    //  按顺序读每一个18B20的值
     {
      value=gettemperature(ds1820_rom_codes[i]);
      w=(float)value;
      w/=16;  

      SPI_W_R(disp[(int)(w*10)%10]);  //显示每一个18B20测出的温度
      SPI_W_R(disp[(int)w%10]); 
      SPI_W_R(disp[(int)(w/10)]); 
      SPI_W_R(0x0ff);
      SPI_W_R(disp[i]);      
      SPI_W_R(disp[0]); 
      PORTB.0=0;
      delay_us(10);
      PORTB.0=1; 
      delay_ms(1000);  
      }
     
      }
}
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -