#include "heater3.h" #include "lcd-twi.h" #include "potentiometers.h" #include "saveload.h" #include "fifo.h" #include "tools.h" const char cyrillic[64] = { 'A', 0xA0, 'B', 0xA1, 0xE0, 'E', 0xA3, 0xA4, 0xA5, 0xA6, 'K', 0xA7, 'M', 'H', 'O', 0xA8, 'P', 'C', 'T', 0xA9, 0xAA, 'X', 0xE1, 0xAB, 0xAC, 0xE2, 0xAD, 0xAE, 'b', 0xAF, 0xB0, 0xB1, 'a', 0xB2, 0xB3, 0xB4, 0xE3, 'e', 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 'o', 0xBE, 'p', 'c', 0xBF, 'y', 0xE4, 'x', 0xE5, 0xC0, 0xC1, 0xE6, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7 }; volatile uint8_t btn_act = 0; volatile uint8_t rxbuf[40]; volatile uint8_t count = 0; volatile comdata_str rxdata; volatile uint8_t tick1 = 0; volatile uint8_t tick2 = 0; uint8_t cal_tmax = 130; uint8_t cal_tmin = 40; heater_str heater[2]; opamp_str opamp[2]; preset_str preset[2]; uint8_t txrequest = 0; static FILE lcd_stdout = FDEV_SETUP_STREAM(lcd_putchar, NULL, _FDEV_SETUP_WRITE); static FILE uart_stdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); FIFO(512) fifo0; ISR(PCINT3_vect) { btn_act = 1; if(((BTNPIN >> 4) | 0xF0) == 0xF0) { cli(); WDTCSR |= (1 << WDCE) | (1 << WDE); } } ISR(INT0_vect) /*OVERCURRENT PROTECTION 1*/ { cli(); GATEPORT |= (1 << GATE1) | (1 << GATE2); LEDPORT &= ~((1 << LED1) | (1 << LED2)); PORTC &= ~(1 << V12POWER); heater[0].status.heating = heater[1].status.heating = 0; heater[0].status.onoff = heater[1].status.onoff = 0; heater[0].status.ocp = 1; } ISR(INT1_vect) /*OVERCURRENT PROTECTION 2*/ { cli(); GATEPORT |= (1 << GATE1) | (1 << GATE2); LEDPORT &= ~((1 << LED1) | (1 << LED2)); PORTC &= ~(1 << V12POWER); heater[0].status.heating = heater[1].status.heating = 0; heater[0].status.onoff = heater[1].status.onoff = 0; heater[1].status.ocp = 1; } ISR(USART0_RX_vect) { count++; rxbuf[count - 1] = UDR0; } ISR(USART0_UDRE_vect) { if(FIFO_IS_EMPTY(fifo0)) { UCSR0B &= ~(1 << UDRIE0); } else { UDR0 = FIFO_FRONT(fifo0); FIFO_POP(fifo0); } } ISR(TIMER0_COMPA_vect) { tick1 = 1; } ISR(TIMER1_COMPA_vect) { tick2 = 1; } void init() { /* Watchdog clear*/ MCUSR &= ~(1 << WDRF); WDTCSR |= (1 << WDCE) | (1 << WDE); WDTCSR = 0x00; /* External interrupts initialization */ EICRA |= (1 << ISC01) | (1 << ISC11); EIMSK |= (1 << INT0) | (1 << INT1); /* GPIO Initialization */ PORTC |= (1 << GATE1) | (1 << GATE2) | (1 << V12POWER); DDRC |= (1 << LED1) | (1 << LED2) | (1 << GATE1) | (1 << GATE2) | (1 << V12POWER); /* UART Initialization */ TXD_PORT |= (1 << TXD_BIT); TXD_DDR |= (1 << TXD_BIT); #if U2X0_SET UBRR0H = (uint8_t)(((F_CPU / (8 * BAUD_RATE)) - 1) >> 8); UBRR0L = (uint8_t)((F_CPU / (8 * BAUD_RATE)) - 1); UCSR0A = (1 << U2X0); #elif UBRR0H = (uint8_t)(((F_CPU / (16 * BAUD_RATE)) - 1) >> 8); UBRR0L = (uint8_t)((F_CPU / (16 * BAUD_RATE)) - 1); #endif UCSR0B = (1 << RXCIE0) | (1 << RXEN0) | (1 << TXEN0); UCSR0C = (1 << UCSZ00) | (1 << UCSZ01); /* SPI Initialization */ DDRB |= (1 << MOSI_BIT) | (1 << SCK_BIT) | (1 << SS_BIT) | (7 << PORTB0); PORTB |= (1 << MOSI_BIT) | (1 << SCK_BIT) | (1 << SS_BIT); SPCR = (1 << SPE) | (1 << MSTR); /* TWI Initialization */ TWBR = (uint8_t)(((F_CPU / TWI_FREQ) - 16) / 2); TWCR = (1 << TWEN); /* Timer0 Initialization */ TCCR0A = (1 << WGM01); OCR0A = 0x80; TCCR0B = (1 << CS00) | (1 << CS02); TIMSK0 = (1 << OCIE0A); /* Timer1 Initialization */ TCCR1B = (1 << CS12) | (1 << CS10) | (1 << WGM12); OCR1A = 0x400; TIMSK1 = (1 << OCIE1A); /* ADC Initialization */ ADMUX |= (1 << REFS0) | (1 << REFS1); ADCSRA = (1 << ADEN) | (1 << ADPS0) | (1 << ADPS1); DIDR0 = 0xFF; PCICR = (1 << PCIE3); PCMSK3 = 0xF0; } void MAX_ReadData() { uint8_t i = 0; max31855_t data; btw32_t *dptr = (btw32_t*)&data; PORTB = (PORTB & 0xF8) | MAXADDR; PORTB &= ~(1 << SS_BIT); for(i = 0; i < 4; i++) { SPDR = 0xFF; while(!(SPSR & (1 << SPIF))); dptr->byte[3 - i] = SPDR; } PORTB |= (1 << SS_BIT); heater[CH0].tintr = heater[CH1].tintr = (int8_t)data.intt_int; if(data.intt_frac * (100.0 / 16.0) >= 50) heater[CH0].tintr++; if(data.oc | data.scg | data.scg) { heater[CH0].status.couple = heater[CH1].status.couple = dptr->byte[0] & 0x07; heater[CH0].tcouple = heater[CH1].tcouple = 0; } else { heater[CH0].status.couple = heater[CH1].status.couple = 0; heater[CH0].tcouple = heater[CH1].tcouple = ((int16_t)data.tct_int ^ 0x0800) - 0x0800; if((data.tct_frac * (100 / 4)) >= 50) heater[CH0].tcouple = heater[CH1].tcouple++; } } int16_t CalculateTemp(uint16_t data, uint8_t ch) { if(data > preset[ch].curve[0].adcdata) return 0; if(data < preset[ch].curve[15].adcdata) return 150; for(uint8_t i = 0; i < 16; i++) { if(data >= preset[ch].curve[i].adcdata) { return Approx(preset[ch].curve[i - 1].adcdata, preset[ch].curve[i].adcdata, preset[ch].curve[i - 1].temp, preset[ch].curve[i].temp, data); } } return (-1); } int16_t TMeasure(uint8_t ch) { uint16_t addata = 0; uint16_t avg_data = 0; uint8_t i = 0; ADMUX = (ADMUX & 0xF8) | (ch & 0x01); _delay_us(100); avg_data = 0; for(i = 0; i < 10; i++) { ADCSRA |= (1 << ADSC); while(!(ADCSRA & (1 << ADIF))); addata = ADCL; addata |= ((uint16_t)ADCH) << 8; avg_data += addata; } addata = avg_data / 10; heater[ch].tmeas_raw = addata; heater[ch].tmeas = CalculateTemp(addata, ch); return (heater[ch].tmeas); } uint16_t CurrMeasure(uint8_t ch) { uint16_t addata = 0; ADMUX = (ADMUX & 0xF8) | (ADC_CUR1 + (ch & 0x01)); _delay_us(100); ADCSRA |= (1 << ADSC); while(!(ADCSRA & (1 << ADIF))); addata = ADCL; addata |= ((uint16_t)ADCH) << 8; heater[ch].current = ((float)addata * 2.4); return (heater[ch].current); } int lcd_putchar(char c, FILE *stream) { if(c >= 0xC0) c = cyrillic[c - 0xC0]; LCD_SendData(c); return 0; } int uart_putchar(char c, FILE *stream) { cli(); if(!FIFO_IS_FULL(fifo0)) { FIFO_PUSH(fifo0, c); UCSR0B |= (1 << UDRIE0); } sei(); return 0; } void TransmitPresets() { uint8_t checksum = 0x1F; uart_putchar(0x55, NULL); // fprintf(&uart_stdout, "BEG"); uart_putchar(0x45, NULL); uart_putchar(0x85, NULL); for(uint8_t pn = 0; pn < 25; pn++) { for(uint8_t offs = 0; offs < 13; offs++) { EEAR = 0x30 + (pn * sizeof(preset_str)) + offs; EECR |= (1 << EERE); uint8_t data = EEDR; uart_putchar(data, NULL); checksum += data; } } uart_putchar(checksum, NULL); txrequest = 0; // fprintf(&uart_stdout, "END"); } void Transmit() { comdata_str *txdata = (comdata_str*)calloc(1, sizeof(comdata_str)); txdata->start = 0x55; txdata->command = txrequest; switch((txreq_t)txrequest) { case REQ_RST: case REQ_ACK: case REQ_NACK: txdata->len = 0; break; case REQ_MAINDATA: txdata->len = sizeof(heater); memcpy(txdata->data, heater, sizeof(heater)); break; case REQ_DEBUGDATA: break; case REQ_PRESETTABLE: TransmitPresets(); free(txdata); return; case REQ_PRESETDATA: txdata->len = sizeof(preset); memcpy(txdata->data, preset, sizeof(preset)); break; } //fprintf(&uart_stdout, "BEG"); for(uint8_t i = 0; i < (txdata->len + 3); i++) { uart_putchar(((uint8_t*)txdata)[i], NULL); txdata->checksum += ((uint8_t*)txdata)[i]; } uart_putchar(txdata->checksum, NULL); //fprintf(&uart_stdout, "END"); txrequest = 0; free(txdata); } void ResetMCU(void) { cli(); WDTCSR |= (1 << WDCE) | (1 << WDE); while(1); } void SwitchHeating(uint8_t ch, uint8_t onoff) { if(onoff) { GATEPORT &= ~(1 << (GATE1 + (ch & 0x01))); LEDPORT |= (1 << (LED1 + (ch & 0x01))); heater[ch].status.heating = 1; } else { GATEPORT |= (1 << (GATE1 + (ch & 0x01))); LEDPORT &= ~(1 << (LED1 + (ch & 0x01))); heater[ch].status.heating = 0; } } float VoltageMeasure(uint8_t ch) { uint16_t addata = 0; float voltage = 0.0; ADMUX = (ADMUX & 0xF8) | (ch & 0x01); _delay_us(100); ADCSRA |= (1 << ADSC); while(!(ADCSRA & (1 << ADIF))); addata = ADCL; addata |= ((uint16_t)ADCH) << 8; voltage = (float)addata * 0.0025; voltage = (voltage / (0.758 * opamp[ch].gain)) + opamp[ch].shift; return voltage; } circ_t CircuitDetect(uint8_t ch) { uint8_t gain, shift, drive; float voltage; circ_t circ; gain = heater[ch].gain; shift = heater[ch].shift; drive = heater[ch].drive; SetDriveVoltage(ch, 0); SetInputRange(ch, 0.0, 3.0); voltage = VoltageMeasure(ch); if(voltage > 3.0) { circ = CIRC_OPEN; } else if((voltage > 0.05) && (voltage <= 1.5)) { SetDriveData(ch, 0xFF); SwitchDrive(ch, ON); _delay_ms(1); voltage = VoltageMeasure(ch); SetDriveData(ch, drive); SwitchDrive(ch, OFF); if(voltage < 0.2) { circ = CIRC_MOSFET; } else { circ = CIRC_RES_DIODE; } } else { circ = CIRC_RES; } SetGainData(ch, gain); SetShiftData(ch, shift); SetDriveData(ch, drive); heater[ch].status.circuit = circ; return circ; } void UARTDataAvail() { static uint8_t rxcnt; uint8_t localcnt = count; for(uint8_t i = 0; i < localcnt; i++) { uint8_t rxbyte = rxbuf[i]; switch(rxcnt) { case 0: if(rxbyte == 0x55) { //rxdata.start = rxbyte; rxdata.checksum = rxbyte; rxcnt++; } break; case 1: if(rxbyte < 100) { rxdata.len = rxbyte; rxdata.checksum += rxbyte; rxcnt++; } else { rxcnt = 0; } break; case 2: rxdata.command = rxbyte; rxdata.checksum += rxbyte; rxcnt++; break; default: if(rxcnt < (rxdata.len + 3)) { rxdata.data[rxcnt - 3] = rxbyte; rxdata.checksum += rxbyte; rxcnt++; } else { if(rxbyte == rxdata.checksum) { ProcessCommand(); } rxcnt = 0; } } count--; } } int AutoCalibration(uint8_t ch) { uint8_t drive = 0; int16_t tstart = 0; uint16_t delcnt = 0; float vlow = 0.0, vhigh = 0.0; MAX_ReadData(); CircuitDetect(ch); if(((heater[ch].status.circuit == CIRC_MOSFET) || (heater[ch].status.circuit == CIRC_RES_DIODE)) && (heater[ch].status.couple == 0)) { LCD_SendCmd(LCD_CLR); SetInputRange(ch, 0.0, 3.0); SetDriveVoltage(ch, 0.0); _delay_ms(2); do { MAX_ReadData(); LCD_SetPos(0, 0); fprintf(&lcd_stdout, "K%.1u P%.2u Tm=%.3u -", ch + 1, heater[ch].preset, heater[ch].tmeas); LCD_SetPos(0, 1); fprintf(&lcd_stdout, "CALIB. Tc=%.3u -", heater[ch].tcouple); } while(heater[ch].tcouple > cal_tmin); tstart = heater[ch].tcouple; vhigh = VoltageMeasure(ch) + 0.04; if(heater[ch].status.circuit == CIRC_MOSFET) { do { SetDriveData(ch, drive); SwitchDrive(ch, ON); SwitchHeating(ch, ON); _delay_ms(1); CurrMeasure(ch); SwitchHeating(ch, OFF); SwitchDrive(ch, OFF); drive++; } while(heater[ch].current < 1000); drive--; SwitchDrive(ch, ON); } SwitchHeating(ch, ON); while(heater[ch].tcouple < (cal_tmax + 2)) { if(CurrMeasure(ch) > CURR_MAX) return 0; if(heater[ch].status.circuit == CIRC_MOSFET) { if(heater[ch].current > 1500) { SetDriveData(ch, --drive); SwitchDrive(ch, ON); } if(heater[ch].current < 1000) { SetDriveData(ch, ++drive); SwitchDrive(ch, ON); } } MAX_ReadData(); if((heater[ch].status.circuit == CIRC_OPEN) || (heater[ch].status.circuit == CIRC_RES) || (heater[ch].status.couple != 0)) { LoadPreset(ch); return (-1); } if(++delcnt > 300) { delcnt = 0; if((heater[ch].tcouple - tstart) < 5) { SwitchHeating(ch, OFF); SwitchDrive(ch, OFF); LCD_SetPos(0, 0); fprintf(&lcd_stdout, "Íåäîñòàòî÷íûé "); LCD_SetPos(0, 1); fprintf(&lcd_stdout, "òåïëîâîé êîíòàêò"); LoadPreset(ch); btn_act = 0; while(!btn_act); return(-1); } else { tstart = heater[ch].tcouple; } } LCD_SetPos(0, 0); fprintf(&lcd_stdout, "%04.2f-%04.2f G=%04.2f", vhigh, vlow, opamp[ch].drive); LCD_SetPos(0, 1); fprintf(&lcd_stdout, "I=%.4umA Tc=%.3u ", heater[ch].current, heater[ch].tcouple); } SwitchHeating(ch, OFF); SwitchDrive(ch, OFF); _delay_ms(2); vlow = VoltageMeasure(ch); if(vlow > 0.01) vlow -= 0.01; SetInputRange(ch, vlow, vhigh); for(uint8_t temp = cal_tmax; temp >= cal_tmin; temp -= 10) { while(heater[ch].tcouple >= temp) { MAX_ReadData(); LCD_SetPos(0, 0); fprintf(&lcd_stdout, "VH=%04.2f Dm=%.3u -", vhigh, heater[ch].tmeas_raw); LCD_SetPos(0, 1); fprintf(&lcd_stdout, "VL=%04.2f Tc=%.3u -", vlow, heater[ch].tcouple); } TMeasure(ch); preset[ch].curve[temp / 10].temp = temp; preset[ch].curve[temp / 10].adcdata = heater[ch].tmeas_raw; if((heater[ch].status.circuit == CIRC_OPEN) || (heater[ch].status.circuit == CIRC_RES) || (heater[ch].status.couple != 0) ) { LoadPreset(ch); return (-1); } } for(uint8_t temp = 0; temp < cal_tmin; temp += 10) { preset[ch].curve[temp / 10].temp = temp; preset[ch].curve[temp / 10].adcdata = Approx(preset[ch].curve[cal_tmin / 10].temp, preset[ch].curve[cal_tmax / 10].temp, preset[ch].curve[cal_tmin / 10].adcdata, preset[ch].curve[cal_tmax / 10].adcdata, preset[ch].curve[temp / 10].temp); } for(uint8_t temp = (cal_tmax + 10); temp < 160; temp += 10) { preset[ch].curve[temp / 10].temp = temp; preset[ch].curve[temp / 10].adcdata = Approx(preset[ch].curve[cal_tmin / 10].temp, preset[ch].curve[cal_tmax / 10].temp, preset[ch].curve[cal_tmin / 10].adcdata, preset[ch].curve[cal_tmax / 10].adcdata, preset[ch].curve[temp / 10].temp); } if(strlen(preset[ch].header) == 0) { strncpy(preset[ch].header, "DEFAULT", 12); } preset[ch].number = heater[ch].preset; preset[ch].gain = heater[ch].gain; preset[ch].shift = heater[ch].shift; preset[ch].drive = heater[ch].drive; SavePreset(ch); LCD_SendCmd(LCD_CLR); } return 0; } void ManualCalibration(uint8_t ch) { uint8_t drive = 0; float vlow = 0.0, vhigh = 0.0; LCD_SendCmd(LCD_CLR); LCD_SetPos(0, 0); fprintf(&lcd_stdout, "ÐÓ×Í. ÊÀËÈÁÐÎÂÊÀ"); if(heater[ch].status.circuit == CIRC_MOSFET) { do { SetDriveData(ch, drive); SwitchDrive(ch, ON); SwitchHeating(ch, ON); _delay_ms(1); CurrMeasure(ch); SwitchHeating(ch, OFF); SwitchDrive(ch, OFF); drive++; } while(heater[ch].current < 1000); drive--; } while(heater[ch].status.calib == CAL_MANUAL) { if(count) { UARTDataAvail(); } if(txrequest) { Transmit(); } if(heater[ch].status.heating) { if(heater[ch].status.circuit == CIRC_MOSFET) SwitchDrive(ch, ON); SwitchHeating(ch, ON); _delay_ms(1); if(CurrMeasure(ch) > 2000) { drive--; SetDriveData(ch, drive); SwitchDrive(ch, ON); } } else { SwitchHeating(ch, OFF); SwitchDrive(ch, OFF); } } heater[ch].status.heating = OFF; } void ProcessCommand() { uint8_t ch = ((rxdata.command & 0x80) >> 7) & 0x01; rxdata.command &= 0x7F; txrequest = REQ_ACK; switch(rxdata.command) { case CMD_RESET: ResetMCU(); break; case CMD_REQ: txrequest = rxdata.data[0]; break; case CMD_CHONOFF: heater[ch].status.onoff = rxdata.data[0]; SwitchHeating(ch, OFF); SwitchDrive(ch, OFF); break; case CMD_SETTEMP: heater[ch].tset = rxdata.data[0]; break; case CMD_SETRANGE: heater[ch].gain = rxdata.data[0]; heater[ch].shift = rxdata.data[1]; SetGainData(ch, rxdata.data[0]); SetShiftData(ch, rxdata.data[1]); break; case CMD_SETVDRIVE: heater[ch].drive = rxdata.data[0]; opamp[ch].drive = ((float)heater->drive / 25.76); break; case CMD_SWPRESET: heater[ch].preset = rxdata.data[0]; LoadPreset(ch); SavePrefs(); break; case CMD_LOADDATA: memcpy((uint8_t*)preset, (uint8_t*)rxdata.data, rxdata.len); SavePreset(ch); break; case CMD_HEATING: if(heater[ch].status.calib == CAL_MANUAL) heater[ch].status.heating = rxdata.data[0]; break; case CMD_CALIBRATION: heater[ch].status.calib = rxdata.data[0]; cal_tmin = rxdata.data[1]; cal_tmax = rxdata.data[2]; if(heater[ch].status.calib == CAL_MANUAL) ManualCalibration(ch); else if(heater[ch].status.calib == CAL_AUTO) AutoCalibration(ch); break; } } void LoadingScreen() { uint8_t c = 0xFF, i = 0, d = 0, btn = 0; do { _delay_ms(20); LCD_SetPos(i, 0); LCD_SendData(c); LCD_SetPos(15 - i, 1); LCD_SendData(c); if(++i > 15) { c ^= ~' '; i = 0; d++; } btn = ~((BTNPIN >> 4) | 0xF0); } while(btn || (d < 2)); LCD_SendCmd(LCD_CLR); } int main() { uint8_t ch = CH0; uint8_t tmp = 0; uint8_t display = DISP_MAIN; btn_t button; menu_str *menu = (menu_str*)calloc(sizeof(menu_str), 1); memset(heater, 0x00, sizeof(heater)); memset(opamp, 0x00, sizeof(opamp)); memset(preset, 0x00, sizeof(preset)); opamp[CH0].ch = heater[CH0].status.channel = CH0; opamp[CH1].ch = heater[CH1].status.channel = CH1; heater[CH0].tset = heater[CH1].tset = 25; stdout = &uart_stdout; init(); LCD_Init(); LoadingScreen(); LoadPrefs(); LoadPreset(CH0); LoadPreset(CH1); //SwitchPower(ON); CircuitDetect(CH0); CircuitDetect(CH1); sei(); Transmit(); while(1) { if(count) { UARTDataAvail(); } if(txrequest) { Transmit(); } if(heater[CH0].status.ocp || heater[CH1].status.ocp) { LCD_SetPos(0, 0); fprintf(&lcd_stdout, "ÇÀÙÈÒÀ ÏÎ ÒÎÊÓ!!"); LCD_SetPos(0, 1); fprintf(&lcd_stdout, "ÍÀÆ."); LCD_SendData(0x00); fprintf(&lcd_stdout, " ÄËß ÑÁÐÎÑÀ"); while(((BTNPIN >> 4) | 0xF0) != 0xF7); ResetMCU(); } if(tick1) { /* ------------- MEASURING SECTION ----------------- */ tick1 = 0; MAX_ReadData(); tmp = ch; for(uint8_t ch = CH0; ch <= CH1; ch++) { if(CurrMeasure(ch) > CURR_MAX) { heater[ch].status.onoff = OFF; } SwitchHeating(ch, OFF); SwitchDrive(ch, OFF); _delay_ms(1); CircuitDetect(ch); TMeasure(ch); if(heater[ch].status.circuit == CIRC_OPEN) { heater[ch].status.onoff = OFF; } else if(heater[ch].status.circuit == CIRC_RES) { if((heater[ch].status.onoff == ON) && (heater[ch].tcouple < heater[ch].tset)) { SwitchHeating(ch, ON); } else { SwitchHeating(ch, OFF); } } else { if((heater[ch].status.onoff == ON) && (heater[ch].tmeas < heater[ch].tset)) { SwitchDrive(ch, ON); SwitchHeating(ch, ON); } else { SwitchDrive(ch, OFF); SwitchHeating(ch, OFF); } } } ch = tmp; } ////// if(tick1) end if(tick2) { /* ------------- DISPLAY SECTION ----------------- */ tick2 = 0; if(display == DISP_MAIN) { LCD_SetPos(0, 0); fprintf(&lcd_stdout, "K%.1u #%.2u Tï=", ch + 1, heater[ch].preset); if(!heater[ch].status.couple) { fprintf(&lcd_stdout, "%.3d\x01", heater[ch].tcouple); } else { fprintf(&lcd_stdout, "--- "); } switch(heater[ch].status.circuit) { case CIRC_OPEN: LCD_SendData(SYM_OPEN); break; case CIRC_SHORT: LCD_SendData(SYM_SHORT); break; case CIRC_RES: LCD_SendData(SYM_RES); break; case CIRC_MOSFET: LCD_SendData(SYM_MOSFET); break; case CIRC_RES_DIODE: LCD_SendData(SYM_DIODE); break; case CIRC_DIODE: break; } LCD_SetPos(0, 1); fprintf(&lcd_stdout, "Tó=%.3u\x01 ", heater[ch].tset); if((heater[ch].status.circuit == CIRC_OPEN) || (heater[ch].status.circuit == CIRC_SHORT)) { fprintf(&lcd_stdout, "ÎÒÊËÞ×."); } else if(heater[ch].status.circuit == CIRC_RES) { fprintf(&lcd_stdout, "I=%4.2fA", ((float)heater[ch].current) / 1000.0); } else { fprintf(&lcd_stdout, "Òí=%.3d\x01", heater[ch].tmeas); } if(heater[ch].status.onoff) { if(heater[ch].status.heating) { LCD_SendData(0xD9); } else { LCD_SendData(0xDA); } } else { LCD_SendData('-'); } if(menu->set == 1) { if(menu->blink_cnt % 4 == 0) { if(menu->blink_cnt > 40) { menu->set = 0; menu->blink_cnt = 0; SavePrefs(); } LCD_SetPos(3, 1); fprintf(&lcd_stdout, " "); } menu->blink_cnt++; } else if(menu->set == 2) { if(menu->blink_cnt % 4 == 0) { if(menu->blink_cnt > 40) { menu->set = 0; menu->blink_cnt = 0; SavePrefs(); } LCD_SetPos(4, 0); fprintf(&lcd_stdout, " "); } menu->blink_cnt++; } if(button.pressed && !button.holded) { if(++button.holdcnt == 12) { button.holded = 1; btn_act = 1; } } } else if(display == DISP_VER) { LCD_SetPos(0, 0); fprintf(&lcd_stdout, "ÓÊÍ-2 09.09.2019"); LCD_SetPos(0, 1); fprintf(&lcd_stdout, "Íàãàåâ Àëåêñàíäð"); } //txrequest = REQ_MAINDATA; //Transmit(); } ////// if(tick2) end /* ---------------- BUTTON SECTION --------------- */ if(btn_act) { _delay_ms(20); btn_act = 0; button.code = ~((BTNPIN >> 4) | 0xF0); if((button.code != 0x00) && (!button.holded)) // Button down event { if(display == DISP_MAIN) { button.pressed = 1; button.released = 0; button.prev_code = button.code; switch(button.code) { case 0x01: menu->blink_cnt = 1; if(menu->set == 1) { heater[ch].tset -= (heater[ch].tset != 0); } else if(menu->set == 2) { heater[ch].preset -= (heater[ch].preset != 0); LoadPreset(ch); } else { ch = CH0; } break; case 0x02: menu->blink_cnt = 1; if(menu->set == 1) { heater[ch].tset += (heater[ch].tset != 150); } else if(menu->set == 2) { heater[ch].preset += (heater[ch].preset != 24); LoadPreset(ch); } else { ch = CH1; } break; case 0x03: LCD_SendCmd(LCD_CLR); display = DISP_VER; break; case 0x04: menu->set = (menu->set + 1) % 3; if(menu->set == 0) SavePrefs(); menu->blink_cnt = 0; break; } ////// switch(btn_code) end } ////// if(display == ON) end } else if(button.code == 0) // Button up event { if(!button.holded) { display = DISP_MAIN; if(button.prev_code == 0x08) { heater[ch].status.onoff ^= 1; SwitchDrive(ch, OFF); SwitchHeating(ch, OFF); } } button.pressed = 0; button.released = 1; button.holded = 0; button.holdcnt = 0; } else // Button hold event { switch(button.code) { case 0x01: case 0x02: btn_act = 1; button.holded = 0; button.holdcnt--; break; case 0x04: menu->set = 0; AutoCalibration(ch); button.pressed = 0; button.holded = 0; button.holdcnt = 0; break; case 0x08: button.prev_code = 0; display = OFF; LCD_SendCmd(LCD_CLR); //btn_hold = 0; break; } } } ////// if(btn_act) end } ////// while(1) end } ////// main() end