圣源电子制作

标题: DS1621恒温控制-控制继电器制作-90S2313-热传感器DS1621-2七段LED显示-转载自外国网站 [打印本页]

作者: sydz    时间: 2011-12-4 15:56
标题: DS1621恒温控制-控制继电器制作-90S2313-热传感器DS1621-2七段LED显示-转载自外国网站
已建立了这个恒温控制电热元件。 为此,他使用了达拉斯热传感器DS1621可通过I2C接口读取。 他用于AVR的2313系列MCU读取传感器数据和2七段LED指示灯显示。
(, 下载次数: 42)
(, 下载次数: 38)

控制继电器切换点是容易 - 只需两个按钮UP和DOWN。 同时按下两个按钮允许设置的滞后和LED刷新占空比。 该设备的电源转换器内置INT准备被插入的任何地方,在你需要控制温度的好处电路和源代码可供下载。

程序:

  1. /*
  2.   Jesper Hansen <jesperh@telia.com>

  3.   This program is free software; you can redistribute it and/or
  4.   modify it under the terms of the GNU General Public License
  5.   as published by the Free Software Foundation; either version 2
  6.   of the License, or (at your option) any later version.

  7.   This program is distributed in the hope that it will be useful,
  8.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.   GNU General Public License for more details.

  11.   You should have received a copy of the GNU General Public License
  12.   along with this program; if not, write to the Free Software Foundation,
  13.   Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.





  14.           Thermostat regulator with Dallas DS1621.
  15.           ----------------------------------------       
  16.    
  17.           2000-11-24  



  18.         CPU: At90S2313

  19.         Switches are at PD2 and PD3, common ground

  20.         LED segments a-g are at PB0 - PB7, and
  21.         the anodes are at PD0 and PD1
  22.         The relay are at PD6, active high

  23.         Dallas DS1621 I2C bus are connected at
  24.         PD4 = SDA
  25.         PD5 = SCL

  26. */


  27. #include <io.h>
  28. #include <io.h>
  29. #include <progmem.h>
  30. #include <eeprom.h>
  31. #include <signal.h>
  32. #include <interrupt.h>

  33. #include "delay.h"
  34. #include "i2c.h"



  35. // PORT D
  36. #define KEYUP        PD2
  37. #define KEYDN        PD3

  38. #define        LED1        PD0
  39. #define LED2        PD1

  40. #define SDA                PD4
  41. #define SCL                PD5

  42. #define RELAY        PD6


  43. // PORT B

  44. #define SEG_a        0x01
  45. #define SEG_b        0x02
  46. #define SEG_c        0x04
  47. #define SEG_d        0x08
  48. #define SEG_e        0x10
  49. #define SEG_f        0x20
  50. #define SEG_g        0x40
  51. #define SEG_dot        0x80

  52. // MISC

  53. // eeprom storage positions
  54. #define EEPROM_SETTEMP                0x11
  55. #define EEPROM_HYSTERESIS        0x13
  56. #define EEPROM_DUTYVALUE        0x15


  57. #define BLINKCOUNT        80

  58. #define KEY_UP                0x01
  59. #define KEY_DOWN         0x02
  60. #define KEY_BOTH        (KEY_UP|KEY_DOWN)

  61. //
  62. // mode setting enums
  63. //
  64. typedef enum mode_e
  65. {
  66.         NORMAL,
  67.         SET_HYST,
  68.         SET_DUTY,
  69. } mode_e;


  70. mode_e next_mode[] = {SET_HYST, SET_DUTY, NORMAL};
  71. mode_e mode = NORMAL;

  72. unsigned char digits[] = {
  73.         (SEG_a|SEG_b|SEG_c|SEG_d|SEG_e|SEG_f),                        // 0
  74.         (SEG_b|SEG_c),                                                                        // 1
  75.         (SEG_a|SEG_b|SEG_d|SEG_e|SEG_g),                                // 2
  76.         (SEG_a|SEG_b|SEG_c|SEG_d|SEG_g),                                // 3
  77.         (SEG_b|SEG_c|SEG_c|SEG_f|SEG_g),                                // 4
  78.         (SEG_a|SEG_c|SEG_d|SEG_f|SEG_g),                                // 5
  79.         (SEG_a|SEG_c|SEG_d|SEG_e|SEG_f|SEG_g),                        // 6
  80.         (SEG_a|SEG_b|SEG_c),                                                        // 7
  81.         (SEG_a|SEG_b|SEG_c|SEG_d|SEG_e|SEG_f|SEG_g),        // 8
  82.         (SEG_a|SEG_b|SEG_c|SEG_d|SEG_f|SEG_g),                        // 9
  83.         (SEG_a),                                                                                // mode 1 indicator
  84.         (SEG_g),                                                                                // mode 2 indicator
  85.         (SEG_d),                                                                                // mode 3 indicator
  86. };



  87. unsigned char set_temp = 20;                // initial set temperature
  88. unsigned char set_flag = 0;                        // no settings in progress

  89. unsigned char hysteresis = 1;                // initial hysteresis
  90. unsigned char dutyvalue = 3;                // initial duty-cycle
  91. unsigned char relay_on = 0;                        // initial relay state



  92. // timer 0 handles multiplex and refresh of the displays

  93. #define TI0_L                (256-64)       

  94. volatile unsigned char flip = 0;
  95. volatile unsigned char dutycount = 0;
  96. volatile unsigned char temp = 20;
  97. unsigned char dotcount = BLINKCOUNT;

  98. SIGNAL(SIG_OVERFLOW0)        //timer 0 overflow
  99. {
  100.         unsigned char b = 0;

  101.         // reload timer
  102.         outp(TI0_L, TCNT0);

  103.         // both displays off

  104.         sbi(PORTD, LED1);
  105.         sbi(PORTD, LED2);

  106.         dutycount++;
  107.         if (dutycount == dutyvalue)
  108.         {
  109.                 dutycount = 0;

  110.                 switch (mode)
  111.                 {
  112.                         case NORMAL:
  113.                                 // see which one we need to update
  114.                                 if (flip)        // high ?
  115.                                         b = (temp / 10);
  116.                                 else
  117.                                         b = temp % 10;
  118.                                 break;

  119.                         case SET_HYST :
  120.                                 // see which one we need to update
  121.                                 if (flip)        // high ?
  122.                                         b = 10;        // mode indicator
  123.                                 else
  124.                                         b = hysteresis;
  125.                                 break;

  126.                         case SET_DUTY :
  127.                                 // see which one we need to update
  128.                                 if (flip)        // high ?
  129.                                         b = 11;        // mode indicator
  130.                                 else
  131.                                         b = dutyvalue;
  132.                                 break;
  133.                                
  134.                 }

  135.                 // set digit data on port
  136.                 outp(digits[b], PORTB);

  137.                 if (flip)        // left LED
  138.                 {
  139.                         if (dotcount < BLINKCOUNT/2)
  140.                                 sbi(PORTB,7);
  141.                                
  142.                         if (dotcount)
  143.                                 dotcount--;
  144.                         else
  145.                                 dotcount = BLINKCOUNT;       
  146.                
  147.                         cbi(PORTD, LED1);
  148.                 }
  149.                 else
  150.                 {
  151.                         if (relay_on)
  152.                                 sbi(PORTB,7);
  153.                        
  154.                         cbi(PORTD, LED2);
  155.                 }
  156.                
  157.                 flip = !flip;
  158.         }
  159. }




  160. void start_timer_0(void)
  161. {
  162.         //setup timer 0

  163.         outp(0x03, TCCR0);                // prescaler /64  tPeriod = 10.667 uS
  164.         sbi(TIMSK, TOIE0);                 // enable timer1 interrupt
  165.         outp(TI0_L,TCNT0);                // load timer  

  166.         sei();                                        // start timer by enabling interrupts
  167. }



  168. int getkey(void)
  169. {
  170.         int ret_val = 0;

  171.         // if none of the keys are down,
  172.         // return zero
  173.         if (bit_is_set(PIND, KEYUP) && bit_is_set(PIND, KEYDN) )
  174.                 return 0;

  175.         // debounce 80 mS
  176.         delay(40000);       
  177.         delay(40000);       
  178.                
  179.         // now read again and return status
  180.         if (bit_is_clear(PIND, KEYUP))
  181.                 ret_val |= KEY_UP;

  182.         if (bit_is_clear(PIND, KEYDN))
  183.                 ret_val |= KEY_DOWN;

  184.         return ret_val;
  185. }                       



  186. int main(void)
  187. {
  188.         unsigned char i2cdata[8];

  189.         // set port B as all outputs
  190.         // and initially set all pins HI

  191.         outp(0xff,PORTB);
  192.         outp(0xff,DDRB);


  193.         // set common LED pins as output
  194.         // and initially set them HI
  195.         // set RELAY pin as output, and initially set it LO (off)
  196.         // also activate pullups on keyboard inputs
  197.         outp((1<<LED1)|(1<<LED2)|(1<<RELAY),DDRD);
  198.         outp((1<<LED1)|(1<<LED2)|(1<<KEYUP)|(1<<KEYDN),PORTD);

  199.         i2c_init();

  200.         // restore data from eeprom
  201.         // and make sure values are sane
  202.         set_temp = eeprom_rb(EEPROM_SETTEMP);
  203.         if (set_temp > 40 || set_temp < 1)
  204.                 set_temp = 20;

  205.         hysteresis = eeprom_rb(EEPROM_HYSTERESIS);
  206.         if (hysteresis > 5)
  207.                 hysteresis = 1;

  208.         dutyvalue = eeprom_rb(EEPROM_DUTYVALUE);
  209.         if (dutyvalue > 10 || dutyvalue < 1)
  210.                 dutyvalue = 3;


  211.         // Setup DS1621

  212.         // Access Config Command
  213.         // Set Continuous transfer, polarity active lo
  214.         i2c_send(0x90, 0xAC, 1, "\0x00");
  215.         delay(1000);

  216.         // Start conversion
  217.         i2c_send(0x90, 0xEE, 0, 0);


  218.         // start the timer
  219.         start_timer_0();



  220.         while (1)
  221.         {
  222.                 // check switch status
  223.                
  224.                 if (temp >= set_temp+hysteresis)
  225.                 {
  226.                         relay_on = 0;
  227.                         cbi(PORTD, RELAY);                                // relay OFF
  228.                 }
  229.                        
  230.                 if (temp <= set_temp-hysteresis)
  231.                 {
  232.                         relay_on = 1;
  233.                         sbi(PORTD, RELAY);                                // relay ON
  234.                 }       
  235.                        
  236.                        
  237.                 // check keys                       
  238.                        
  239.                 switch (getkey())                       
  240.                 {
  241.                         case KEY_UP :
  242.                                 if (set_flag)                // don't change set_temp on first press
  243.                                 {
  244.                                         switch (mode)
  245.                                         {
  246.                                                 case NORMAL :
  247.                                                         set_temp++;                // increment set temperature
  248.                                                         break;
  249.                                                 case SET_HYST :                                                       
  250.                                                         hysteresis++;        // increment hysteresis
  251.                                                         break;
  252.                                                 case SET_DUTY :
  253.                                                         dutyvalue++;        // increment duty value
  254.                                                         break;
  255.                                         }
  256.                                 }       
  257.                                 set_flag = 50;                // set timeout flag for display
  258.                                 break;

  259.                         case KEY_DOWN :
  260.                                 if (set_flag)                // don't change set_temp on first press
  261.                                 {
  262.                                         switch (mode)
  263.                                         {
  264.                                                 case NORMAL :
  265.                                                         set_temp--;                // decrement set temperature
  266.                                                         break;
  267.                                                 case SET_HYST :                                                       
  268.                                                         hysteresis--;        // decrement hysteresis
  269.                                                         break;
  270.                                                 case SET_DUTY :
  271.                                                         dutyvalue--;        // decrement duty value
  272.                                                         break;
  273.                                         }

  274.                                 }       
  275.                                 set_flag = 50;                // set timeout flag for display
  276.                                 break;
  277.                                
  278.                         case KEY_BOTH :       
  279.                                 mode = next_mode[mode];
  280.                                 set_flag = 50;
  281.                                 break;
  282.                        
  283.                 }



  284.                 delay(10000);
  285.                        
  286.                 if (set_flag)
  287.                 {
  288.                         set_flag--;
  289.                         if (set_flag == 0)
  290.                         {
  291.                                 switch (mode)
  292.                                 {
  293.                                         case NORMAL:
  294.                                                 eeprom_wb(EEPROM_SETTEMP,set_temp);
  295.                                                 break;
  296.                                         case SET_HYST :
  297.                                                 eeprom_wb(EEPROM_HYSTERESIS,hysteresis);
  298.                                                 break;
  299.                                         case SET_DUTY :
  300.                                                 eeprom_wb(EEPROM_DUTYVALUE,dutyvalue);
  301.                                                 break;
  302.                                 }                                               
  303.                                        
  304.                                 mode = NORMAL;
  305.                         }
  306.                         temp = set_temp;
  307.                 }
  308.                 else
  309.                 {
  310.                         // read temp
  311.                         i2c_receive(0x90,0xAA, 2, i2cdata);
  312.                         temp = *i2cdata;
  313.                 }
  314.        
  315.        
  316.         }




  317. }


复制代码


(, 下载次数: 42)
下载:
(, 下载次数: 8)
(, 下载次数: 8)




欢迎光临 圣源电子制作 (https://bbs.syyyd.com/) Powered by Discuz! X3.4