|
| |||||||
|
Опубликовано 2013-03-21 10:56:23 автором Ruslan Управление микроклиматом в инкубаторе на AVRДело было так: решил мой кум заняться разведением с/х птицы, и пришел за советом ко мне, что и как бы все это организовать, автоматизировать весь процесс. Так как кум у меня отличный строитель и не очень разбирается в цифровой электронике и программировании, я взялся сделать ему для инкубатора электронику, которая бы следила за температурой в рабочей среде, переворачивала яйца несколько раз в день, охлаждала рабочую область инкубатора и считала время с начала выседки. И еще нужно было всю информацию выводить на семисегментный led-индикатор.Схема всего устройства .
Устройство можно условно разделить на три блока.
Дальше нужно было разработать программу, чтобы управлять всем этим добром.
#include <mega8.h>
#include <delay.h>
#asm
.equ __w1_port=0x12;
.equ __w1_bit=5
#endasm
//#include <1wire.h>
#include <ds18b20.h>
struct Ttime
{
unsigned second:5;
unsigned minute:6;
unsigned hour:6;
unsigned day:5;
} time={0,0,0,0} ;
unsigned char nomer[]={0b01111101,
0b00000101,0b01110011,0b01010111,0b00001111,0b01011110,
0b01111110,0b01000101,0b01111111,0b01011111};
unsigned char segment[]={0b10011110,0b10011101,0b10011011,};
unsigned char i[3]={1,4,5},z=0;
unsigned char g=0,stan=1;
unsigned int showled[5];
unsigned char napramok=0;
unsigned char devices; //переменная в которой количество присоеденённых датчиков
unsigned int temp;
unsigned char t_drob,t1,t2,t_int,t_min=378,t_max=379;
void move_motor( unsigned int time,unsigned char shvid)
{
int i;
if (napramok)
{
TCCR1A=0x81;
OCR1AL=shvid;
}
else
{
OCR1BL=shvid;
TCCR1A=0x21;
};
for ( i=100; i<=time; i+=100)
{
delay_ms(100);
if (PIND.7==0) { TCCR1A=0x81; napramok=1; delay_ms(150); break;}
if (PIND.4==0) { TCCR1A=0x21; napramok=0; delay_ms(150); break; }
}
TCCR1A=0x01;
}
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
w1_init();
w1_write(0xCC);
w1_write(0xBE);
t1=w1_read();
t2=w1_read();
w1_init();
w1_write(0xCC);
w1_write(0x44);
if (++time.second==30)
{
time.second=0;
if ( (showled[2]=++time.minute)==60)
{
time.minute=0;
move_motor(2600,160);
if ( (showled[3]=++time.hour) ==24 )
{
time.hour=0;
showled[4]= ++time.day;
}
}
}
}
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
PORTC=nomer[ i [z] ];
PORTD=segment[z] | (nomer[ i [z] ] & 0b01000000 ) ;
if (++z==3) z=g;
}
void out(unsigned int k)
{
if (k<1000)
{ i[2]=k%10;
i[1]=(k/10)%10;
if ( i[0]=k/100 ){ TCCR0=0x03 ; g=0; } else { g=1+ !( i[1]); TCCR0=3+g;}
}
}
void main(void)
{
// Port B initialization
PORTB=0x00;
DDRB=0b00000111;
PORTB.0=1;
// Port C initialization
DDRC=0xff;
PORTC=0x00;
PORTD=0b10011000;
DDRD=0b01000111;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 0,977 kHz
TCCR0=0x03;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x01;
TCCR1B=0x0B;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x64;
OCR1BH=0x00;
OCR1BL=0x64;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x08;
TCCR2=0x06;
TCNT2=0x00;
OCR2=0x00;
// INT1: On
// INT1 Mode: Low level
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x41;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
ds18b20_init(0,20,40,DS18B20_11BIT_RES);
#asm("sei")
while(1){
if (PIND.7==0) {napramok=1; move_motor(150,100); } //
if (PIND.4==0) {napramok=0; move_motor(150,100); }
delay_ms(150); // дребезг контактов
t_int= (t1>>4) | ((t2 & 7)<<4);
t_drob=t1&15;
t_drob= (t_drob<<1) + (t_drob<<3);
t_drob=t_drob>>4;
showled[1]= ( (t_int<<1) + (t_int<<3) ) +t_drob; //получаем значение температуры
if (showled[1]<=374) PORTB.0=0;
else if (showled[1]>=376) PORTB.0=1;
if (PIND.3==0)
{
if ( (++stan==5) ) { TIMSK^=0x01; PORTC^=PORTC; PORTD&=~(1<<6); stan=0; }
else TIMSK=0x41;
}
if (stan) out( showled[stan] ); // выводим нужную величину из масива
};
}
Работу устройства коротко можно описать так: Микроконтроллер дает команду на включение датчика температуры, затем - команду на измерение температуры. Датчик измеряет температуру внутри прибора и записывает ее в свой внутренний регистр.
Измерение температуры внутри инкубатора
Комментарии - (5)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |
|||||||