高级会员 
 
主题
回帖0
积分3518
阅读权限30
注册时间2011-6-19
最后登录1970-1-1
在线时间 小时
 
 
 
 
 | 
//2012年修改 pc0 接18b20 
 
#include <iom8v.h> //和单片机类型相对应的头文件,选择Atmega8做实验; 
#include <macros.h> 
#include <stdio.h> 
#include <eeprom.h> 
#include <MATH.H> 
#include <stdlib.h> 
#include <STRING.H> 
#define uchar unsigned char 
#define uint unsigned int 
#define LED_NUM    PORTD  
#define LED_VALUE  PORTB  
#define ADC_KEY    3  
#define SOUND_OUT  0x08  
#define FAN_OUT1   0x01 
#define FAN_OUT2   0x02 
#define FAN_OUT3   0x04 
#define DELAY_MIN  1100  
uint v = 0;  
uchar adc_channel = 0;  
uchar hot_warning[4]={34,34,34,45};  
uint  temper[3]={5,5,5};//存放温度 
uchar setting_mode = 0;  
uchar auto_mode = 0x00;  
uchar timeh=0x06; 
uchar temp2=0; 
uchar PWF1=0; 
uchar PWFS1=0,PWFS2=0,PWFS3=0;//是否进行调速标志 
uchar Fc1,Fc2,Fc3;//计数 
void init_1820();//初始化1820                                                                                 
write_1820(uchar x); //写参数到1820 
uchar read_1820(); //读温度 
void delay(uint x);  
void disp_led(uchar buffer,uchar control); 
void test(void); 
void delay_1ms(void);  
//uchar hot_warning[4]={30,35,40,45};//设定风扇启动温度 
void delay_nms(unsigned int n); 
unsigned int wendu[4]={21,22,23,24};//定义温度存放数组 
void temph(unsigned int tx); //电压转换成温度 
void display(void);// 显示数据 
void display_mode(uchar mo);//模式显示,花样显示 
void scandisplay(uint value);//扫描显示数码管 
void dc_save(void);//dc 转换结果存储后用 
void init_port();//初始化端口  
void output(uchar channel,uchar power);//风扇控制 函数 通道  风力 
unsigned int  uiVref_preset=4996;         // 参考电压=2665mV 
uchar Lednum[4]={0xEF,0xDF,0xBF,0x7F};//数码管公共端口 
uchar  disp_table[17] = { 
        0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 
        0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x40,0}; 
        //共阴数码管         
const uint v_table[135]={ 
950,1000,1050,1100,1150,1200,1250,1300,1350,1400,//-10-1 
1450,1500,1550,1600,1650,1700,1750,1800,1850,1900//0-9 
,1950,2000,2050,2100,2150,2200,2230,2260,2290,2320//10-19 
,2350,2380,2410,2440,2470,2520,2590,2600,2617,2670//20-29 
,2725,2800,2855,2935,2990,3041,3100,3148,3206,3260 
,3302,3354,3414,3450,3504,3554,3600,3650,3680,3748 
,3778,3818,3850,3889,3936,3986,4008,4015,4059,4089 
,4116,4124,4146,4170,4200,4224,4248,4275,4296,4314 
,4332,4353,4374,4395,4416,4428,4444,4461,4476,4488 
,4502,4528,4544,4552,4562,4574,4584,4594,4602,4612 
,4622,4632,4642,4652,4660,4668,4672,4680,4690,4698 
,4704,4713,4723,4728,4733,4738,                                                 
                                                }; 
