Народ хелп плиз. Написал программу в симуляторе AVRstudio при шаговой отладке все хорошо принимает данные с пульта, а вот в железе начинаются проблемы в сом-порт гонит в основном одни "1". Использую следующий алгоритм. изначально нога контроллера притянута к +5в 1. Разрешаю прерывания по изменению уровня сигнал заведен на PD2 2. при первом прерывании (спаду) запускаю таймер 3. при появлении высокого логического уровня снова генерируется прерывание считываю значение таймера 4. Проверяю длину импульса 4а. Если импульс длинный то однозначно я нахожусь на середине бита и можно производить считывание, считываю значение порта ложу в переменную 4б Если импульс короткий проверяю где нахожусь: если на границе битов то ничего не считываю просто запоминаю что граница, если на середине бита то считываю значение порта ложу в перемененную. Ниже привожу кусок программы приема и обработки сигнала, пробовал варьировать задержки при считывании значения порта ни помогло, с начало думал может помехи какие возникают.
#include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #include <avr/signal.h> volatile int v,r,p,u=0, oldp,gr; uint16_t j,k,f,x,y1,y2,pult; uint8_t c,a,e,q,m=0,m1; ISR (INT0_vect) { r++;//переменная r служит для подсчета для того что бы узнать где находимся на середине или на границе при коротких импульсях TCCR0=(1<<CS02);//запускаем таймер p=TCNT0;//считываем заначение таймера TCNT0=0;// if(r==2)// если находимся на середине бита то запоминаем предыдущее значение таймера { oldp=p; r=0; } } //прерывание по приему USART ISR (USART_RXC_vect) { v=UDR; _delay_us(5); UDR=v; } // инициализация настроек void inic() {
DDRC=0xFF; DDRB=0xFF; DDRB&=~(1<<0); PORTB=0; PORTB|=(1<<3); //натсраиваем скорость 19200 бот/c UBRRL=25; UBRRH=0; UCSRA=0; // настраиваем приемник передатчик UCSRB=(1<<RXEN) |(1<<TXEN)|(1<<RXCIE); // 8 бит данных UCSRC=(1<<UCSZ0) |(1<<UCSZ1)|(1<<URSEL); MCUCR=(1<<ISC00); GICR=(1<<INT0); } void main() { inic(); while(1) { sei(); while(1) { if ((p>0x18)&&(p<0x1F))// если интервал короткий { if(p==oldp)//проверяем где находимся на границе или на середине бита если на середине бита то gr=1 { gr=1; oldp=0; } if (((p>0x18)&&(p<0x1F))&&gr)// если интервал короткий и мы находимся на середине то можно считывать значение порта {
gr=0; p=0; j=PIND&(1<<2); _delay_us(50); j=PIND&(1<<2); if(j) { while(!(UCSRA&(1<<UDRE))) {} pult|=(1<<u); UDR='1'; } if(!j) { while(!(UCSRA&(1<<UDRE))) {} pult&=~(1<<u); UDR='0'; } u++;// стчик для складирования битов } p=0;
} //динный импульс if ((p>0x37) && (p<0x3B))// если импульс длинный то мы однозначно на середине считываем значение порта { r=0; gr=0; p=0; j=PIND&(1<<2); _delay_us(50); j=PIND&(1<<2); if(j) { while(!(UCSRA&(1<<UDRE))) {} UDR='1'; pult|=(1<<u); } if(!j) { while(!(UCSRA&(1<<UDRE))) {} pult&=~(1<<u); UDR='0'; } u++; } if(u==14) { u=0; while(!(UCSRA&(1<<UDRE))) {} UDR='E'; } } } }
|