Код:
/*******************************************************
This program was created by the CodeWizardAVR V3.51
Automatic Program Generator
© Copyright 1998-2023 Pavel Haiduc, HP InfoTech S.R.L.
http://www.hpinfotech.ro
Project : Kangoo - KEY12
Version : 1.01
Date : 03.07.2023
Author : Stalker_W
Company : Визг&Вопли
Comments: Переходник с разъёма Renault Kangoo I на контакты Key1 Key2 магнитолы
Ножка Порт - номер Зарезервирован Вход выход Моё использование
9 PB6 XTAL1 Вых 6 коричневый, опрос энкодер
10 PB7 XTAL2 Вых 4 красный, опрос 4 5 3
11 PD5 Вых 5 чёрный, опрос 1 2 6
12 PD6 Вх 1 жёлтый, линия 1 4 энк1
13 PD7 Вх 3 зелёный, линия 2 5 энк2
14 PB0 Вх 2 голубой, линия 6 3 энк3
18 PB4 Вых Encoder up
19 PB5 OC1A Вых Encoder down
23 PC0 ADC0 Вых Кн 1
24 PC1 Вых Кн 2
25 PC2 Вых Кн 3
26 PC3 Вых Кн 4
27 PC4 Вых Кн 5
28 PC5 Вых Кн 6
Chip type : ATmega8
Program type : Application
AVR Core Clock frequency: 1,000000 MHz
внутренний генератор
Memory model : Small
External RAM size : 0
Data Stack size : 256
Фьюзы PonyProg2000 галочки: Bodlevel
Boden
!!! Lock2 !!! (в последнюю очередь)
!!! Lock1 !!! (в последнюю очередь)
SUT0
CKSEL3
CKSEL2
CKSEL1
Конструктор фьюзов http://radioshemi.ucoz.ru/FUSI/calc.html?part=ATmega8
*******************************************************/
// I/O Registers definitions
#include <mega8.h>
#include <delay.h>
// Declare your global variables here
//==================== переопределения =========================
#define key1_vkl PORTC.0 = 1 //подача напряжения на контакт в сторону входа магнитолы
#define key2_vkl PORTC.1 = 1
#define key3_vkl PORTC.2 = 1
#define key4_vkl PORTC.3 = 1
#define key5_vkl PORTC.4 = 1
#define key6_vkl PORTC.5 = 1
#define key_encod_up PORTB.4 = 1
#define key_encod_down PORTB.5 = 1
#define shina1_vkl PORTB.7 = 1 //подача опроса на провод 4 - кнопки 4 5 3
#define shina1_otkl PORTB.7 = 0
#define shina2_vkl PORTD.5 = 1 //подача опроса на провод 5 - кнопки 1 2 6
#define shina2_otkl PORTD.5 = 0
#define shina3_vkl PORTB.6 = 1 //подача опроса на провод 6 - энкодер
#define shina3_otkl PORTB.6 = 0
#define liniya1 PIND.6 //читаем провод 1 кнопки 1 4 энк1
#define liniya2 PIND.7 //читаем провод 3 кнопки 2 5 энк2
#define liniya3 PINB.0 //читаем провод 2 кнопки 6 3 энк3
// ============ глобальные константы =========================
const unsigned char vrema_key = 2; // НЕ МЕНЬШЕ 1 длительность эмуляции нажатия кнопки энкодера ( х 65мс)
const unsigned char pause_front = 3; // пауза между подачей тестового напряжения и считыванием кнопки мс
// ============= глобальные переменные ========================
unsigned char enkoder_otdacha = 0; //отдаём энкодер, больше нуля остаток циклов
unsigned char knopka = 0; //что читаем
unsigned char knopka_old = 0; //что реально отдаём
unsigned char enkoder; //читаем энкодер
unsigned char enkoder_old; //предыдущее состояние энкодера
//================ процедуры прерываний =======================
// Timer 0 overflow interrupt service routine
//как-бы основной цикл. Срабатывает каждые 65 мс
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
if (enkoder_otdacha == 0)
{
//читаем кнопки
knopka = 0;
shina1_vkl;
delay_ms(pause_front);
if (liniya1) {knopka = 4;};
if (liniya2) {knopka = 5;};
if (liniya3) {knopka = 3;};
shina1_otkl;
shina2_vkl;
delay_ms(pause_front);
if (liniya1) {knopka = 1;};
if (liniya2) {knopka = 2;};
if (liniya3) {knopka = 6;};
shina2_otkl;
//читаем энкодер
shina3_vkl;
enkoder = 0;
delay_ms(pause_front);
if ((liniya1) & (!liniya2) & (!liniya3)) {enkoder = 1;};
if ((liniya2) & (!liniya1) & (!liniya3)) {enkoder = 2;};
if ((liniya3) & (!liniya1) & (!liniya2)) {enkoder = 3;};
shina3_otkl;
if ((enkoder != enkoder_old) & (enkoder > 0))
{ //энкодер переключился
if (enkoder_old == 1)
{
if (enkoder == 2) {knopka = 8;} else {knopka = 7;};
};
if (enkoder_old == 2)
{
if (enkoder == 3) {knopka = 8;} else {knopka = 7;};
};
if (enkoder_old == 3)
{
if (enkoder == 1) {knopka = 8;} else {knopka = 7;};
};
enkoder_otdacha = vrema_key - 1;
enkoder_old = enkoder;
};
//нвчинаем раздавать
if (knopka != knopka_old)
{ //новое нажатие
PORTC.0 = 0; //выключаем всё
PORTC.1 = 0;
PORTC.2 = 0;
PORTC.3 = 0;
PORTC.4 = 0;
PORTC.5 = 0;
PORTB.4 = 0;
PORTB.5 = 0;
switch (knopka)
{
case 1: key1_vkl;
break;
case 2: key2_vkl;
break;
case 3: key3_vkl;
break;
case 4: key4_vkl;
break;
case 5: key5_vkl;
break;
case 6: key6_vkl;
break;
case 7: key_encod_down;
break;
case 8: key_encod_up;
break;
};
knopka_old = knopka;
};
}
else {enkoder_otdacha--; //счётчик времени отдачи энкодера
//читаем энкодер
shina3_vkl;
enkoder = 0;
delay_ms(pause_front);
if ((liniya1) & (!liniya2) & (!liniya3)) {enkoder = 1;};
if ((liniya2) & (!liniya1) & (!liniya3)) {enkoder = 2;};
if ((liniya3) & (!liniya1) & (!liniya2)) {enkoder = 3;};
shina3_otkl;
if ((enkoder != enkoder_old) & (enkoder > 0))
{ //энкодер переключился
enkoder_old = enkoder;
};
};
} //конец прерывания
void main(void)
{
// Declare your local variables here
// Input/Output PORTs initialization
// PORT B initialization
// Function: Bit7=Out Bit6=Out Bit5=Out Bit4=Out Bit3=In Bit2=In Bit1=In Bit0=In
DDRB=(1<<DDB7) | (1<<DDB6) | (1<<DDB5) | (1<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=0 Bit6=0 Bit5=0 Bit4=0 Bit3=T Bit2=T Bit1=T Bit0=T
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);
// PORT C initialization
// Function: Bit6=In Bit5=Out Bit4=Out Bit3=Out Bit2=Out Bit1=Out Bit0=Out
DDRC=(0<<DDC6) | (1<<DDC5) | (1<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0);
// State: Bit6=T Bit5=0 Bit4=0 Bit3=0 Bit2=0 Bit1=0 Bit0=0
PORTC=(0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);
// PORT D initialization
// Function: Bit7=In Bit6=In Bit5=Out Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<<DDD7) | (0<<DDD6) | (1<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=0 Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
// Timer/Counter 0 initialization
// Clock source: System Clock
TCCR0=0x00; //стартуем без прерывания чтоб считать энкодер
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0<<AS2;
TCCR2=(0<<PWM2) | (0<<COM21) | (0<<COM20) | (0<<CTC2) | (0<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<TOIE0);
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
// USART initialization
// USART disabled
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) | (0<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
SFIOR=(0<<ACME);
// ADC initialization
// ADC disabled
ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADFR) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);
// SPI initialization
// SPI disabled
SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);
// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);
//типа основной код Таймер прерывание временно выключаем
PORTC.0 = 0; //выключаем всё
PORTC.1 = 0;
PORTC.2 = 0;
PORTC.3 = 0;
PORTC.4 = 0;
PORTC.5 = 0;
PORTB.4 = 0;
PORTB.5 = 0;
//инициализация энкодера.
shina3_vkl;
enkoder_old = 1;
delay_ms(pause_front);
//if (liniya1 == 1) {enkoder_old = 1}; и так уже 1
if (liniya2 == 1) {enkoder_old = 2;};
if (liniya3 == 1) {enkoder_old = 3;};
shina3_otkl;
//старт таймера прерывания
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 3,906 kHz
TCCR0=(1<<CS02) | (0<<CS01) | (0<<CS00);
TCNT0=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (1<<TOIE0);
// Globally enable interrupts
#asm("sei")
while (1)
{
//основной цикл пуст. Всё работает циклично на прерывании Timer/Counter 0
}
}