const uchar sound[]={ //?Ρ?誹? 
        0x45,0x48,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x49,0x4a, 
        0x49,0x48,0x48,0x48,0x48,0x48,0x45,0x48,0x4a,0x4a, 
        0x48,0x4a,0x4c,0x4c,0x4b,0x4a,0x49,0x49,0x49,0x49, 
        0x49,0x4c,0x4b,0x4a,0x4a,0x4a,0x49,0x48,0x48,0x49, 
        0x4a,0x4c,0x4b,0x4b,0x4b,0x4b,0x4b,0x46,0x46,0x45, 
        0x45,0x45,0x47,0x48,0x49,0x49,0x4a,0x49,0x48,0x48, 
        0x48,0x48,0x48,0x48, 
        0x00,0x00 
};                 
uchar temp1[6]; 
uint count; 
#define PWM0                        3         //OC0   PB3 
#define PWM1A                        5         //OC1A  PD5 
#define PWM1B                        4         //OC1B  PD4 
#define PWM2                        7         //OC2   PD7 
#define   Fosc           4096000          //系统晶振频率 4.096MHz  
#define   Fosc_TIME2      (64*10)             //TIME2 比较中断频率=采样率*AD通道数*工频50Hz的倍数 
volatile unsigned char T2PWM;         
void main(void) 
{    
    uint i,k; 
        int j;         
        uchar temh,teml; 
  init_port();//初始化         
  hot_warning[0] = EEPROMread(0x01);  //读取报警温度 
  hot_warning[1] = EEPROMread(0x02);  
  hot_warning[2] = EEPROMread(0x03);   
     for(k=0;k<4;k++) //初始化 
      { 
           if (hot_warning[k]>120) 
            hot_warning[k]=32; 
      }         
  while(1)  
  {   init_1820();        //复位18b20  
                write_1820(0xcc);   // 发出转换命令  
                write_1820(0x44);  
                delay(400);  
                                 //scandisplay(count);  
                init_1820();  
                WDR();  
                write_1820(0xcc);  //发出读命令  
                 //scandisplay(count);  
                                write_1820(0xbe);  
                teml=read_1820();  //读数据  
                temh=read_1820();  
                count=((temh*256+teml)*6.25)/10;  //计算具体温度  
                scandisplay(temh); 
  }  
 
} 
 
//io口初始化 
void init_port() 
{ 
           OSCCAL=0X9d;   //系统时钟校准,不同的芯片和不同的频率, 
          //DDRB=0x03;     //定义B口的PB0、PB1为输出口 
          //DDRC=0x30;     //定义C口的PC4和PC5为输出口 
        //PORTD = 0x01;  //pd2.pd3.pd4输入 pd0 输出 
    //DDRD  = 0x01; 
    //CLKPR = 0x80;  
   // CLKPR = 0x00;     
    DDRB = 0xff;  
    PORTB = 0xff;  
    DDRC = 0x00;  
    PORTC = 0x00;  
         DDRB = 0xff;  
     PORTB = 0xff; 
    DDRD  = 0xFF;//定义PD0喇叭输出 PD2 PD3 PD4 按键输入 PD5 PD6 PD7 风扇输出 
        PORTD = 0xF7; //初始化 端口 数据 
        WDR();        //看门狗计数清零 
    WDTCR=0x0F;    //使能watchdog,并且,采用2048K分频,典型溢出时间5V时2.1S 
    //adc_init();                // 使能ADC 
        //timer2_init();             // 使能AD转换 
        CLI();  
    ADMUX = (1<<REFS0);    //选择基准 
    ADCSRA = (1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1);          
         MCUCR = 0x00; 
     GICR  = 0x00; 
    TIMSK = 0x15; //timer interrupt sources         
        SEI();       //开放中断 
          //WDTCSR = 0x0F; 
        //PORTB=0B00000010; //PB1口输出高电平,PB0口输出低电平,关闭绿灯,红灯亮 
          //delay_nms(500); //延时1秒 
        temp1[1]=1; 
        temp1[2]=2; 
        temp1[3]=3; 
        //test(); 
        timer0_init(); 
        timer1_init(); 
} 
//TIMER0 initialize - prescale:1024 
// desired value: 60mSec 
// actual value: 59.904mSec (0.2%) 
void timer0_init(void) 
{ 
 TCCR0 = 0x00; //stop 
 TCNT0 = 0x16; //set count 
 TCCR0 = 0x05; //start timer  
} 
#pragma interrupt_handler timer0_ovf_isr:10 
void timer0_ovf_isr(void) 
{ 
 TCNT0 = 0x16; //reload counter value 
} 
 
 
//数码管 扫描显示  
 
