123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644 |
- #include "main.h"
- __C_task void main(void)
- {
- /* Disable comaparator */
- ACSR = 1<<ACD;
- /* Init LED */
- LED_DDR = LED_1 | LED_2;
- LED_OFF(LED_1);
- LED_OFF(LED_2);
- /* Init 7 segment LED indicators */
- INDCTR_SEGMENT_DDR = 0xFF; // segment pins to output
- INDCTR_SEGMENT_PORT = 0x00; // off all segment
- INDCTR_COMMON_DDR = INDCTR_COMMON_ALL; // common pins to output
- INDCTR_COMMON_PORT = ~INDCTR_COMMON_ALL; // off all indikators
- Flag2.needDot = 0;
- Flag2.blinkIndktr = 0;
- /* Timer0 every 4 ms switch showing LED */
- TCCR0 = TIM0_PRESCALER;
- TCNT0 = TIM0_CNT; // load timer
- TIMSK |= 1<<TOIE0; // enable TIM0_OVF interrupt
- /* Timer1 ticks with 1 MHz frequency for DS18B20 delays */
- TCCR1B = TIM1_PRESCALER;
- // TCNT1 = 64536;
- // TIMSK |= 1<<TOIE1; // enable TIM1_OVF interrupt
- /* Timer2 count 1 ms */
- TCCR2 = TIM2_PRESCALER;
- TCNT2 = TIM2_CNT; // load timer
- TIMSK |= 1<<TOV2; // enable TIM2_OVF interrupt
- /* ADC init */
- resultADC = 0;
- ADMUX = (1<<REFS0) | (1<<ADLAR); // Vref = AVcc, channel ADC0, Left adjusted result
- ADCSR = 1<<ADEN | 1<<ADPS2 | 1<<ADPS1; // enable ADC, prescaler = 64
- /* I2C init */
- TWI_MasterInit(100);
- __enable_interrupt();
- // Start tasks
- counterADC = PERIOD_ADC; // every 50 ms start ADC measure
- counterTWI = 4; // small delay
- counterDS18B20s = 12; // small delay
-
- State = show_HHMM;
- while(1) {
- /* check time */
- if (1 == Flag.getTime) {
- Flag.getTime = 0;
- getTime();
- } // end of Flag.getTime
- if (1 == Flag.newTime) {
- Flag.newTime = 0;
-
- switch (State) {
- case show_HHMM:
- // every 25 and 55 seconds shoe temperature for 5 seconds
- if ((0x25 == Clock.seconds) || (0x55 == Clock.seconds)) {
- State = show_TEMP;
- counterShowTemp = PERIOD_SHT;
- showTEMP();
- } else {
- showHHMM();
- }
- break;
-
- case show_MMSS:
- showMMSS();
- break;
- case set_TIME:
- showHHMM();
- break;
-
- default:
- break;
- }
- } // end of Flag.newTime
- /* Temperature */
- if (1 == Flag.startDS18B20) {
- Flag.startDS18B20 = 0;
- ds18b20_StartMeasure();
- }
-
- if (1 == Flag.readDS18B20) {
- Flag.readDS18B20 = 0;
- ds18b20_ReadTemperature();
- }
- if (1 == Flag.newTemp) {
- Flag.newTemp = 0;
- if (show_TEMP == State) {
- showTEMP();
- }
- } // end of Flag.newTemp
- /* check buttons */
- if (1 == Flag.newBTN) {
- Flag.newBTN = 0;
- uint8_t mm, hh;
-
- btn_t btn = getBTN();
- switch (btn) {
- case btn_1:
- // show HH:MM
- if (State != set_TIME) {
- State = show_HHMM;
- counterShowTemp = 0;
- showHHMM();
- }
- break;
- case btn_2:
- // show MM SS
- if (State != set_TIME) {
- State = show_MMSS;
- Flag2.needDot = 1;
- counterShowTemp = 0;
- showMMSS();
- }
- break;
- case btn_3:
- // show temperature
- if (State != set_TIME) {
- State = show_TEMP;
- Flag2.needDot = 0;
- counterShowTemp = 0;
- showTEMP();
- }
- break;
- case btn_4:
- // time --
- if (set_TIME == State) {
- mm = bcd2bin(Clock.minutes);
- hh = bcd2bin(Clock.hours);
- mm --;
- if (mm > 59) {
- mm = 59;
- hh --;
- if (hh >23 ) {
- hh = 23;
- }
- }
- Clock.minutes = bin2bcd(mm);
- Clock.hours = bin2bcd(hh);
- Flag.newTime = 1;
- }
- break;
- case btn_5:
- // time ++
- if (set_TIME == State) {
- mm = bcd2bin(Clock.minutes);
- hh = bcd2bin(Clock.hours);
- mm ++;
- if (mm > 59) {
- mm = 0;
- hh ++;
- if (hh > 23) {
- hh = 0;
- }
- }
- Clock.minutes = bin2bcd(mm);
- Clock.hours = bin2bcd(hh);
- Flag.newTime = 1;
- }
- break;
- case btn_6:
- // save new time
- if (set_TIME == State) {
- State = show_HHMM;
- Flag2.blinkIndktr = 0;
- setTime();
- counterTWI = PERIOD_TWI;
- Flag.newTime = 1;
- }
- break;
- case btn_7:
- // time set
- if (show_HHMM == State) {
- State = set_TIME;
- Flag2.blinkIndktr = 1;
- Flag2.needDot = 1;
- counterTWI = 0;
- }
- break;
- default:
- break;
- }
-
- } // end of new BTN
- // делать нехрен -- спим, ждём прерывание
- MCUCR = 1<<SE;
- __sleep();
- } // end of while(1)
- } // end of main()
- /**
- * S u b r o u t i n e s
- */
- static uint8_t bcd2bin(uint8_t bcd) {
- // return ((10*(bcd>>4))|(bcd&0x0f));
- uint8_t Temp = bcd & 0x0F;
- while (bcd>=0x10)
- {
- Temp += 10;
- bcd -= 0x10;
- }
- return Temp;
- }
- static uint8_t bin2bcd(uint8_t bin) {
- // return (((bin/10)<<4)|(bin%10));
- uint8_t Temp = 0;
- while(bin>9)
- {
- Temp += 0x10;
- bin-=10;
- }
- return Temp+bin;
- }
- static void showHHMM(void) {
- if (Clock.hours > 9) {
- Indicator1 = IndctrNums[(0x0F & (Clock.hours>>4))];
- } else {
- Indicator1 = Sym_blank;
- }
- Indicator2 = IndctrNums[(0x0F & Clock.hours)];
- Indicator3 = IndctrNums[(0x0F & (Clock.minutes>>4))];
- Indicator4 = IndctrNums[(0x0F & Clock.minutes)];
- }
- static void showMMSS(void) {
- Indicator1 = IndctrNums[(0x0F & (Clock.minutes>>4))];
- Indicator2 = IndctrNums[(0x0F & Clock.minutes)];
- Indicator3 = IndctrNums[(0x0F & (Clock.seconds>>4))];
- Indicator4 = IndctrNums[(0x0F & Clock.seconds)];
- }
- static void showTEMP(void) {
- int8_t t = Temperature;
-
- if (t < 0) {
- Indicator1 = Sym_minus;
- t = -t;
- } else {
- Indicator1 = Sym_blank;
- }
- // convert to BCD
- t = bin2bcd(t);
- Indicator2 = IndctrNums[(0x0F & (t>>4))];
- Indicator3 = IndctrNums[(0x0F & t)];
- Indicator4 = Sym_gradus;
-
- Flag2.needDot = 0;
- }
- static btn_t getBTN(void) {
- uint8_t btn_code = resultADC;
- if (btn_code > 0xED) {
- return btn_no;
- } else if (btn_code > 0xD8) {
- return btn_1;
- } else if (btn_code > 0xD0) {
- return btn_2;
- } else if (btn_code > 0xC5) {
- return btn_3;
- } else if (btn_code > 0xB4) {
- return btn_4;
- } else if (btn_code > 0x94) {
- return btn_5;
- } else if (btn_code > 0x3F) {
- return btn_6;
- } else {
- return btn_7;
- }
- }
- static void getTime(void) {
- static uint8_t old_sec;
- /* Sync with indicators */
- Flag2.waitIndktr = 1;
- while (Flag2.waitIndktr == 1);
-
- /*устанавливаем указатель DS1307 на нулевой адрес*/
- twi_buf[0] = (DS1307_ADR<<1)|0; //адресный пакет
- twi_buf[1] = 0; //адрес регистра
- TWI_SendData(twi_buf, 2);
- /*считываем время с DS1307*/
- twi_buf[0] = (DS1307_ADR<<1)|1;
- TWI_SendData(twi_buf, 5);
- /*переписываем данные буфера драйвера в свой буфер*/
- TWI_GetData(twi_buf, 5);
- Clock.seconds = twi_buf[1];
- Clock.minutes = twi_buf[2];
- Clock.hours = twi_buf[3];
-
- if (show_HHMM == State) {
- if (old_sec != Clock.seconds) {
- Flag2.needDot = 1;
- old_sec = Clock.seconds;
- } else {
- Flag2.needDot = 0;
- }
- }
- Flag.newTime = 1;
- }
- static void setTime(void) {
- /* Sync with indicators */
- Flag2.waitIndktr = 1;
- while (Flag2.waitIndktr == 1);
-
- /* prepare new time */
- twi_buf[0] = (DS1307_ADR<<1)|0; //адресный пакет
- twi_buf[1] = 0; //адрес регистра
- twi_buf[2] = 0; //значение секунд
- twi_buf[3] = Clock.minutes; //значение минут
- twi_buf[4] = Clock.hours; //значение часов
- /* senr to rtc */
- TWI_SendData(twi_buf, 5);
- }
- /* DS18B20 functions */
- static uint8_t ds18b20_Reset(void) {
- uint8_t i;
- /* Pull line low and wait for 480uS */
- DS18B20_LOW;
- DS18B20_OUTPUT_MODE;
- //ds18b20_delay(us(480));
- TCNT1 = 0;
- while (TCNT1 <= 480) {
- }
- /* Release line and wait for 60uS */
- DS18B20_INPUT_MODE;
- //ds18b20_delay(us(60));
- TCNT1 = 0;
- while (TCNT1 <= 60) {
- }
- /* Store line value and wait until the completion of 480uS period */
- i = DS18B20_VALUE;
- //ds18b20_delay(us(420));
- //OCR1B = 420;
- TCNT1 = 0;
- while (TCNT1 <= 420) {
- }
- /* Return the value read from the presence pulse (0=OK, else=WRONG) */
- return i;
- }
- static void ds18b20_WriteBit(uint8_t bit) {
- /* Pull line low for 1uS */
- DS18B20_LOW;
- DS18B20_OUTPUT_MODE;
- //ds18b20_delay(us(1));
- TCNT1 = 0;
- while (TCNT1 <= 1);
- /* If we want to write 1, release the line (if not will keep low) */
- if(1 == bit) {
- DS18B20_INPUT_MODE;
- }
- /* Wait for 60uS and release the line */
- //ds18b20_delay(us(60));
- TCNT1 = 0;
- while (TCNT1 <= 60) {
- }
- DS18B20_INPUT_MODE;
- }
- static uint8_t ds18b20_ReadBit(void) {
- uint8_t bit=0;
- /* Pull line low for 1uS */
- DS18B20_LOW;
- DS18B20_OUTPUT_MODE;
- //ds18b20_delay(us(1));
- TCNT1 = 0;
- while (TCNT1 <= 1);
- /* Release line and wait for 14uS */
- DS18B20_INPUT_MODE;
- //ds18b20_delay(us(14));
- TCNT1 = 0;
- while (TCNT1 <= 14) {
- }
- /* Read line value */
- if (DS18B20_VALUE != 0) {
- bit = 0x80;
- }
- /* Wait for 45uS to end and return read value */
- //ds18b20_delay(us(45));
- TCNT1 = 0;
- while (TCNT1 <= 45) {
- }
- return bit;
- }
- static uint8_t ds18b20_ReadByte(void) {
- uint8_t i=8, n=0;
- while (i--) {
- /* Shift one position right and store read value */
- n >>= 1;
- n |= ds18b20_ReadBit();
- }
- return n;
- }
- static void ds18b20_WriteByte(uint8_t byte) {
- uint8_t i=8;
- while (i--) {
- /* Write actual bit and shift one position right to make the next bit ready */
- ds18b20_WriteBit(byte & 0x01);
- byte >>= 1;
- }
- }
- static void ds18b20_StartMeasure(void) {
- /* Sync with indicators */
- Flag2.waitIndktr = 1;
- while (Flag2.waitIndktr == 1);
-
- /* Reset, skip ROM and start temperature conversion */
- if (ds18b20_Reset() != 0) {
- Temperature = -99;
- Flag.newTemp = 1;
- } else {
- ds18b20_WriteByte(DS18B20_CMD_SKIPROM);
- ds18b20_WriteByte(DS18B20_CMD_CONVERTTEMP);
- counterDS18B20r = PERIOD_DS18B20r;
- }
- }
- static void ds18b20_ReadTemperature(void) {
- uint8_t temperature[2];
- uint8_t decimal;
- /* Sync with indicators */
- Flag2.waitIndktr = 1;
- while (Flag2.waitIndktr == 1);
-
- /* Reset, skip ROM and send command to read Scratchpad */
- if (ds18b20_Reset() != 0) {
- Temperature = -98;
- } else {
- ds18b20_WriteByte(DS18B20_CMD_SKIPROM);
- ds18b20_WriteByte(DS18B20_CMD_RSCRATCHPAD);
- /* Read Scratchpad (only 2 first bytes) */
- temperature[0]=ds18b20_ReadByte();
- temperature[1]=ds18b20_ReadByte();
- //ds18b20_reset();
- /* Store temperature integer digits */
- Temperature = ((temperature[1]&0x7)<<4) | (temperature[0]>>4);
- // get decimal part
- decimal = (temperature[0] & 15);
-
- // convert to binary
- //decimal *= 10; //(tempDecimals << 1) + (tempDecimals << 3);// Умножаем на 10
- //decimal >>= 4; //(tempDecimals >> 4);//делим на 16 или умножаем на 0.0625
-
- // round integer part
- if (decimal > 7) {
- Temperature ++;
- }
- }
-
- Flag.newTemp = 1;
- }
- /**
- * I n t e r r u p t h a n d l e r s
- */
- #pragma vector=TIMER0_OVF_vect
- __interrupt void TIMER0_OVF_ISR(void) {
- static uint8_t indicator = 0;
- static uint8_t blank_time = 0; // blanking timer
- uint8_t flag = 1;
- TCNT0 = TIM0_CNT; // reload timer
- INDCTR_COMMON_PORT &= ~INDCTR_COMMON_ALL; // off all indikators
- INDCTR_SEGMENT_PORT = 0;
- Flag2.waitIndktr = 0;
- if (1 == Flag2.blinkIndktr) {
- if (blank_time <= 150) {
- flag = 1;
- blank_time ++;
- } else if (blank_time <= 250) {
- blank_time ++;
- flag = 0;
- } else {
- blank_time = 0;
- flag = 1;
- }
- }
- if (1 == flag) {
- switch (indicator) {
- case 0:
- INDCTR_SEGMENT_PORT = Indicator1;
- INDCTR_COMMON_PORT |= 0x01;
- indicator = 1;
- break;
- case 1:
- if (1 == Flag2.needDot) {
- INDCTR_SEGMENT_PORT = Indicator2 | Sym_dot;
- } else {
- INDCTR_SEGMENT_PORT = Indicator2;
- }
- INDCTR_COMMON_PORT |= 0x02;
- indicator = 2;
- break;
- case 2:
- INDCTR_SEGMENT_PORT = Indicator3;
- INDCTR_COMMON_PORT |= 0x04;
- indicator = 3;
- break;
- case 3:
- INDCTR_SEGMENT_PORT = Indicator4;
- INDCTR_COMMON_PORT |= 0x08;
- default:
- indicator = 0;
- break;
- } // end of switch
- }
- }
- #pragma vector=TIMER1_COMPA_vect
- __interrupt void TIMER1_COMPA_ISR(void) {
- }
- #pragma vector=TIMER1_COMPB_vect
- __interrupt void TIMER1_COMPB_ISR(void) {
- }
- #pragma vector=TIMER1_OVF_vect
- __interrupt void TIMER1_OVF_ISR(void) {
- // Flag.T1OC = 1;
- }
- #pragma vector=TIMER2_OVF_vect
- __interrupt void TIMER2_OVF_ISR(void) {
- TCNT2 = TIM2_CNT; // reload timer
- if (counterADC > 0) {
- counterADC --;
- if (counterADC == 0) {
- counterADC = PERIOD_ADC;
- // enable interrupt and start conversion
- ADCSR |= ((1<<ADSC) | (1<<ADIE));
- }
- }
- if (counterTWI > 0) {
- counterTWI --;
- if (counterTWI == 0) {
- counterTWI = PERIOD_TWI;
- Flag.getTime = 1;
- }
- }
- if (counterShowTemp > 0) {
- counterShowTemp --;
- if (counterShowTemp == 0) {
- State = show_HHMM;
- }
- }
-
- if (counterDS18B20s > 0) {
- counterDS18B20s --;
- if (counterDS18B20s == 0) {
- counterDS18B20s = PERIOD_DS18B20s;
- Flag.startDS18B20 = 1;
- }
- }
-
- if (counterDS18B20r > 0) {
- counterDS18B20r --;
- if (counterDS18B20r == 0) {
- Flag.readDS18B20 = 1;
- }
- }
- }
- #pragma vector=ADC_vect
- __interrupt void ADC_ISR(void) {
- resultADC = ADCH;
- ADCSR &= ~(1<<ADIE); // disable interrupt
- Flag.newBTN = 1;
- }
|