
- •Разработка микропроцессорного термостата на базе элементов пельтье Дипломный проект
- •Новосибирск
- •1. Алгоритм работы программы аппаратной части устройства 26
- •Введение
- •Измерение и стабилизация температуры внутри замкнутого объема
- •Измерение температуры
- •Стабилизация температуры
- •Датчики температуры
- •Постановка задачи
- •Выбор датчика температуры на основе p-n перехода полупроводникового диода и схемы его подключения
- •Выбор типа термоэлектрического модуля (тэм)
- •Решение задачи
- •Структурная схема термостата
- •Принципиальная электрическая схема термостата
- •Принципиальная электрическая схема контроллера термостата
- •Принципиальная электрическая схема силового драйвера модуля Пельтье
- •Список использованных источников
- •Блок – схема алгоритма программы аппаратной части устройства
- •Описание работы блоков программы динамического режима
- •Описание работы блоков программы статического режима
- •Описание работы блоков обработчика прерывания от usart rx Complete (Сборка принятой команды)
- •Описание работы блоков программы обработчика прерывания от timer0 (Выполнение принятой команды)
- •Описание работы блоков программы обработчика прерывания от timer1 (Формирование управляющих сигналов для драйвера Пельтье)
- •Описание работы блоков программы обработчика прерывания от timer2 (Формирование точной временной задержки)
- •Описание работы термостата.
- •Внешний вид электронных блоков
- •Листинг программы аппаратной части устройства
Внешний вид электронных блоков
Рис. Б.1. Внешний вид платы контроллера термостата
Рис. Б.2. Внешний вид силового драйвера модуля Пельтье
Рис. Б.3. Внешний вид подключенных модулей
ПРИЛОЖЕНИЕ Г
Листинг программы аппаратной части устройства
#defineF_CPU11059200UL
#include<avr/io.h>
#include<avr/interrupt.h>
#include<stdio.h>
#include<string.h>
/***********GlobalVariables**************/
volatileunsignedcharcommand[50];//массивдлявычесленнойкомманды
volatileunsignedcharbuffer[50];//временныйбуфердлявхоящихданных
volatileunsignedcharnum=1;//переменная счетчик входящий байт
volatileunsignedcharcom_complete=1;//флагвыполенннойкомманды
volatileunsignedcharbytesym=0;//суммабайтвкомманде
volatileunsignedinttemperature=0;
volatileuint32_tdt=0;//разность температур
volatileuint32_tvh=0;
volatileuint32_tvhb=0;
volatileuint32_tpt=0;
volatileuint32_tp=0;
volatileuint8_titerm=0;
volatileuint8_ti=0;
volatileunsignedcharuyt=0;
volatileuint32_tcurrenttemp=0;
volatileuint32_tstemp=2500;
volatileuint32_ttempmax=0;//температурныймаксимум
volatileuint32_ttempmin=0;//температурныйминимум
volatileunsignedcharmode=0;//режим работы: 0 - поддержание постоянной температуры, 1 - динамическое изменение температуры
volatileuint32_tperiodtime=0;//время 1 периода, 1 периодом считается постепенное повышение от температурного минимума до максимума и от максимума до минимума
volatileuint32_tperiods=0;//количество периодов
volatileunsignedcharPRGSTART=0;
volatileunsignedchartimeup=0;
/***********FunctionPrototypes***********/
VoidUSART_Init(unsignedintbaud);
VoidUSART_Transmit(constchardata);
VoidUSART_Str(constchar*stroka);
VoidUSART_data(unsignedchardata);
VoidTIMER0_Init(void);
VoidTIMER1_Init(void);
VoidTIMER2_AS_Init(void);
unsignedintanalogread(unsignedcharchannel);
/************interruptVectors************/
ISR(USART_RXC_vect)
{
unsignedcharbyte=UDR;
buffer[num]=byte;
num++;
if((buffer[num-2]==0x0D)&&(buffer[num-1]==0x0A))//если пришли символы перевода строки и возврата коретки, то
{
for(i=0;i<num-3;i++)
{
command[i]=buffer[i+1];//запоминаемпринятуюкоманду
}
num=1;
for(i=0;i<49;i++)
{
buffer[i]=0;
}
com_complete=0;//ставим статус комманды как невыполненный
TIMSK|=(1<<TOIE0);
}
if(num>48)
{
num=1;
for(i=0;i<50;i++)
{
buffer[i]=0;
}
}
}
ISR(TIMER0_OVF_vect)
{
if((command[0]=='S')||(command[0]=='R')||(command[0]=='H')||(command[0]=='h'))
{
if((command[0]=='S')&&(command[1]=='E')&&(command[2]=='T'))
{
/****************************************************************************************/
if((command[3]=='T')&&(command[4]=='E')&&(command[5]=='M')&&(command[6]=='P'))
{
if((command[7]=='M')&&(command[8]=='A')&&(command[9]=='X'))//максимальнаятемпература
{
if(command[10]=='=')
{
uint8_tpcount=11;
bytesym=0;
for(pcount=11;!(command[pcount]==0);pcount++)
{
bytesym++;
}
switch(bytesym)
{
case4:tempmax=((command[11]-48)*(uint32_t)1000)+((command[12]-48)*(uint32_t)100)+((command[13]-48)*(uint32_t)10)+((command[14]-48));break;
case3:tempmax=((command[11]-48)*(uint32_t)100)+((command[12]-48)*(uint32_t)10)+((command[13]-48));break;
case2:tempmax=((command[11]-48)*(uint32_t)10)+((command[12]-48));break;
case1:tempmax=(command[11]-48);break;
default:break;
}
bytesym=0;
}
}
/****************************************************************************************/
if((command[7]=='M')&&(command[8]=='I')&&(command[9]=='N'))//минимальнаятемпература
{
if(command[10]=='=')
{
uint8_tpcount=11;
bytesym=0;
for(pcount=11;!(command[pcount]==0);pcount++)
{
bytesym++;
}
switch(bytesym)
{
case4:tempmin=((command[11]-48)*(uint32_t)1000)+((command[12]-48)*(uint32_t)100)+((command[13]-48)*(uint32_t)10)+((command[14]-48));break;
case3:tempmin=((command[11]-48)*(uint32_t)100)+((command[12]-48)*(uint32_t)10)+((command[13]-48));break;
case2:tempmin=((command[11]-48)*(uint32_t)10)+((command[12]-48));break;
case1:tempmin=(command[11]-48);break;
default:break;
}
bytesym=0;
}
}
/****************************************************************************************/
}
/*****************************************************************************************/
if((command[3]=='M')&&(command[4]=='O')&&(command[5]=='D')&&(command[6]=='E'))
{
if(command[7]=='=')
{
uint8_tpcount=8;
bytesym=0;
for(pcount=8;!(command[pcount]==0);pcount++)
{
bytesym++;
}
if(bytesym==1){mode=(command[8]-48);}
bytesym=0;
}
}
/*****************************************************************************************/
if((command[3]=='P')&&(command[4]=='T')&&(command[5]=='I')&&(command[6]=='M')&&(command[7]=='E'))
{
if(command[8]=='=')
{
uint8_tpcount=9;
bytesym=0;
for(pcount=9;!(command[pcount]==0);pcount++)
{
bytesym++;
}
switch(bytesym)
{
case6:periodtime=(uint32_t)128*(((command[9]-48)*(uint32_t)100000)+((command[10]-48)*(uint32_t)10000)+((command[11]-48)*(uint32_t)1000)+((command[12]-48)*(uint32_t)100)+((command[13]-48)*(uint32_t)10)+((command[14]-48)));break;
case5:periodtime=(uint32_t)128*(((command[9]-48)*(uint32_t)10000)+((command[10]-48)*(uint32_t)1000)+((command[11]-48)*(uint32_t)100)+((command[12]-48)*(uint32_t)10)+((command[13]-48)));break;
case4:periodtime=(uint32_t)128*(((command[9]-48)*(uint32_t)1000)+((command[10]-48)*(uint32_t)100)+((command[11]-48)*(uint32_t)10)+((command[12]-48)));break;
case3:periodtime=(uint32_t)128*(((command[9]-48)*(uint32_t)100)+((command[10]-48)*(uint32_t)10)+((command[11]-48)));break;
case2:periodtime=(uint32_t)128*(((command[9]-48)*(uint32_t)10)+((command[10]-48)));break;
case1:periodtime=(uint32_t)128*((command[9]-48));break;
default:break;
}
bytesym=0;
}
}
/*****************************************************************************************/
if((command[3]=='P')&&(command[4]=='N')&&(command[5]=='U')&&(command[6]=='M')&&(command[7]=='B'))
{
if(command[8]=='=')
{
uint8_tpcount=9;
bytesym=0;
for(pcount=9;!(command[pcount]==0);pcount++)
{
bytesym++;
}
switch(bytesym)
{
case4:periods=((command[9]-48)*(uint32_t)1000)+((command[10]-48)*(uint32_t)100)+((command[11]-48)*(uint32_t)10)+((command[12]-48));break;
case3:periods=((command[9]-48)*(uint32_t)100)+((command[10]-48)*(uint32_t)10)+((command[11]-48));break;
case2:periods=((command[9]-48)*(uint32_t)10)+((command[10]-48));break;
case1:periods=(command[9]-48);break;
default:break;
}
bytesym=0;
}
}
}
/****************************************Флагстартапрограммы***************************************/
if((command[0]=='S')&&(command[1]=='T')&&(command[2]=='A')&&(command[3]=='R')&&(command[4]=='T'))
{
PRGSTART=1;
}
/*****************************************Флагостановкипрограммы***********************************/
if((command[0]=='S')&&(command[1]=='T')&&(command[2]=='O')&&(command[3]=='P'))
{
PRGSTART=0;
}
/**********************************************************************************************/
/*******************************Запросыначтение *********************************************/
if((command[0]=='R')&&(command[1]=='E')&&(command[2]=='A')&&(command[3]=='D'))
{
if((command[4]=='T')&&(command[5]=='E')&&(command[6]=='M')&&(command[7]=='P')&&(command[8]=='M')&&(command[9]=='A')&&(command[10]=='X'))
{
charstr[15];
sprintf(str, "TEMPMAX=%d",(int)tempmax);
USART_Str(str);
USART_Transmit(0x0D);
USART_Transmit(0x0A);
}
/*******************************************/
if((command[4]=='T')&&(command[5]=='E')&&(command[6]=='M')&&(command[7]=='P')&&(command[8]=='M')&&(command[9]=='I')&&(command[10]=='N'))
{
charstr[15];
sprintf(str, "TEMPMIN=%d",(int)tempmin);
USART_Str(str);
USART_Transmit(0x0D);
USART_Transmit(0x0A);
}
/*******************************************/
if((command[4]=='P')&&(command[5]=='R')&&(command[6]=='G')&&(command[7]=='S')&&(command[8]=='T')&&(command[9]=='A')&&(command[10]=='T'))
{
charstr[15];
sprintf(str, "PRGSTAT=%d",(int)PRGSTART);
USART_Str(str);
USART_Transmit(0x0D);
USART_Transmit(0x0A);
}
/*******************************************/
if((command[4]=='P')&&(command[5]=='N')&&(command[6]=='U')&&(command[7]=='M')&&(command[8]=='B'))
{
charstr[15];
sprintf(str, "PNUMB=%d",(int)periods);
USART_Str(str);
USART_Transmit(0x0D);
USART_Transmit(0x0A);
}
/*******************************************/
if((command[4]=='M')&&(command[5]=='O')&&(command[6]=='D')&&(command[7]=='E'))
{
charstr[15];
sprintf(str, "MODE=%d",(int)mode);
USART_Str(str);
USART_Transmit(0x0D);
USART_Transmit(0x0A);
}
/*******************************************/
if((command[4]=='P')&&(command[5]=='T')&&(command[6]=='I')&&(command[7]=='M')&&(command[8]=='E'))
{
charstr[15];
sprintf(str, "PTIME=%ld",(longint)(periodtime/(uint32_t)128));
USART_Str(str);
USART_Transmit(0x0D);
USART_Transmit(0x0A);
}
/*******************************************/
if((command[4]=='C')&&(command[5]=='T')&&(command[6]=='E')&&(command[7]=='M')&&(command[8]=='P'))
{
charstr[15];
sprintf(str, "CTEMP=%ld",(longint)currenttemp);
USART_Str(str);
USART_Transmit(0x0D);
USART_Transmit(0x0A);
}
/*******************************************/
if((command[4]=='A')&&(command[5]=='D')&&(command[6]=='C'))
{
charstr[15];
//unsignedinttemperature = (int)(((uint32_t)analogread(0)*(uint32_t)4889)/(uint32_t)1000);
sprintf(str, "ADC=%d",temperature);
USART_Str(str);
USART_Transmit(0x0D);
USART_Transmit(0x0A);
}
/*******************************************/
}
if(((command[0]=='H')&&(command[1]=='E')&&(command[2]=='L')&&(command[3]=='P'))
||((command[0]=='h')&&(command[1]=='e')&&(command[2]=='l')&&(command[3]=='p')))
{
USART_Str("Commands:");
USART_Transmit(0x0D);
USART_Transmit(0x0A);
USART_Str("SETTEMPMAX - setthemaximumtemperature");
USART_Transmit(0x0D);
USART_Transmit(0x0A);
USART_Str("SETTEMPMIN - settheminimumtemperature");
USART_Transmit(0x0D);
USART_Transmit(0x0A);
USART_Str("SETPTIME - settheperiodtime (seconds)");
USART_Transmit(0x0D);
USART_Transmit(0x0A);
USART_Str("SETPNUMB - setnumberofperiods");
USART_Transmit(0x0D);
USART_Transmit(0x0A);
USART_Str("SETMODE - setmode, 0 - static, 1 - dynamic");
USART_Transmit(0x0D);
USART_Transmit(0x0A);
USART_Str("START - starttheprogram");
USART_Transmit(0x0D);
USART_Transmit(0x0A);
USART_Str("STOP - stoptheprogram");
USART_Transmit(0x0D);
USART_Transmit(0x0A);
USART_Str("READTEMPMAX - showthemaximumtemperature");
USART_Transmit(0x0D);
USART_Transmit(0x0A);
USART_Str("READTEMPMIN - showtheminimumtemperature");
USART_Transmit(0x0D);
USART_Transmit(0x0A);
USART_Str("READPRGSTAT - showtheprogramstatus, 1 - programrunning, 0 - stopped");
USART_Transmit(0x0D);
USART_Transmit(0x0A);
USART_Str("READPNUMB - showthenumberofperiods");
USART_Transmit(0x0D);
USART_Transmit(0x0A);
USART_Str("READMODE - showthecurrentmode, 1 - dynamic, 0 - static");
USART_Transmit(0x0D);
USART_Transmit(0x0A);
USART_Str("READPTIME - showthesettimeperiod");
USART_Transmit(0x0D);
USART_Transmit(0x0A);
USART_Str("READCTEMP - showthecurrenttemperature");
USART_Transmit(0x0D);
USART_Transmit(0x0A);
}
/*************************************************************************************************/
}
com_complete=1;
for(iterm=0;iterm<49;iterm++)
{
command[iterm]=0;
}
//}
TIMSK&=~(1<<TOIE0);
}
ISR(TIMER1_OVF_vect)
{
DDRB=255;
DDRA=0;
temperature=(int)(((uint32_t)analogread(0)*(uint32_t)4889)/(uint32_t)1000);//4889=(50/1024)*100000
if(currenttemp>temperature)PORTB=1;
if(currenttemp<temperature)PORTB=2;
}
ISR(TIMER2_OVF_vect)
{
timeup=1;
}
intmain(void)
{
PORTB=255;
DDRB=255;
PORTA=0;
DDRA=0;
PORTC=0;
DDRC=0;
USART_Init(5);
TIMER0_Init();
TIMER2_AS_Init();
TIMER1_Init();
asm("sei");
tempmax=1600;//nnxx; nn - целые числа градуса, xx - сотые, например 1045 это 10.45 градусов цельсия
tempmin=1000;//10.00 градусов
periodtime=((uint32_t)60)*((uint32_t)128);//без приведения типов он пишет в переменную "попугаи"
periods=4;
currenttemp=tempmin;
PRGSTART=0;
while(1)
{
if(PRGSTART==1)//если пришла комманда старта программы
{
if(mode==1)
{
currenttemp=tempmin;
dt=(tempmax-tempmin);//разностьтемператур
vh=((uint32_t)(periodtime/2))/dt;//заходить и изменять тек.температуру каждые vh пропущенных циклов
vhb=0;
p=0;
for(p=periods;p>0;p--)
{
vhb=0;
for(pt=periodtime/2;pt>0;pt--)
{
vhb++;
if(vhb==vh)
{
vhb=0;
currenttemp++;
}
while(timeup==0);
timeup=0;
}
pt=0;
vhb=0;
for(pt=periodtime/2;pt>0;pt--)
{
vhb++;
if(vhb==vh)
{
vhb=0;
currenttemp--;
}
while(timeup==0);
timeup=0;
}
pt=0;
}
USART_Str("Programstopped");
USART_Transmit(0x0D);
USART_Transmit(0x0A);
PRGSTART=0;
}
if(mode==0)
{
for(pt=periodtime;pt>0;pt--)
{
currenttemp=stemp;
while(timeup==0);
timeup=0;
}
pt=0;
USART_Str("Programstopped");
USART_Transmit(0x0D);
USART_Transmit(0x0A);
PRGSTART=0;
}
}
}
}
VoidUSART_Init(unsignedintbaud)
{
UBRRH=(unsignedchar)(baud>>8);
UBRRL=(unsignedchar)(baud);
UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
UCSRC=(1<<URSEL)|(3<<UCSZ0);
}
voidUSART_Transmit(constchardata)
{
while(!(UCSRA&(1<<UDRE)));
UDR=data;
}
voidUSART_Str(constchar*stroka)
{
unsignedchari=0;
while(!(stroka[i]=='\0'))
{
USART_Transmit(stroka[i]);
i++;
}
}
voidTIMER0_Init(void)
{
TCCR0=(1<<CS01);
}
voidTIMER1_Init(void)
{
TIMSK|=(1<<TOIE1);
TCCR1A=0;
TCCR1B=(1<<CS01);
}
voidTIMER2_AS_Init(void)
{
ASSR=(1<<AS2);
TIMSK|=(1<<TOIE2);
TCCR2=(1<<CS20);
}
unsignedintanalogread(unsignedcharchannel)
{
unsignedintadc_val;
ADMUX=0x40;
ADMUX|=channel;
ADCSRA=0xC6;
while((ADCSRA&(1<<ADSC)));
adc_val=ADCL;
adc_val+=(ADCH*256);
return(adc_val);
}
Void USART_data (unsigned char data)
{
while(!(UCSRA&(1<<UDRE)));
UDR=data;
}