void scandisplay(uint value)  
{      
      uchar i,j,k,l;  
          uint tempvalue;  
      uchar led_data[4]; 
led_data[3]=16; 
 if ((value & 0x8000)==0x8000)  
  {  
      value &= 0x7fff;  
      led_data[2] = 15; // 顯示負號  
  }  
  else  
  {  
      value &= 0x7fff;  
           if(value<999)//需要加小数点 
      { 
       k=1; 
           led_data[2] = value/100; 
       } 
     else 
     { 
      k=0; 
          value=value/10; 
          led_data[2] = value/100; 
     }           
  };  
 
 led_data[1] = value%100/10;  
 led_data[0] = value%100%10; 
 if((led_data[2]==0)&&(led_data[1]==0)) 
 {//如果只有1位数的时候,将高位的0去掉 
 led_data[2]=16; 
 led_data[1]=16; 
 k=0;//去掉小数点 
 } 
    for (j=0;j<10;j++) //刷新20次 避免数据跳动 
     {   
         for (i=0;i<4;i++)  
      {  
                LED_VALUE = disp_table[led_data[i]];  
        if((i==1)&&(k==1))  
        {     
            LED_VALUE |= 0x80; // 加上小數點  
        }  
                LED_NUM&=Lednum[i];//对应位数码管点亮 
                delay_nms(10);  
           LED_NUM|= 0xF0;//只保留高3位为1  
      };  
     }; 
} 
 
void delay_1ms(void)//1ms延时函数 
{ 
  unsigned int i; 
  for (i=0;i<150;i++); 
  WDR();    //清看门狗 
} 
void delay_nms(unsigned int n)//延时n毫秒 
{ 
  unsigned int i; 
  for (i=0;i<n;i++)//执行n次1毫秒延时 
  delay_1ms();  
} 
#pragma interrupt_handler adc_isr:iv_ADC  
void adc_isr(void)  
{  uint temp;  
  temp = ADCL;  
  temp |= (int)ADCH<<8;   
  temp = (50*temp)/10;  
  v += temp;    
}  
void get_adc_value(uchar adc_pin)  
{   
  uchar i;  
  v = 0x0000;  
  ADMUX = (1<<REFS0)|adc_pin;  
  {  
  ADCSRA |= (1<<ADSC);  
  delay_nms(1);   
  ADCSRA &= ~(1<<ADSC);   
  }   
}  
uint get_degree(void)  
{  
  uchar x,y;  
  uint v_big,v_small,v_step;  
  if (v<100) return 0x83E7; // 當沒有信號時顯示-99.9錯誤  
  for (x=0;x<135;x++) // 查表  
  {  
      if ( v>= v_table[x]) // 找出電壓區域 // 
      {  
        v_big = v_table[x+1]; // 區域 高段  
        v_small = v_table[x]; //區域 低段  
        v_step = (v_big - v_small)/10; // 把區域細分成10份  
        for (y=0;y<10;y++) // 細分比較  
        {  
            v_small += v_step;  
            if (v < v_small) // 得出結果  
            {  
              v = x*10+y;// 其中x*10 為整數部分, y 為小數部分  
              if (x<10) // 少於10時為負溫度  
              {  
                           // v -= 400; // 0 度修正 
                  v |= 0x8000; // 加入負號標記  
                                  //v=v; 
              }  
              else  
              {  
               v -= 100; // 0 度修正  
              }  
                          
                  return v;  //返回温度 
            };  
        };  
      };  
      WDR();  
  }   
  return v;     
} 
uchar get_key_value(void) 
{ 
        get_adc_value(ADC_KEY); 
        if (v < 250) 
        { 
                return 0; 
        } 
        else 
        { 
                if ((v > 1000)&&(v < 1300)) 
                { 
                        return 1;//1150mv 
                } 
                else 
                { 
                        if ((v > 1300)&&(v < 2200)) 
                        { 
                                return 2;//1948 
                        } 
                        else 
                        { 
                                if ((v > 2200)&&(v < 3500)) 
                                { 
                                        return 3;//3000mv 
                                } 
                                else 
                                { 
                                        return 0; 
                                } 
                        } 
                } 
        } 
} 
 
