立即注册 登录
返回首页

uid:83710的个人空间

日志

水温控制系统终结版

已有 1457 次阅读2015-6-25 02:37 | 控制系统

 #include"iostm8s105k4.h"
#include"qudong.h"
#include"18b20.h"
void wendudeal()
{
   wendu= DS18B20_ReadTemperature1(0);
   wendu1= DS18B20_ReadTemperature1(1);
   wendu_medium=(int)((wendu+wendu1)*10/2);
   wendu_display[0]=wendu_medium/100;
   wendu_display[1]=wendu_medium%100/10;
   wendu_display[2]=wendu_medium%10;
  
      dis_flag3[0]=time3_set/1000;
      dis_flag3[1]=time3_set%1000/100;
      dis_flag3[2]=time3_set%1000%100/10;
      dis_flag3[3]=time3_set%10;
     
      if(start_it==0)
      {
        if(wendu_medium>ad_sum)PA_ODR&=~0x04;
         if(wendu_medium<=ad_sum)PA_ODR|=0x04;
      }
}
main()
{
  
  Init_UART2();
                hex_led();
                Init_Timer4();
                 clock_hsi_16mhz();
                key_inint();
                TIM2_Init();
             //    read_rom_cmd();
                 TIM3_Init();
                asm("rim");//开全局中断
  while (1)
  {
                   wendudeal();
                   key_scan();
                   set_pwm();
  }
}


//18b20.h
#include"iostm8s105k4.h"
/******** STM8S-Discovery DS18B20 Test ********
* 版本.........: 1.0
* 作者.........: 陈利栋
* 目标.........: STM8S105C6
* 文件名.......: main.c
* 编译器.......: IAR for STM8 V1.1
* 创建时间.....: 2010.09.10
* 最后修改.....: 2010.09.10
**********************************************/
#define DS18B20_DQ_OUT          PB_DDR_DDR0 = 1   //输出
#define DS18B20_DQ_IN           PB_DDR_DDR0 = 0   //输入
#define DS18B20_DQ_HIGH         PB_ODR_ODR0 = 1   //拉高
#define DS18B20_DQ_LOW          PB_ODR_ODR0 = 0   //拉低
#define DS18B20_DQ_PULL_UP      PB_CR1_C10  = 1   //上拉
#define DS18B20_DQ_FLOATING     PB_CR1_C10  = 0   //浮空
#define DS18B20_DQ_PUSH_PULL    PB_CR1_C10  = 1   //推挽
#define DS18B20_DQ_OPEN_DRAIN   PB_CR1_C10  = 0   //开漏
#define DS18B20_DQ_VALUE        PB_IDR_IDR0       //DQ值
#define maxnum  2
#define uchar unsigned char
float wendu,wendu1;
unsigned char rom_code[8];
unsigned char const laseredrom[2][8]=
{
  0x1d,0x00,0x00,0x05,0xcf,0x53,0x2b,0x28,
  0x10,0x00,0x00,0x05,0xd0,0x28,0x2d,0x28,
};
unsigned char id[maxnum][8];
void _delay_us(unsigned int i)
{
    i *= 3;
     while(--i);
}
void _delay_ms(unsigned int i)
{
    while(i--)
    {
        _delay_us(1000);
    }
}
void DS18B20_Init(void)
{
    DS18B20_DQ_OUT;  
    DS18B20_DQ_PUSH_PULL;   
    DS18B20_DQ_HIGH;  
    _delay_us(10);
    DS18B20_DQ_LOW;  
    _delay_us(600);     //复位脉冲
   
    DS18B20_DQ_IN;  
    DS18B20_DQ_PULL_UP;   
    _delay_us(100);    
    while(DS18B20_DQ_VALUE == 1);
    _delay_us(400);
}
void DS18B20_WriteByte(unsigned char _data)
{
    unsigned char i = 0;
    DS18B20_DQ_OUT;
    for (i = 0; i < 8; i++)
    {
        DS18B20_DQ_LOW;
        _delay_us(2);
        if (_data & 0x01)
        {
            DS18B20_DQ_HIGH;
        }
        _data >>= 1;
        _delay_us(60);
        DS18B20_DQ_HIGH;
    }
}

