ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Среда
24 апреля
957433 Топик полностью
Гудвин, волшебник (07.11.2019 15:27, просмотров: 169) ответил Ксения на Научите как :), у меня эта матрица в жизни первая.
Вот для Меги. Пульт ДУ радио на 48 кнопок. Особо глазастым занудам (задержка в функции прерывания) - прерывание это и есть основной функционал ;)  // atmega48v, компилятор CodeVision AVR // fuses настраиваем для работы внутреннего генератора 8 МГц, включен делитель на 8 - (частота тактирования 1 МГц). // матрица клавиатуры 8*6 // PORTD - строки // PORTC - колонки #include <mega48.h> #include <delay.h> #include <sleep.h> /* // эта отладочная фишка имеется только в моем stk500 клоне void init_debug(void) { PORTB=0x00; DDRB=0x38; PORTB.3=1; // сигнал MOSI программатора - используется как SS delay_ms(1); PORTB.3=0; delay_ms(1); } void putchar( char c) { unsigned char n; for (n=0;n<8;n++) { if (c & 1) PORTB.4=1; // сигнал MISO программатора - данные else PORTB.4=0; PORTB.5 =0; // сигнал SCK программатора - clock delay_us(100); PORTB.5 =1; delay_us(100); c=c>>1; } } */ void imp_led(void) // мигнем одним из светодиодов (PORTB.5) { PORTB.5 = 1; delay_ms(3); PORTB.5 = 0; // PORTB.4 = 1; // delay_ms(5); // PORTB.4 = 0; // PORTB.3 = 1; // delay_ms(5); // PORTB.3 = 0; } void send_byte(char b) // пошлем байт в порт (PORTB.7) - "модулятор" передатчика { char i; for (i=0;i<8;i++) { if (b & 1) { PORTB.7=1; delay_us(1000); PORTB.7=0; delay_us(1000); } else { PORTB.7=1; delay_us(500); PORTB.7=0; delay_us(500); } b=b>>1; } } void send_cod(unsigned char cod) // пошлем код в COM порт 0x0,0x0, - преамбула для синхронизации // 0xE6, - синхпробайт // <код>,<инверсия кода>, - код // 0x6E, 0x0 - конец пакета { PORTB.6=1; // порт (PORTB.6) включим питание передатчика delay_ms(1); // ждем 1мс для фиксации PLL передатчика send_byte(0); send_byte(0); send_byte(0); send_byte(0); send_byte(0); send_byte(0); send_byte(0); send_byte(0xE6); send_byte(cod); send_byte(~(cod)); send_byte(0x6E); send_byte(0); PORTB.6=0; // порт (PORTB.6) вЫключим питание передатчика } // Pin change 16-23 interrupt service routine interrupt [PCINT2] void pin_change_isr2(void) { unsigned char i; unsigned char b; volatile unsigned char cod; delay_ms(5); // антидребезг b=PIND; if(b == 0xFF) return; // прерывание было при отпускании кнопки - выходим без обработки for (i=0;i<8;i++) { if (!(b & 1)) break; b=b>>1; } cod=i; PORTD = 0; // меняем порты D и С местами DDRD = 0xFF; DDRC = 0; PORTC = 0x7F; delay_ms(5); // антидребезг b=PINC; for (i=0;i<6;i++) { if (!(b & 1)) break; b=b>>1; } DDRD=0x00; // возвращаем порты D и С в исходное состояние PORTD=0xFF; PORTC=0x00; DDRC=0x7F; cod=(i*8)+cod; cod+=1; // чтобы код начинался с единицы //putchar(cod); // отладочный вывод в отладчик stk500 lab1: send_cod(cod); imp_led(); if ((cod==12) || (cod==14)) // кнопки громкости - автоповтор { delay_ms(100); if (!(PIND==0xFF)) goto lab1; // повторяем пока нажата кнопка } PCIFR=0x04; // чистим флаг прерывания перед выходом } //////////////////////////////////////////////////////////////////////////////////////// void main(void) { PORTB=0x00; DDRB=0xFF; PORTC=0x00; DDRC=0x7F; PORTD=0xFF; DDRD=0x00; // Interrupt on any change on pins PCINT16-23: On EICRA=0x00; EIMSK=0x00; PCICR=0x04; PCMSK2=0xFF; PCIFR=0x04; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; ADCSRB=0x00; // int_debug(); // Global enable interrupts #asm("sei") while (1) { sleep_enable(); // здесь просто спим. Вся обработка в прерывании powerdown(); }; }