void temp_setting(void) 
{ 
        uchar key; 
        key = get_key_value(); 
 
        if(key==2) 
        {  
                adc_channel++; 
 
                if (adc_channel>2) //切换显示路数 
                  {  
                   adc_channel = 0; 
                   } 
       scandisplay(adc_channel+1); 
           scandisplay(adc_channel+1); 
           scandisplay(adc_channel+1); 
           scandisplay(adc_channel+1);                 
        } 
        if(key==3) 
        { 
           if (auto_mode==0xff) // 自動模式  
        {  
                auto_mode = ~auto_mode;//退出 自动模式 
                } 
                 
                if (adc_channel==0) //设置模式 
                { 
                        adc_channel = 1; 
                        auto_mode = ~auto_mode;//3路自动切换 
                } 
                adc_channel--;                 
        } 
        while(1) 
        { 
                get_adc_value(ADC_KEY); 
                if(v < 200) //退出当前模式 
                { 
                        break; 
                }; 
        };         
        if (key==1)  
        { 
        scandisplay(1+adc_channel); 
        scandisplay(1+adc_channel); 
        scandisplay(1+adc_channel);         
        scandisplay(1+adc_channel);         
        setting_mode = 1; 
        } 
 
        while(setting_mode==1) 
        { 
                key = get_key_value(); 
                if(key==1) 
                { 
            adc_channel++;                                         
                        if (adc_channel>2) 
                        { 
                                adc_channel = 0; 
                                setting_mode = 0; 
                                EEPROMwrite(0x01, hot_warning[0]); 
                                delay_nms(5); 
                                EEPROMwrite(0x02, hot_warning[1]); 
                                delay_nms(5); 
                                EEPROMwrite(0x03, hot_warning[2]); 
                                delay_nms(5); 
                        } 
           scandisplay(1+adc_channel); 
           scandisplay(1+adc_channel); 
           scandisplay(1+adc_channel); 
           scandisplay(1+adc_channel);                                         
                } 
                else 
                { 
                        if(key==2) 
                        { 
                            if(hot_warning[adc_channel]>105) 
                                { 
                                hot_warning[adc_channel]=30; 
                                } 
                                else 
                                { 
                                ++hot_warning[adc_channel]; 
                                } 
                        } 
                        else 
                        {        if(key==3) 
                            { 
                            if(hot_warning[adc_channel]<1) 
                                { 
                                hot_warning[adc_channel]=30; 
                                } 
                            else 
                                {  
                                 --hot_warning[adc_channel]; 
                                } 
                                } 
                        }; 
                }; 
                while(1) 
                { 
                        get_adc_value(ADC_KEY); 
                        if(v < 200) 
                        { 
                                break; 
                        }; 
                }; 
                scandisplay(hot_warning[adc_channel]*10); 
        } 
} 
   
//TIMER1 initialize - prescale:1024 
// WGM: 0) Normal, TOP=0xFFFF 
// desired value: 500mSec 
// actual value: 499.968mSec (0.0%) 
void timer1_init(void) 
{ 
 TCCR1B = 0x00; //stop 
 TCNT1H = 0xFF; //setup 
 TCNT1L = 0xFC; 
 OCR1AH = 0x07; 
 OCR1AL = 0xA1; 
 OCR1BH = 0x07; 
 OCR1BL = 0xA1; 
 ICR1H  = 0x07; 
 ICR1L  = 0xA1; 
 TCCR1A = 0x00; 
 TCCR1B = 0x05; //start Timer 
} 
 
