#include #include #include "lcd.h" #include "usart.h" #include "i2c.h" #include "rtc.h" #define _XTAL_FREQ 4000000 #define STATE TRISC0 #define PIN RC0 #define IRpin RB0 #define right RB1 #define left RB2 #define ebutton RB5 volatile static bit volume_flag = 0; volatile static bit update_flag = 0; volatile static bit volume_status = 0; volatile static bit encoder_flag = 0; volatile static bit button_flag = 0; volatile static bit exit_status = 0; volatile static bit exit_flag = 0; volatile static bit mute_status = 0; volatile static bit bass_flag = 0; volatile static bit bass_status = 0; volatile static bit treble_flag = 0; volatile static bit treble_status = 0; volatile static bit time_flag = 0; volatile static bit time_status = 0; volatile static bit direction; //1 - rising, 0 - falling volatile unsigned char IRbyte; //принятый байт volatile bit togglebit; //бит переключалка volatile bit oldtogglebit; //хранение старого значения бита-переключалки volatile bit buffer; volatile unsigned char bytecount; volatile unsigned char i=0; volatile unsigned char EncData; volatile unsigned char itemp =0; volatile unsigned char volume = 50; volatile char bass = 0; volatile char treble = 0; char temperature = 25; unsigned char temp_drob = 0; unsigned char sign = 0; unsigned char upcount = 0; unsigned char downcount = 0; const unsigned char digits[10] = { 0b00110000, //0 0b00110001, //1 0b00110010, //2 0b00110011, //3 0b00110100, //4 0b00110101, //5 0b00110110, //6 0b00110111, //7 0b00111000, //8 0b00111001, //9 }; __CONFIG(WDTDIS & UNPROTECT & LVPDIS & HS); void StartTimer(void); static bit INIT(void); void TX(unsigned char cmd); unsigned char RX(); void get_temp(); void printTemp(); void display_tt(); void menu(unsigned char i); void pointer_time(unsigned char i); display_digit(unsigned char digit, unsigned char pos); setup_volume(unsigned char value); void mute(); void bass_setup(unsigned char value); void treble_setup(unsigned char value); void setup_time(); void main() { static bit up = 0; static bit down = 0; unsigned char OldEncData = 3; unsigned char IRcom = 0; static bit muteIR = 0; __delay_ms(200); TRISB = 0x00; TRISD = 0x00; init_comms(); // инициализируем уарт I2CInit(); // инициализруем I2C lcd_init(); // инициализруем дисплей display_tt(); // отображаем дежурную функцию TMR2 = 0x01; //стартуем с 1 PR2 = 0xFF; //считаем по 255*16 мкс T2CKPS0 = 1; T2CKPS1 = 1; //1 делитель не делит входную частоту TOUTPS2 = 1; TOUTPS1 = 1; TOUTPS3 = 1; TOUTPS0 = 1; //2 делитель делит на 5 GIE = 1; // глобальные прерывания PEIE = 1; // прерывания перефирии //INTE = 1; RBIE = 1; TRISB1 = 1; // преднастройка энкодера TRISB2 = 1; TRISB0 = 1; TRISB5 = 1; TMR2IE = 1; TMR2ON = 1; // Запуск таймера! OPTION = 0b11010001; // Настройки таймера TNR0 TMR0 = 0; T0IE = 1; buffer = 0; IRbyte = 0; bytecount = 0; direction = 0; INTEDG = 0; INTE = 1; printf("\r\nStarting Done!"); while (1) { //---------------Обработка ИК команд--------------- if (bytecount>13) { GIE = 0; //printf("\r\nToggle is %d", togglebit); if (oldtogglebit != togglebit) { printf("\r\nPressed button is %d", IRbyte); switch(IRbyte) { case 10 : if (!muteIR) { itemp = 0; volume_flag = 0; mute_status = 0; mute(); muteIR = 1; } else { TRISB2 = 1; TRISB1 = 1; volume_flag = 1; bass_flag = 0; treble_flag = 0; menu(0); muteIR = 0; } break; case 16 : IRcom = 16; //right break; case 17 : IRcom = 17; //left break; case 13 : IRcom = 13; //Enter break; case 32 : IRcom = 32; //Up break; case 33 : IRcom = 33; break; case 41 : IRcom = 41; //exit break; case 43 : IRcom = 43; //volume+ break; case 44 : IRcom = 44; //volume- break; }//17 left, 16 right } IRbyte = 0; bytecount=0; INTEDG = 0; buffer = 0; oldtogglebit = togglebit; GIE = 1; } //---------------Конец обработки IR команд--------------- /* Обновление дежурной информации на дисплее */ if (update_flag) { GIE = 0; TMR2ON = 0; display_tt(); update_flag = 0; GIE = 1; TMR2ON = 1; } /* --------End of procedure------------------- */ /* Обработка вращения энкодера */ if (OldEncData != EncData) { switch (OldEncData) { case 0 : if (EncData == 1) {upcount++; downcount=0; } if (EncData == 2) {downcount++; upcount = 0; } break; case 1 : if (EncData == 3) {upcount++; downcount=0; } if (EncData == 0) {downcount++; upcount = 0; } break; case 2 : if (EncData == 0) {upcount++; downcount=0; } if (EncData == 3) {downcount++; upcount = 0; } break; case 3 : if (EncData == 2) {upcount++; downcount=0; } if (EncData == 1) {downcount++; upcount = 0; } break; } OldEncData = EncData; } if (upcount >= 4) { up = 1; upcount = 0; } if (downcount >= 4 ) { down = 1; downcount = 0; } /* --------End of procedure------------------- */ if ((IRcom == 13)&&(!volume_flag)) //Вход в меню с пульта { volume_flag = 1; bass_flag = 0; treble_flag = 0; menu(0); IRcom = 0; } if ((exit_flag)||(IRcom == 41)||((IRcom == 13)&&(exit_status))) { //выход из меню IRcom = 0; display_tt(); exit_flag = 0; } if (((time_flag)&&(!time_status))||((IRcom == 13)&&(time_status))) //Вход в процедуру установку времени { GIE = 0; time_flag=0; IRcom = 0; setup_time(); } /* Регулировка уровня громкости */ if (((up)&&(!volume_flag)&&(!bass_flag)&&(!treble_flag))||(IRcom == 43)) { if (volume<100) volume++; setup_volume(volume); up = 0; IRcom = 0; } if (((down)&&(!volume_flag)&&(!bass_flag)&&(!treble_flag))||(IRcom == 44)) { if (volume>0) volume--; setup_volume(volume); down = 0; IRcom = 0; } /* ------------End of procedure------------------- */ /* Басы */ if ((IRcom == 13)&&(bass_status)) { itemp = 0; volume_flag = 0; bass_flag = 1; bass_status = 0; IRcom = 0; } if (((down)&&(bass_flag))||((IRcom == 17)&&(bass_flag))) { bass--; bass_setup(bass); down = 0; IRcom = 0; } if (((up)&&(bass_flag))||((IRcom == 16)&&(bass_flag))) { bass++; bass_setup(bass); up = 0; IRcom = 0; } /* ------------End of procedure------------------- */ /* Тембр */ if ((IRcom == 13)&&(treble_status)) { itemp = 0; volume_flag = 0; treble_flag = 1; treble_status = 0; IRcom = 0; } if (((down)&&(treble_flag))||((IRcom == 17)&&(treble_flag))) { treble--; treble_setup(treble); down = 0; IRcom = 0; } if (((up)&&(treble_flag))||((IRcom == 16)&&(treble_flag))) { treble++; treble_setup(treble); up = 0; IRcom = 0; } /* ------------End of procedure------------------- */ /* Скроллинг пунктов меню */ if (((up)&&(volume_flag)&&(!bass_flag)&&(!treble_flag))||((IRcom == 33)&&(volume_flag)&&(!bass_flag)&&(!treble_flag))) { if (itemp < 7) { if (itemp<6) { itemp++; exit_status = 0; } else { itemp = 7; exit_status = 1; } } else { itemp = 1; exit_status = 0; } IRcom = 0; menu(itemp); up = 0; } if (((down)&&(volume_flag)&&(!bass_flag)&&(!treble_flag))||((IRcom == 32)&&(volume_flag)&&(!bass_flag)&&(!treble_flag))) { if (itemp > 1 ) { itemp--; exit_status = 0; } else { itemp = 7; exit_status = 1; } IRcom = 0; menu(itemp); down = 0; } /* ------------End of procedure------------------- */ if (itemp == 2) volume_status = 1; else volume_status = 0; if (itemp == 1) mute_status = 1; else mute_status = 0; if (itemp == 3) bass_status = 1; else bass_status = 0; if (itemp == 4) treble_status = 1; else treble_status = 0; if (itemp == 5) time_status = 1; else time_status = 0; /* ------------End of procedure------------------- */ /* Статусные переменные для скролла меню */ /*switch (itemp) { case 1 : volume_status = 0; exit_status = 0; mute_status = 1; break; case 2 : mute_status = 0; bass_status = 0; volume_status = 1; break; case 3 : volume_status = 0; treble_status = 0; bass_status = 1; break; case 4 : bass_status = 0; time_status = 0; treble_status = 1; break; case 5 : treble_status = 0; exit_status = 0; time_status = 1; break; } /* ------------End of procedure------------------- */ } //End of while(1) } //End of main unsigned int update = 0; interrupt isr() { //-------------------IR decoding------------------- if (INTF) { if (bytecount<1) { direction = 1; INTEDG = 1; StartTimer(); bytecount++; } else { direction = !direction; //if (bytecount<3) { //if (((direction)&&(buffer))||(!(direction)&&!(buffer))) if (direction==buffer) { StartTimer(); bytecount++; } // } INTEDG = direction; } INTF = 0; } else { if (TMR1IF) { buffer = IRpin; TMR1ON = 0; TMR1IF = 0; if (bytecount==2) togglebit = buffer; if ((bytecount>7)&&(bytecount<14)) //забираем только команду { IRbyte <<= 1; IRbyte |= buffer; } } } //--------------------End IR--------------------- if (RBIF) { GIE = 0; __delay_ms(100); if (!ebutton) { if ((!volume_flag)&&(!time_status)&&(!exit_status)&&(!time_flag)) { //Вход в меню TRISB2 = 1; TRISB1 = 1; volume_flag = 1; bass_flag = 0; treble_flag = 0; menu(0); } if (exit_status) { //Выходим из меню exit_flag = 1; exit_status = 0; volume_flag = 0; } if (volume_status) { //Регулировка громкости itemp = 0; volume_flag = 0; volume_status = 0; } if (mute_status) { //mute itemp = 0; volume_flag = 0; mute_status = 0; mute(); } if (bass_status) { //басы itemp = 0; volume_flag = 0; bass_status = 0; bass_flag = 1; } if (treble_status) { //тембр itemp = 0; volume_flag = 0; treble_status = 0; treble_flag = 1; } if (time_status) { //Установка времени itemp = 0; time_status = 0; time_flag = 1; } } RBIF = 0; GIE = 1; } if (TMR2IF) { //Таймер для дежурной функции update++; //printf("\r\n\update is %d", update); //printf("\r\n\update flag %d", update_flag); if (update > 600) { GIE = 0; TMR2ON = 0; update_flag = 1; update = 0; } TMR2 = 0x01; T2CKPS0 = 1; T2CKPS1 = 1; //1 делитель не делит входную частоту TOUTPS2 = 1; TOUTPS1 = 1; TOUTPS3 = 1; TOUTPS0 = 1; //2 делитель делит на 5 TMR2IF = 0; //сброс флага } if (T0IF) { //Таймер для энкодера TMR0 = 0; EncData = PORTB & 0b00000110; EncData >>= 1; T0IF = 0; } } /* ---------------------------------------------Функции--------------------------------------------*/ void StartTimer(void) { T1CKPS1 = 0; T1CKPS0 = 0; T1OSCEN = 0; //выключаем внутренний генератор TMR1CS = 0; // Fosc/4 TMR1IE = 1; // прерывание по переполнению TMR1 TMR1H = 0b11111011; TMR1L = 0b00010110; //1.257ms //TMR1H = 0b00000000; TMR1L = 0x00; TMR1ON = 1; // включаем таймер } /* 1-wire functions */ static bit INIT(void){ static bit b; STATE = 1; STATE = 0; __delay_us(500); STATE = 1; __delay_us(65); b = PIN; __delay_us(450); return b; } void TX(unsigned char cmd){ unsigned char temp = 0; unsigned char i = 0; temp = cmd; for (i=0;i<8;i++) { if (temp&0x01) { STATE = 0; __delay_us(5); STATE = 1; __delay_us(70); } else { STATE = 0; __delay_us(70); STATE = 1; __delay_us(5); } temp >>= 1; } } unsigned char RX() { unsigned char d = 0; unsigned char i = 0; for (i=0;i<8;i++){ STATE = 0; __delay_us(6); STATE = 1; __delay_us(4); d>>=1; if (PIN == 1) d |= 0x80; //printf("\r\n %d", d); __delay_us(60); } return d; } void get_temp() { static bit init; unsigned char temp1; unsigned char temp2; init = INIT(); if (!init) { TX(0xCC); TX(0x44); __delay_ms(150); __delay_ms(150); __delay_ms(150); __delay_ms(150); __delay_ms(150); } else printf("bug"); init = INIT(); if (!init) { TX(0xCC); TX(0xBE); temp1 = RX(); temp2 = RX(); } temp_drob = temp1 & 0b00001111; //Записываем дробную часть в отдельную переменную temp_drob = ((temp_drob*6)+2)/10; //Переводим в нужное дробное число temp1 >>= 4; sign = temp2 & 0x80; temp2 <<= 4; temp2 &= 0b01110000; temp2 |= temp1; if (sign) { temperature = 127-temp2; temp_drob = 10 - temp_drob; } else temperature = temp2; } void printTemp() { get_temp(); //printf("\r\ntemperatura -- "); if (temperature<10) { if (sign) printf("\r\n2020"); else printf("\r\n2010"); } else { if (sign) printf("\r\n202"); else printf("\r\n201"); } printf("%d", temperature); __delay_ms(20); if (temp_drob<10) printf("\r\n2030"); else printf("\r\n203"); printf("%d", temp_drob); __delay_ms(20); } void display_tt() { //дежурная функция отображения информации на LCD unsigned char d; get_temp(); //берем значение температуры LCD_RS = 0; lcd_write(0b00001100); __delay_us(100); lcd_clear(); d = ReadHour(); lcd_goto(0x05); lcd_putch(digits[d/10]); //выводим значение часов d = d - ((d/10)*10); lcd_putch(digits[d]); d = 0b00111010; lcd_putch(d); d = ReadMin(); lcd_putch(digits[d/10]); //выводим значение минут d = d - ((d/10)*10); lcd_putch(digits[d]); lcd_goto(0x44); if (!sign) lcd_putch(0b00101011); else lcd_putch(0b10110000); //знак температуры d=temperature/10; lcd_putch(digits[d]); //целое значение температуры d=temperature-((temperature/10)*10); lcd_putch(digits[d]); d = 0b00101110; lcd_putch(d); //точка lcd_putch(digits[temp_drob]); //вывод дробного значения d = 0b11011111; lcd_putch(d); //градус d = 0b01000011; lcd_putch(d); //С } void menu(unsigned char i) { lcd_clear(); LCD_RS = 0; lcd_write(0b00001100); __delay_us(100); switch (i) { case 0 : lcd_goto(0x00); lcd_puts("Menu:"); lcd_goto(0x08); lcd_puts("1.Mute"); lcd_goto(0x48); lcd_puts("2.Volume"); break; case 1 : lcd_goto(0x00); lcd_puts("Menu:"); lcd_goto(0x07); lcd_putch(0b00111110); lcd_goto(0x08); lcd_puts("1.Mute"); lcd_goto(0x48); lcd_puts("2.Volume"); break; case 2 : lcd_goto(0x00); lcd_puts("Menu:"); lcd_goto(0x08); lcd_puts("1.Mute"); lcd_goto(0x47); lcd_putch(0b00111110); lcd_goto(0x48); lcd_puts("2.Volume"); break; case 3 : lcd_goto(0x00); lcd_puts("Menu:"); lcd_goto(0x07); lcd_putch(0b00111110); lcd_goto(0x08); lcd_puts("3.Bass"); lcd_goto(0x48); lcd_puts("4.Treble"); break; case 4 : lcd_goto(0x00); lcd_puts("Menu:"); lcd_goto(0x08); lcd_puts("3.Bass"); lcd_goto(0x47); lcd_putch(0b00111110); lcd_goto(0x48); lcd_puts("4.Treble"); break; case 5 : lcd_goto(0x00); lcd_puts("Menu:"); lcd_goto(0x07); lcd_putch(0b00111110); lcd_goto(0x08); lcd_puts("5.Time"); lcd_goto(0x48); lcd_puts("6.StBy"); break; case 6 : lcd_goto(0x00); lcd_puts("Menu:"); lcd_goto(0x08); lcd_puts("5.Time"); lcd_goto(0x47); lcd_putch(0b00111110); lcd_goto(0x48); lcd_puts("6.StBy"); break; case 7 : lcd_goto(0x00); lcd_puts("Menu:"); lcd_goto(0x07); lcd_putch(0b00111110); lcd_goto(0x08); lcd_puts("7.Exit"); break; } } void pointer_time(unsigned char i) { switch (i) { case 0 : lcd_goto(0x00); lcd_putch(0b00111110); lcd_goto(0x40); lcd_putch(0b00100000); lcd_goto(0x09); lcd_putch(0b00100000); lcd_goto(0x49); lcd_putch(0b00100000); break; case 1 : lcd_goto(0x00); lcd_putch(0b00100000); lcd_goto(0x40); lcd_putch(0b00111110); lcd_goto(0x09); lcd_putch(0b00100000); lcd_goto(0x49); lcd_putch(0b00100000); break; case 2 : lcd_goto(0x00); lcd_putch(0b00100000); lcd_goto(0x40); lcd_putch(0b00100000); lcd_goto(0x09); lcd_putch(0b00111110); lcd_goto(0x49); lcd_putch(0b00100000); break; case 3 : lcd_goto(0x00); lcd_putch(0b00100000); lcd_goto(0x40); lcd_putch(0b00100000); lcd_goto(0x09); lcd_putch(0b00100000); lcd_goto(0x49); lcd_putch(0b00111110); break; } } display_digit(unsigned char digit, unsigned char pos){ if (digit<100) lcd_goto(pos); lcd_putch(digits[digit/10]); //выводим значение часов digit = digit - ((digit/10)*10); lcd_putch(digits[digit]); } setup_volume(unsigned char value) { lcd_clear(); LCD_RS = 0; lcd_write(0b00001100); __delay_us(100); lcd_goto(0x00); lcd_puts("Volume"); if (value<100) display_digit(value, 0x0D); else { lcd_goto(0x0C); lcd_putch(0b00110001); lcd_putch(0b00110000); lcd_putch(0b00110000); } lcd_goto(0x0F); lcd_putch(0b00100101); lcd_goto(0x40); lcd_putch(0b01111110); lcd_goto(0x46); if (value == 0) lcd_puts("----------"); if ((value > 0) && (value <= 10)) lcd_puts("O---------"); if ((value > 10) && (value <= 20)) lcd_puts("OO--------"); if ((value > 20) && (value <= 30)) lcd_puts("OOO-------"); if ((value > 30) && (value <= 40)) lcd_puts("OOOO------"); if ((value > 40) && (value <= 50)) lcd_puts("OOOOO-----"); if ((value > 50) && (value <= 60)) lcd_puts("OOOOOO----"); if ((value > 60) && (value <= 70)) lcd_puts("OOOOOOO---"); if ((value > 70) && (value <= 80)) lcd_puts("OOOOOOOO--"); if ((value > 80) && (value < 100)) lcd_puts("OOOOOOOOO-"); if (value == 100) lcd_puts("OOOOOOOOOO"); } void mute() { TRISB2 = 0; TRISB1 = 0; lcd_clear(); lcd_goto(0x06); lcd_puts("MUTE"); } void bass_setup(unsigned char value) { lcd_clear(); lcd_goto(0x00); lcd_puts("Bass Setup:"); display_digit(value, 0x0D); } void treble_setup(unsigned char value) { lcd_clear(); lcd_goto(0x00); lcd_puts("Treble Setup:"); display_digit(value, 0x0D); } void setup_time() { unsigned char temp = 0; char i; static bit exit = 0; static bit shr = 0; static bit smin = 0; static bit ssec = 0; unsigned char OldEncData = 3; static bit smenu = 0; i = 0; exit = 0; smenu = 0; temp = ReadHour(); lcd_clear(); lcd_goto(0x01); lcd_puts("Hr:"); lcd_goto(0x00); lcd_putch(0b00111110); display_digit(temp, 0x05); temp = ReadMin(); lcd_goto(0x41); lcd_puts("Min:"); display_digit(temp, 0x45); temp = ReadSeconds(); lcd_goto(0x0A); lcd_puts("Sec:"); display_digit(temp, 0x0E); lcd_goto(0x4A); lcd_puts("Exit?"); while(!exit) { __delay_ms(1); EncData = PORTB & 0b00000110; EncData >>= 1; if (OldEncData != EncData) { switch (OldEncData) { case 0 : if (EncData == 1) {upcount++; downcount=0; } if (EncData == 2) {downcount++; upcount = 0; } break; case 1 : if (EncData == 3) {upcount++; downcount=0; } if (EncData == 0) {downcount++; upcount = 0; } break; case 2 : if (EncData == 0) {upcount++; downcount=0; } if (EncData == 3) {downcount++; upcount = 0; } break; case 3 : if (EncData == 2) {upcount++; downcount=0; } if (EncData == 1) {downcount++; upcount = 0; } break; } OldEncData = EncData; } if (!smenu) { if (upcount >= 4) { if (i<3) i++; else i = 0; upcount = 0; } if (downcount >= 4 ) { if (i>0) i--; else i = 4; downcount = 0; } pointer_time(i); } else { if (upcount >= 4) { temp++; upcount = 0; } if (downcount >= 4 ) { temp--; downcount = 0; } if (shr) { if (temp >= 24) temp = 0; display_digit(temp, 0x05); i = 5; } if (smin) { if (temp >= 60) temp = 0; display_digit(temp, 0x45); i = 6; } if (ssec) { if (temp >= 60) temp = 0; display_digit(temp, 0x0E); i = 7; } } if (!ebutton) { __delay_ms(200); smenu = !smenu; switch (i) { case 0 : shr = 1; smin = 0; ssec = 0; temp = ReadHour(); lcd_goto(0x00); lcd_putch(0b00101010); break; case 1 : smin = 1; shr = 0; ssec = 0; temp = ReadMin(); lcd_goto(0x40); lcd_putch(0b00101010); break; case 2 : ssec = 1; shr = 0; smin = 0; temp = ReadSeconds(); lcd_goto(0x09); lcd_putch(0b00101010); break; case 3 : exit = 1; break; case 5 : SetHour(temp); shr = 0; i = 0; pointer_time(i); break; case 6 : SetMin(temp); smin = 0; i = 1; pointer_time(i); break; case 7 : SetSeconds(temp); ssec = 0; i = 2; pointer_time(i); break; } } } GIE = 1; } //большой длинный файл