void DS18B2_WRITEBIT(uchar data)
{
    DS18B20_DQ_OUT;
     DS18B20_DQ_LOW;
       if (data & 0x01)
        {
            DS18B20_DQ_HIGH;
        }
        _delay_us(60);
       DS18B20_DQ_HIGH;
      
}
unsigned char DS18B20_2BITS(void)
{
  unsigned char i,data=0;
  for(i=0;i<2;i++)
  {
     DS18B20_DQ_OUT;
     DS18B20_DQ_LOW;
     _delay_us(5);
     data<<=1;
      DS18B20_DQ_HIGH;
      DS18B20_DQ_IN;
       if (DS18B20_DQ_VALUE)
         data|=0x01;
       DS18B20_DQ_OUT;
        DS18B20_DQ_HIGH;
        _delay_us(60);
  }
  return data;
}
unsigned char DS18B20_ReadByte(void)
{
    unsigned char i = 0, _data = 0;
    for (i = 0; i < 8; i++)
    {
        DS18B20_DQ_OUT;
        DS18B20_DQ_LOW;
        _delay_us(5);
        _data >>= 1;
        DS18B20_DQ_HIGH;
        DS18B20_DQ_IN;
        if (DS18B20_DQ_VALUE)
        {
            _data |= 0x80;
        }
        DS18B20_DQ_OUT;
        DS18B20_DQ_HIGH;
        _delay_us(60);
    }
    return _data;
}
float DS18B20_ReadTemperature(void)
{
    unsigned char temp = 0;
    float t = 0;
   
    DS18B20_Init();
    DS18B20_WriteByte(0xcc);
    DS18B20_WriteByte(0x44);
    DS18B20_Init();
    DS18B20_WriteByte(0xcc);
    DS18B20_WriteByte(0xbe);
    temp = DS18B20_ReadByte();
    t = (((temp & 0xf0) >> 4) + (temp & 0x07) * 0.125);
    temp = DS18B20_ReadByte();
    t += ((temp & 0x0f) << 4);
   
    return t;
}
float DS18B20_ReadTemperature1(unsigned char j)
{
    unsigned char i,temp = 0;
    float t = 0;
   
    DS18B20_Init();
    DS18B20_WriteByte(0x55);
    for(i=0;i<8;i++)
    DS18B20_WriteByte(laseredrom[j][7-i]);
    DS18B20_WriteByte(0x44);
     
    DS18B20_Init();
    DS18B20_WriteByte(0x55);
    for(i=0;i<8;i++)
    DS18B20_WriteByte(laseredrom[j][7-i]);
   
    DS18B20_WriteByte(0xbe);
    temp = DS18B20_ReadByte();
    t = (((temp & 0xf0) >> 4) + (temp & 0x07) * 0.125);
    temp = DS18B20_ReadByte();
    t += ((temp & 0x0f) << 4);
    return t;
}
float DS18B20_read(unsigned char i)
{
  unsigned char j,temp = 0;
  float t = 0;
    DS18B20_Init();
    DS18B20_WriteByte(0xcc);
    DS18B20_WriteByte(0x44);
    DS18B20_Init();
    DS18B20_WriteByte(0x55);
    for(j=0;j<8;j++)
    {
       DS18B20_WriteByte(id[i][j]);
    }
     DS18B20_WriteByte(0xbe);
     temp = DS18B20_ReadByte();
    t = (((temp & 0xf0) >> 4) + (temp & 0x07) * 0.125);
    temp = DS18B20_ReadByte();
    t += ((temp & 0x0f) << 4);
   
    return t;
}
 
