Показать сообщение отдельно
Старый 10.05.2009, 18:48   #157   
Форумец
 
Сообщений: 1,532
Регистрация: 19.02.2009
Возраст: 54
Записей в дневнике: 1

petrd вне форума Не в сети
Вот переделал. Теперь если после входа в режим уставки примерно в течении 30 сек. не будет нажатий кнопок "Выше" или "Ниже", то программа выйдет из режима уставки. Ну и для сравнения кодов убрал сотые, на их месте теперь будет пробел. Процедуру обработки нажатия кнопок вынес в отдельную подпрограмму и появилась подпрограмма обработки прерываний от TMR0 (таймер нужен для отсчета 30 сек.). Проверил - в железе вроде работает как надо, что не так - говорите.
Код:
#define Up          Button(&PORTA, 0,10,0)
#define Dn          Button(&PORTA, 1,10,0)
#define SetBut      Button(&PORTB, 7,10,0)
#define Relay_On()  PORTA=8
#define Relay_Off() PORTA=0
const unsigned short TEMP_RESOLUTION = 12;
unsigned short MaxTemp, old_MaxTemp, state, MinTemp, old_MinTemp;
char *text = "000.0", *maxT = "000", *minT="000";
unsigned temp, counter;
/*************  подпрограмма обработки прерываний **************************/
void interrupt(){
if(INTCON.T0IF){
counter++;
INTCON.T0IF=0;
}
}// interrupt
/*************подпрограмма обработки нажатия кнопок**************************/
void Control_Button(){
if(SetBut){         //нажимаем кнопку на RB7 (вход в режим уставки)
while(SetBut){}
counter=0;
INTCON.GIE=1;       // включили механизм прерываний
do{                           // изменение мин. температуры
Lcd_Out(2,5,"   ");
delay_ms(300);
Lcd_Out(2,5,minT);
delay_ms(300);
if (Up){                     // нажимаем кнопку на RA0 ("выше")
counter=0;
MinTemp++;
if (MinTemp>=MaxTemp)
MinTemp=MaxTemp;
}
if (Dn){                     // нажимаем кнопку на RA1 ("ниже")
counter=0;
MinTemp-- ;
if (MinTemp==255)
MinTemp=0;
}
minT[0]=MinTemp/100+48;
minT[1]=(MinTemp/10)%10+48;
minT[2]=MinTemp%10+48;
Lcd_Out(2,5,minT);
if (counter>450)
return;
}
while(!SetBut);
while(SetBut){}
do{                         // изменение макс. температуры
Lcd_Out(2,13,"   ");
delay_ms(300);
Lcd_Out(2,13,maxT);
delay_ms(300);
if (Up){                   // нажимаем кнопку на RA0 ("выше")
counter=0;
MaxTemp++;
if (MaxTemp>125)
MaxTemp=125;
}
if (Dn){                   // нажимаем кнопку на RA1 ("ниже")
counter=0;
MaxTemp-- ;
if (MaxTemp<MinTemp)
MaxTemp=MinTemp;
}
maxT[0]=MaxTemp/100+48;
maxT[1]=(MaxTemp/10)%10+48;
maxT[2]=MaxTemp%10+48;
Lcd_Out(2,13,maxT);
if (counter>450)
return;
}
while(!SetBut);
while(SetBut){}     // выход из режима уставки
INTCON.GIE=0;       // выключили механизм прерываний
}
}
/* подпрограмма форматирования, вывода на ЖКИ температуры и уставок, включение-выключение*/
void Display_Temperature(unsigned int temp2write) {
const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
char temp_whole;
unsigned int temp_fraction;
if (temp2write & 0x8000) {    // преобразование отрицательной температуры
text[0] = '-';
temp2write = ~temp2write + 1;
}
temp_whole = temp2write >> RES_SHIFT ;   // извлечение целой части
// преобразование целой части температуры в символы
text[0] = temp_whole/100  + 48;                // извлечение сотен
text[1] = (temp_whole/10)%10 + 48;             // извлечение десятков
text[2] = temp_whole%10     + 48;              // извлечение единиц
// извлечение и преобразование дробной части
temp_fraction  = temp2write << (4-RES_SHIFT);
temp_fraction &= 0x000F;
temp_fraction *= 625;
// преобразование дробной части в символы
text[4] =  temp_fraction/1000    + 48;         // извлечение тысячных
//text[5] = (temp_fraction/100)%10 + 48;         // извлечение сотых
//text[6] = (temp_fraction/10)%10  + 48;       // извлечение десятых
//text[7] =  temp_fraction%10      + 48;       // извлечение единиц
Lcd_Out(1,7,text);                             // вывод температуры на ЖКИ
// код стейт-машинки
switch(state){
case 0: {
if(temp_whole<MaxTemp){
Relay_On();
Lcd_Chr(1,16,'1');
}
else {
Relay_Off();
Lcd_Chr(1,16,'0');
state=1;
}
}; break;
case 1: {
if(temp_whole<MinTemp){
Relay_On();
Lcd_Chr(1,16,'1');
state=0;
}
else {
Relay_Off();
Lcd_Chr(1,16,'0');
}
}; break;
} // окончание стейт-машинки
}//~
void main() {
CMCON = 7;                               // Все выводы цифровые входы-выходы
TRISA=0b11110111;                        // все выводы PORTA на вход, RA3 - выход
OPTION_REG = 0x87;  // настройка TMR0, прерывания будут каждые 66,304 ms
INTCON.T0IE=1;      // разрешили прерывания по переполнению TMR0
state=0;
Lcd_Config(&PORTB, 4, 5, 6, 3, 2, 1, 0); // назначение выводов ЖКИ - PIC
Lcd_Cmd(LCD_CURSOR_OFF);
Lcd_Out(1, 1, "Temp:");
Lcd_Chr(1,13,223);                       // вывод символа точки и "С" как единицы измерения
Lcd_Chr(1,14,'C');
Lcd_Out(2,1,"Min");
Lcd_Out(2,9,"Max");
MaxTemp=Eeprom_Read(0);                  // читаем уставку из EEPROM
MinTemp=Eeprom_Read(1);
if (MaxTemp>125){
MaxTemp=25;
MinTemp=23;
old_MaxTemp=MaxTemp;
old_MinTemp=MinTemp;
delay_ms(50);
Eeprom_Write(0,MaxTemp);
Eeprom_Write(1,MinTemp);
delay_ms(50);
}
minT[0]=MinTemp/100+48;
minT[1]=(MinTemp/10)%10+48;
minT[2]=MinTemp%10+48;
Lcd_Out(2,5,minT);
maxT[0]=MaxTemp/100+48;
maxT[1]=(MaxTemp/10)%10+48;
maxT[2]=MaxTemp%10+48;
Lcd_Out(2,13,maxT);
//--- главный цикл
do{
//--- чтение температуры из DS18B20
Ow_Reset(&PORTA,2);            // сигнал сброса
Ow_Write(&PORTA,2,0xCC);       // команда SKIP_ROM
Ow_Write(&PORTA,2,0x44);       // команда CONVERT_T
Delay_us(120);
Ow_Reset(&PORTA,2);
Ow_Write(&PORTA,2,0xCC);       // команда SKIP_ROM
Ow_Write(&PORTA,2,0xBE);       // команда READ_SCRATCHPAD
temp =  Ow_Read(&PORTA,2);
temp = (Ow_Read(&PORTA,2) << 8) + temp;
Control_Button();                    // подпрограмма обработки нажатия кнопок
if (old_MaxTemp!= MaxTemp) {          // если было изменение макс. температуры
Eeprom_Write(0,MaxTemp);             // то сохраняем в EEPROM новое значение уставки
delay_ms(50);
old_MaxTemp = MaxTemp;               // и сохраняем для текущей работы
}
if (old_MinTemp!=MinTemp) {           // если было изменение мин. температуры
Eeprom_Write(1,MinTemp);             // то сохраняем в EEPROM новое значение уставки
delay_ms(50);
old_MinTemp = MinTemp;               // и сохраняем для текущей работы
}
//--- форматирование, вывод на ЖКИ температуры и уставки, включение-выключение
Display_Temperature(temp);
Delay_ms(500);
}while (1);
}

Последний раз редактировалось petrd; 20.09.2010 в 09:37.
  Ответить с цитированием