久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4078|回復: 1
打印 上一主題 下一主題
收起左側

stm8溫度控制系統

[復制鏈接]
跳轉到指定樓層
樓主
ID:83710 發表于 2015-6-25 02:43 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式

師居然讓我們做個溫度控制系統,幸好這學期自己自學了32,所以覺得這還不是件困難的事。零零散散的寫了幾回,還么有在做好,各個模塊都調通了,所以只有收尾的工作可干了。
      廢話少說,先上程序。
//主函數
#include"iostm8s105k4.h"
#include"qudong.h"
#include"18b20.h"
main()
{

Init_UART2();
                hex_led();
                Init_Timer4();
                 clock_hsi_16mhz();//將系統的時鐘設置為16MHZ
                key_inint();//按鍵掃描程序,開始想用中斷控制,發現效果不太好,所以改用按鍵掃描查詢模式
                TIM2_Init(); //定時器2,產生2路PWM波,一路供繼電器控制熱地塊,另一路控制馬達攪拌水
           //      TIM3_Init();
                asm("rim");//開全局中斷
while (1)
{             if(flag==1)
                             {

                             }
                  key_scan();
                 set_pwm();  //改變占空比,來調節馬達和繼電器的開關速率
                wendu= DS18B20_ReadTemperature();//將18b20的讀數讀取。因為讀取一個數據需要750ms,所以反應速率還是超級慢的,之前用lm35,但發現就是個啃,用不了,也許我用錯了。

}
}
//驅動程序函數
#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};
unsigned char code_n[]={0xfb,0xf7,0xef,0xdf};
unsigned char time4_i;
unsigned long int ad_sum=500;
unsigned char set,flag;
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)  //設置4個共陰數碼管引腳定義
{
          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;            //由定時器4按照每2ms掃描一個數碼管
   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;  
}



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]]);
      UART2_sendchar(HexTable[dat_code[2]]);
}

void Init_Timer4(void)
{
    TIM4_CR1=0x01;//使能計數器
  //TIM4_IER=0x00;
    TIM4_IER=0x01;//更新中斷使能
    TIM4_EGR=0x01;
    TIM4_CNTR=255;//計數器值
    TIM4_ARR=255;//自動重裝的值
    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|=0x00;         
}

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<200)ad_sum=200;

}

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;break;
       case 2:flag=1; break;
       default:flag=1;break;
       }
         while((PF_IDR&0X10)!=0X10);
       }
  }
  if((PD_IDR&0x85)!=0x85)
                  {
                    delay(200);
                    if((PD_IDR&0x85)!=0x85)
                    {

                      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)
                      {
                  unsigned char sum_h,sum_l;
                sum_h=ad_sum/100;
                sum_l=ad_sum%100/10;  
                UART2_sendnum(sum_h);
                UART2_sendnum(sum_l);
                sum_l=ad_sum%10;
                 UART2_sendnum(sum_l);

                      }
                       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 = 0;
//啟動計數
TIM2_CR1 = TIM2_CR1 | 0x01;
}

void set_pwm(void)
{
  unsigned char i;
   for(i=0;i<255;i++)
   {
     TIM2_CCR1H = 1;
     TIM2_CCR1L = i;
     TIM2_CCR2H = 1;
     TIM2_CCR2L = i;
   //  delay(100);
   }
   // 下面的循環將占空比逐漸從50%遞減到0
   for(i=255;i>0;i--)
   {
      TIM2_CCR2H = 3;
     TIM2_CCR2L = i;
     TIM2_CCR1H = 3;
     TIM2_CCR1L = i;
     //delay(100);
   }
}

#pragma vector=TIM4_OVR_UIF_vector//0x19
__interrupt void TIM4_OVR_UIF_IRQHandler(void)//對應IAP的中斷地址:0x8060
{

      ++time4_i;
      TIM4_SR=0x00;
    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;

    }
      //return;
}
//溫度采集程序
#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值
float wendu;
unsigned char state;
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;
    }
}

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;
}


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=0x00; //31250 16MHz / 125 = 128000Hz  (1S)  
    TIM3_ARRL=0x0a; //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;

          PA_ODR^=0x04;

    }






分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:168091 發表于 2017-12-5 14:16 來自手機 | 只看該作者
樓主有電路原理圖嗎
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 中文字幕日本一区二区 | 久久久精品 | av天天看| 精品欧美一区二区中文字幕视频 | 亚洲成人一二三 | 中国黄色毛片视频 | 91精品久久久久久久 | 91天堂 | 精品国偷自产在线 | 国产精品一区二区在线 | 国产精品一区二区三区久久 | 欧美日韩精品 | 在线亚洲免费视频 | 久久久久久综合 | 农夫在线精品视频免费观看 | 亚洲黄色网址视频 | 国产精品精品久久久 | 国产成人高清 | 国内精品视频免费观看 | 黄片毛片免费观看 | 伊人一区 | 日韩在线播放一区 | 懂色av色香蕉一区二区蜜桃 | 国产精品久久久久aaaa九色 | 在线欧美 | 久久久久国色av免费观看性色 | 中文字幕在线精品 | av黄色片在线观看 | 在线欧美| 成人福利电影 | 亚洲国产精品一区二区三区 | 综合久久国产 | 欧美三区在线观看 | 久久国内精品 | 欧美一区二区大片 | 九九一级片 | 亚洲三区在线播放 | 欧美激情视频一区二区三区在线播放 | 99精品视频免费观看 | 夜夜草天天草 | 高清一区二区 |