void read_rom_cmd(void)
{
  unsigned char i;
    DS18B20_Init();
    DS18B20_WriteByte(0x33);
    for(i=0;i<8;i++)
    rom_code[i]= DS18B20_ReadByte();
}
//qongdong.h
#include"iostm8s105k4.h"
unsigned char HexTable[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
unsigned char code_hex[]={0x7f,0x0c,0xb6,0x9f,0xcc,0xdb,0xfb,0x0f,0xff,0xdf,0x0c,0x72,0xb0,0x00};//0,1,2,3,4,5,6,7,8,9,1,C,c, ,
unsigned char code_flag3[]={0x7f,0xe6,0xf2,0x6f,0x72,0x70,0x7f,0xda};//open  close
unsigned char code_n[]={0xfb,0xf7,0xef,0xdf};
unsigned char time4_i;
unsigned char time3_flag,time3_flag_i;
unsigned char dis_flag3[4];
unsigned int time3_i;
unsigned int  time2_ccr;
unsigned char start_it;
int time3_set=3600;
unsigned int ad_sum=300;
unsigned char set,flag;
extern float wendu,wendu1;
int wendu_medium;
unsigned char wendu_display[3];
void clock_hsi_16mhz(void)
{
        CLK_ICKR|=0x01;      //开启内部HSI
 while(!(CLK_ICKR&0x02));//HSI准备就绪
 CLK_SWR=0xe1;        //HSI为主时钟源
 CLK_CKDIVR=0x00;     //HSI不分频
}

void hex_led(void)
{
          PE_DDR|=0x20;
   PE_CR1|=0x20;
   PE_CR2|=0x00;
          PE_ODR|=0x00;
         
          PC_DDR|=0xFF;
   PC_CR1|=0xFF;
   PC_CR2|=0x00;
          PC_ODR|=0x00;
         
          PB_DDR|=0x3C;
   PB_CR1|=0x3C;
   PB_CR2|=0x00;
          PB_ODR|=0x3C;
       
}
void dis_hex_led(unsigned char dat,unsigned char  n)
{
 // PC_ODR=0x00;
 //  PE_ODR&=0x00;
   PB_ODR|=0x3c;
   PB_ODR&=code_n[n];
   PC_ODR=code_hex[dat];
   if(n!=1)
   PE_ODR&=~0x20;
  else  PE_ODR|=0x20;
  if(ad_sum==1000)
    PE_ODR&=~0x20; 
  if(flag==3)
   PE_ODR&=~0x20;  
}
void dis_hex_flag3(unsigned char dat,unsigned char  n)
{
   PB_ODR|=0x3c;
   PB_ODR&=code_n[n];
   PC_ODR=code_flag3[dat];
   PE_ODR&=~0x20; 
}
void Init_UART2(void)
{
      UART2_CR1=0x00;
      UART2_CR2=0x00;
      UART2_CR3=0x00;
      // 设置波特率,必须注意以下几点:
      // (1) 必须先写BRR2
      // (2) BRR1存放的是分频系数的第11位到第4位,
      // (3) BRR2存放的是分频系数的第15位到第12位,和第3位
      // 到第0位
      // 例如对于波特率位9600时,分频系数=2000000/9600=208
      // 对应的十六进制数为00D0,BBR1=0D,BBR2=00
      UART2_BRR2=0x0B;//以115.2kHz频率发送数据
      UART2_BRR1=0x08;
      UART2_CR2=0x08;//允许接收,发送,开接收中断
     
          PD_DDR|=0x20;
   PD_CR1|=0x40;
   PD_CR2|=0x20;
          PD_ODR|=0x00;
         
}
void UART2_sendchar(unsigned char c)
{
      while((UART2_SR & 0x80)==0x00);
      UART2_DR=c;
}
void UART2_sendhex(unsigned char dat)
{
  UART2_sendchar('0');
  
                UART2_sendchar('x');
  
                UART2_sendchar(HexTable[dat>>4]);
  
                UART2_sendchar(HexTable[dat&0x0f]);
  
                UART2_sendchar(' ');
}
void UART2_sendstr(unsigned char *dat)
{
  while(*dat!='\0')
  
                {
    
                  UART2_sendchar(*dat);
    
                  dat++;
    //delay2us();
  
                }
}
void  UART2_sendnum(unsigned char dat)
{
  unsigned char dat_code[3];
  dat_code[0]=dat/100;
  dat_code[1]=dat%100/10;
  dat_code[2]=dat%10;
  if(dat>=100)
      UART2_sendchar(HexTable[dat_code[0]]);
   if(dat>=10)
      UART2_sendchar(HexTable[dat_code[1]]);
   if(dat>0)
      UART2_sendchar(HexTable[dat_code[2]]);
}
void Init_Timer4(void)
{
    TIM4_CR1=0x01;//使能计数器
  //TIM4_IER=0x00;
    TIM4_IER=0x01;//更新中断使能
    TIM4_EGR=0x01;   //自动重装的值
    TIM4_PSCR=0x07;//分频值128分频周期4ms
}

void key_inint(void)
{
          PD_DDR&=~0x85;
   PD_CR1|=0x85;
   PD_CR2|=0x00;
         
          PF_DDR|=~0x10;
   PF_CR1|=0x10;
   PF_CR2|=0x00;
      
          PA_DDR|=0x06;
   PA_CR1|=0x06;
   PA_CR2|=0x06;
          PA_ODR|=0x04;        
}
void delay(unsigned  int i)
{
  while(i--);
}
void set_key(void)
{
  ++set;
  if(set==3)
    set=0;
}
void add_key(void)
{
  switch(set)
  {
  case 0:ad_sum+=100;break;
  case 1:ad_sum+=10;break;
  case 2:ad_sum+=1;break;
  default: ad_sum+=0;break;
  }
  if(ad_sum>1000)ad_sum=1000;
}
void del_key(void)
{
  switch(set)
  {
  case 0:ad_sum-=100;break;
  case 1:ad_sum-=10;break;
  case 2:ad_sum-=1;break;
  default: ad_sum-=0;break;
  }
  if(ad_sum<100)ad_sum=100;
 
}
void sendtepandset()
{
    if(flag==2)
                 {
                unsigned char sum_h,sum_l;
                sum_h=ad_sum/100;
                UART2_sendchar('\n');
               UART2_sendchar('S');
               UART2_sendchar('E');
               UART2_sendchar('T');
                if(sum_h==10)
                {
                   UART2_sendnum(100);
                
                }
                else
                {
                   UART2_sendchar(HexTable[sum_h]);
                  sum_h= ad_sum%100/10;
                  sum_l= ad_sum%10;
                   UART2_sendchar(HexTable[sum_h]);
                   UART2_sendchar('.');
                   UART2_sendchar(HexTable[sum_l]);
                }
                 UART2_sendchar('o');
                 UART2_sendchar('C');
                 UART2_sendchar('\n');
                 sum_h=wendu_medium/100;
                  UART2_sendchar('T');
                  UART2_sendchar('E');
                 UART2_sendchar('P');
                  if(wendu_display[0]>=10)
                  {
                     UART2_sendnum(100);
                  }
                  
                  else
                  {
                   UART2_sendchar(HexTable[wendu_display[0]]);
                   UART2_sendchar(HexTable[wendu_display[1]]);
                   UART2_sendchar('.');
                   UART2_sendchar(HexTable[wendu_display[2]]);
                  }
                  UART2_sendchar('o');
                 UART2_sendchar('C');
                 UART2_sendchar('\n');
                      }
}
void time3_flag_set()
{
  if(time3_flag_i==0)
  {
  ++time3_flag;
  if(time3_flag==2)
   time3_flag=0;
   start_it=0;
  
  }
  else
  {
    ++time3_flag_i;
    if(time3_flag_i==5)
      time3_flag_i=1;
  }
}
void time3_flag_i_add()
{
  if(time3_flag==1)
  {
   switch(time3_flag_i)
   {
   case 0:time3_set+=0;time3_flag_i=1;break;
   case 1:time3_set+=1;break;
   case 2:time3_set+=10;break;
   case 3:time3_set+=100;break;
   case 4:time3_set+=1000;break;
   default:time3_flag_i=1;break;
   }
   if(time3_set>10000)time3_set=9999;
  }
}

void time3_flag_i_del()
{
  if(time3_flag==1)
  {
   switch(time3_flag_i)
   {
   case 0:time3_set-=0;time3_flag_i=1;break;
   case 1:time3_set-=1;break;
   case 2:time3_set-=10;break;
   case 3:time3_set-=100;break;
   case 4:time3_set-=1000;break;
   default:time3_flag_i=1;break;
   }
   if(time3_set<=200)time3_set=200;
  }
}
void key_scan_flag3()
{
   if(flag==3)
     {
          switch(PD_IDR&0x85)
        {
          case 0x84:PA_ODR^=0x02;time3_flag_i_del();break;
          case 0x81:PA_ODR^=0x02;time3_flag_i_add();break;
          case 0x05:PA_ODR^=0x02;time3_flag_set();break;
          default:break;
        }
      }
    
}
void key_scan(void)
{
  if((PF_IDR&0X10)!=0X10)
  {
     delay(200);
     if((PF_IDR&0X10)!=0X10)
      {
          PA_ODR^=0x02;
          if(flag==0)
          {
             flag=1; 
            Init_UART2();
                             
          }
       switch(flag)
       {
       case 1:flag=2;sendtepandset();break;
       case 2:flag=3; time3_flag_i=0; break;
       case 3:flag=1;break;
       default:flag=1;break;
       }
         while((PF_IDR&0X10)!=0X10);
       }
  }
  if((PD_IDR&0x85)!=0x85)
                  {
                    delay(200);
                    if((PD_IDR&0x85)!=0x85)
                    {
                     if(flag==1||flag==0)
                     {
                      switch(PD_IDR&0x85)
                      {
                      case 0x84:PA_ODR^=0x02;del_key();break;
                      case 0x81:PA_ODR^=0x02;add_key();break;
                      case 0x05:PA_ODR^=0x02;set_key();break;
                      default:break;
                      }
                     }
                     if(flag==2)
                     sendtepandset();
                      key_scan_flag3();
                       while((PD_IDR&0x85)!=0x85);
                    }
                     
                  } 
 
}
 
void TIM2_Init()
{
TIM2_CCMR2 = TIM2_CCMR2 | 0x70;// Output modePWM2.        
                                //通道2被设置成比较输出方式
                                // OC2M = 111,为PWM模式2,
                                // 向上计数时,若计数器小于比较值,为无效电平
                                // 即当计数器在0到比较值时,输出为1,否则为0
TIM2_CCMR1 = TIM2_CCMR1 | 0x70;
TIM2_CCER1 = TIM2_CCER1 | 0x33;// CC polarity low,enable PWMoutput      */
                                // CC2P = 1,低电平为有效电平
                                // CC2E = 1,开启输出引脚              
  
//初始化自动装载寄存器,决定PWM方波的频率,Fpwm=16000000/1000=16kHZ     
  TIM2_ARRH = 1000/256;
  TIM2_ARRL = 1000%256;
 
   TIM2_CCR1H = 0;
  TIM2_CCR1L = 0; 
//初始化比较寄存器,决定PWM方波的占空比           
  TIM2_CCR2H = 0;
  TIM2_CCR2L = 0;
     
//初始化时钟分频器为1,即计数器的时钟频率为Fmaster=4MHZ
  TIM2_PSCR =0x00;//因为用了继电器,所以哟分频,可到0x08,256分频
//启动计数
TIM2_CR1 = TIM2_CR1 | 0x01;
}
void set_pwm(void)
{
 
  if(start_it==0)
      {
          if(time2_ccr<300)
          time2_ccr=300;
        if(wendu_medium>ad_sum)
        {
          ++time2_ccr;
          if(time2_ccr>900)
            time2_ccr=900;
           TIM2_CCR1H = time2_ccr/256;
           TIM2_CCR1L = time2_ccr%256;
            TIM2_CCR2H = (1000-time2_ccr)/256;
            TIM2_CCR2L = (1000-time2_ccr)%256;
        }
         if(wendu_medium<=ad_sum)
        {
          --time2_ccr;
          if(time2_ccr<300)
            time2_ccr=300;
           TIM2_CCR1H = time2_ccr/256;
           TIM2_CCR1L = time2_ccr%256;
           TIM2_CCR2H = (1000-time2_ccr)/256;
           TIM2_CCR2L = (1000-time2_ccr)%256;
        }
      }
  else
  {
     TIM2_CCR1H = 0;
     TIM2_CCR1L = 0;
     TIM2_CCR2H = 1000/256;
     TIM2_CCR2L = 1000%256;
  }
 /* unsigned char i;
 
   for(i=0;i<255;i++)
   {
     TIM2_CCR1H = 15;
     TIM2_CCR1L = i;
     TIM2_CCR2H = 15;
     TIM2_CCR2L = i;
   //  delay(100);
   }
   // 下面的循环将占空比逐渐从50%递减到0
   for(i=255;i>0;i--)
   {
      TIM2_CCR2H = 15;
     TIM2_CCR2L = i;
     TIM2_CCR1H = 15;
     TIM2_CCR1L = i;
     //delay(100);
   }
   */
}
void timer4_task0()
{
   switch(time4_i)
    {
      case 1:dis_hex_led(11,3);break;
      case 2:
           {
          
             dis_hex_led(ad_sum/100,0);
          }
          break;
     case 3:  dis_hex_led(ad_sum%100/10,1); break;
     case 4:  dis_hex_led(ad_sum%10,2);time4_i=0; break;
    default:time4_i=0;break;
    
    }
}
void  timer4_task1()
{
  if((wendu_medium<=1000)&&(wendu_medium>=100))
  {
   switch(time4_i)
    {
      case 1:dis_hex_led(12,3);break;
      case 2:dis_hex_led(wendu_display[0],0); break;
     case 3:  dis_hex_led(wendu_display[1],1); break;
     case 4:  dis_hex_led(wendu_display[2],2);time4_i=0; break;
    default:time4_i=0;break;
    
    }
  }
}
void timer4_task2()
{
  if(time3_flag==0)
  {
   
     switch(time4_i)
    {
      case 1:dis_hex_flag3(4,0);break;
      case 2: dis_hex_flag3(5,1);break;
     case 3:  dis_hex_flag3(6,2); break;
     case 4:  dis_hex_flag3(7,3);time4_i=0; break;
    default:time4_i=0;break;
    
    }
  }
  else
  {
    if(time3_flag_i==0)
    {
       switch(time4_i)
    {
      case 1:dis_hex_flag3(0,0);break;
      case 2: dis_hex_flag3(1,1);break;
     case 3:  dis_hex_flag3(2,2); break;
     case 4:  dis_hex_flag3(3,3);time4_i=0; break;
    default:time4_i=0;break;
    
    }
   
    }
    else
    {
          
       switch(time4_i)
    {
      case 1:dis_hex_led(dis_flag3[0],0);break;
      case 2:dis_hex_led(dis_flag3[1],1); break;
     case 3:  dis_hex_led(dis_flag3[2],2); break;
     case 4:  dis_hex_led(dis_flag3[3],3);time4_i=0; break;
    default:time4_i=0;break;
    
    }
    }
  }
}
#pragma vector=TIM4_OVR_UIF_vector//0x19
__interrupt void TIM4_OVR_UIF_IRQHandler(void)//对应IAP的中断地址:0x8060
{
      ++time4_i;
      TIM4_SR=0x00;
   switch(flag)
   {
     case 0:timer4_task0();break;
     case 1:timer4_task0();break;
     case 2:timer4_task1();break;
     case 3:timer4_task2();break;
     default:flag=1;break;
   }
    
}
void TIM3_Init()
{
     TIM3_EGR=0x01; //手动产生更新事件,重新初始化计数器,并允许产生一个更新事件   
    //设置定时器初值 
    TIM3_CNTRH=0; //不能使用TIM3_CNTR直接设值,
    TIM3_CNTRL=0;  
    //设定自动重装寄存器值     
    //这里得注意不能使用TIM2_ARR的方式进行设值,TIM2是十六位的。 
    //如TIM2_ARR=0xFA,实际上是赋给高字节了,TIM2_ARRH=0xFA,而不是想象中的赋给低字节。 
    TIM3_ARRH=0xef; //31250 16MHz / 125 = 128000Hz  (1S) 
    TIM3_ARRL=0x42; //0x007d   意味着每产生一次中断时间为1MS 
    TIM3_PSCR=0x07; //分频128 
 
    TIM3_IER=0x01; //中断允许位使能 
    TIM3_CR1=0x01; //使能计时器 
}
#pragma vector=TIM3_OVR_UIF_vector
     __interrupt void TIM3_OVF_IRQHandler(void)
    {
      
         TIM3_SR1 = 0x00;
         ++time3_i;
         if(time3_flag)
         {
             if(time3_i>=time3_set*2)
            {
               PA_ODR&=~0x04;  
               start_it=1;
               time3_i=0;
             }
         }
         if(time3_i>64800) //最多工作九小时
         {
           time3_i=0;
           PA_ODR&=~0x04;
           start_it=1;
         }
       
    }
 

路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

返回顶部