#pragma interrupt_handler timer1_compa_isr:7 
void timer1_compa_isr(void) 
{ 
 //compare occured TCNT1=OCR1A 
} 
#pragma interrupt_handler timer1_ovf_isr:9 
void timer1_ovf_isr(void) 
{ 
 //TIMER1 has overflowed 
 //TCNT1H = 0xF8; //reload counter high value 
 TCNT1H = 0xFF; 
 TCNT1L = 0xFC; //reload counter low value 
  //PORTD=bitcpl(PORTD,2);// 取反 。。。 
  // scandisplay(995); 
  Fc1++; 
  pwm1(); 
  Fc2++; 
  Fc3++; 
  //pwm2(); 
  
} 
 
void pwm1(void) // pwm 控制函数 
{ 
 //开始 调速控制 
 if(PWFS1) 
  { 
    //输出 
         if(Fc1<45) 
         { 
         PORTD=bitset(PORTD,0);//打开风扇 
         } 
    else 
     { 
     PORTD=bitclr(PORTD,0);//关闭风扇 
     } 
     if(Fc1>90) 
     { 
     Fc1=0; 
     } 
  } 
     //输出 
        if(PWFS2) 
        { 
         if(Fc2<45) 
         { 
         PORTD=bitset(PORTD,1);//打开风扇 
         } 
    else 
     { 
     PORTD=bitclr(PORTD,1);//关闭风扇 
     } 
     if(Fc2>90) 
     { 
     Fc2=0; 
     } 
   } 
     //输出 
        if(PWFS3) 
        { 
         if(Fc3<45) 
         { 
         PORTD=bitset(PORTD,2);//打开风扇 
         } 
    else 
     { 
     PORTD=bitclr(PORTD,2);//关闭风扇 
     } 
     if(Fc3>90) 
     { 
     Fc3=0; 
     } 
   }  
} 
uchar bitclr(uchar num,uchar bit) /*清除某一位*/ 
{ 
uchar bit_value[]={1,2,4,8,16,32,64,128}; 
return num&~bit_value[bit]; 
} 
uchar bitset(uchar num,uchar bit) /*设置某一位*/ 
{ 
uchar bit_value[]={1,2,4,8,16,32,64,128}; 
return num|bit_value[bit]; 
} 
uchar bitcpl(uchar num,uchar bit) /*取反某一位*/ 
{ 
uchar bit_value[]={1,2,4,8,16,32,64,128}; 
if(num>>bit&0x01==1) 
return num&~bit_value[bit]; 
else 
return num|bit_value[bit]; 
} 
void init_1820()  
{  
         PORTC|=(1<<0);     
         PORTC&=~(1<<0);  
         delay(3000);    //480us以上  
            PORTC|=(1<<0);  
         DDRC&=~(1<<0);  
         delay(40);     //15~60us  
         while(PINC&(1<<0))  
         {  
           // disp_led(3,0);  
                // for(;;)  
                 //{}  
        }  
         DDRC|=(1<<0);  
         PORTC|=(1<<0);  
         delay(150);   //60~240us  
}  
write_1820(uchar x)  
{     
     uchar m;  
         for(m=0;m<8;m++)  
         {  
              PORTC&=~(1<<0);  
                 if(x&(1<<m))    //写数据,从低位开始  
                 PORTC|=(1<<0);  
                 else  
                 PORTC&=~(1<<0);  
                 delay(40);   //15~60us  
                 PORTC|=(1<<0);  
         }  
          PORTC|=(1<<0);  
}  
 
 
uchar read_1820()  
{      
         uchar temp,k,n;  
           temp=0;  
         for(n=0;n<8;n++)  
            {  
                PORTC&=~(1<<0);  
                //delay(2);        
                PORTC|=(1<<0);  
                //delay(3);      
                DDRC&=~(1<<0);  
                k=(PIND&(1<<0));    //读数据,从低位开始  
                if(k)  
                temp|=(1<<n);  
                else  
                temp&=~(1<<n);  
                delay(50); //60~120us      
                DDRC|=(1<<0);  
        }  
        return (temp);  
}   
 
void delay(uint x)  //1.5us左右  
{  
          while(x)  
         {  
            x--;  
         }  
} |   
 
 
 
 |