logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[atmega8] [c] RC dwukanałowa proporcjonalna

maziu 06 Mar 2010 12:11 1065 0
REKLAMA
  • #1 7790635
    maziu
    Poziom 18  
    Ostatnio oprogramowałem sobie aparaturę RC dwukanałową proporcjonalną .

    Zasada działania :
    Wysyła 4 paczki 8 bitowe niosące informacje o synchronizacji, wybranym potku/serwie, o nastawie potka/serwa, sumę sprawdzającą adres i nastawę potka/serwa

    Problem zaczyna się w momencie zaniku sygnału na wejściu odbiornika ... Z założenia odbiornik powinien od razu ustawić serwa w pozycji 90 stopni (robi to dopiero po kilku sekundach od zaniku sygnału)

    W sytuacji odwrotnej kiedy w nadajniku zmienię kod a dokładniej adres potka na nieistniejący to wszystko działa poprawnie .

    Wniosek z tego taki że przy błędnym sygnale z nadajnika wszystko działa a przy jego braku działa z dużym opóźnieniem ...

    Czy może mnie ktoś naprowadzić ??

    //********************************************************************************
    //	NADAJNIK
    //	UART
    //********************************************************************************
    
    #include <avr/io.h>							// wejścia wyjścia 
    #include <util/delay.h>
    
    #ifndef F_CPU
    #define F_CPU 8000000						// częstotliwość zegara w Hz
    #endif
    
    #define BAUDRATE 1200						// prędkość transmisji
    #define UBRRVAL ((F_CPU/(BAUDRATE*16UL))-1)
    
    #define SYNC 0xAA							// sygnał synchronizacji 8bitów
    							
    //********************************************************************************
    //	INICJOWANIE UsART
    //********************************************************************************
    
    void USART(void)
    {
    	UBRRL = (uint8_t)UBRRVAL;	// ustawienie  prędkości transmisji 
    	UBRRH = (UBRRVAL>>8);					
    
    	UCSRC = (1<<URSEL)|
    			(0<<UMSEL)|
    			(0<<UPM1) |
    			(0<<UPM0) |			// ustawienie formatu ramki 
    			(0<<USBS) |			// 8bitów danych, 1bit stopu, brak synchronizacji
    			(0<<UCSZ2)|
    			(1<<UCSZ1)|
    			(1<<UCSZ0);		
    
    	UCSRB = (1<<TXEN);			// włączenie nadajnika i odbiornika
    }
    //********************************************************************************
    void USART_vSendByte(uint8_t u8Data)
    {
        while((UCSRA&(1<<UDRE)) == 0);
        UDR = u8Data;  
    }
    
    
    void Send_Packet(uint8_t addr, uint8_t cmd)
    {
    	USART_vSendByte(SYNC);				// synchronizacja 8bit	
    	USART_vSendByte(addr);				// adres 8bit
    	USART_vSendByte(cmd);				// dane 8bit
    	USART_vSendByte((addr+cmd));		// suma adresu i danych 8bit
    }
    
    
    void delayms(uint8_t t)					//delay in ms
    {
    uint8_t i;
    for(i=0;i<t;i++)
    	_delay_ms(1);
    }
    
    //********************************************************************************
    //	INICJOWANIE PRZETWORNIKA AC
    //********************************************************************************
    unsigned int pomiar1;		// Zmienna do przechowywania wyniku pomiaru
    unsigned int pomiar2;		// Zmienna do przechowywania wyniku pomiaru
    
    void PRZETWORNIK(void)
    {
    	DDRC=0x00;				// Port jako wejścia
    	PORTC=0x00;				// Wejścia bez podciągania
    
    
    	ADMUX = (1<<REFS0) | 	// Wybór źródła napięcia odniesienia.
    			(0<<REFS1) |	// zewnętrznne
    			(1<<ADLAR) ;	// Bit wyboru sposobu zapisu wyniku w rejestrach ADCL i ADCH
    		/*	(0<<MUX3)  |	// Bity wyboru wejścia analogowego. Wejście wybrane kombinacją  
    			(0<<MUX2)  |	// tych bitów jest dołączone do przetwornika.
    			(0<<MUX1)  |	// MUX 3 2 1 0			MUX 3 2 1 0	
    			(1<<MUX0)  ;	//     0 0 0 0 ADC0	        0 0 0 1 ADC1			*/
    
    	ADCSRA= (1<<ADEN)  |	// Ustawienie go zezwala na pracę przetwornika	
    			(1<<ADPS0) |	// Wybranie częstotliwości dla taktowania przetwornika
    			(0<<ADPS1) |	// 1/32
    			(1<<ADPS2) ;
    }
    //********************************************************************************
    //  Program główny
    //********************************************************************************
    int main(void)
    {	
    int RADDR;
    
    USART();
    PRZETWORNIK();
    while(1)
    	{
    
    	RADDR=0x35;							// sygnał adresu adres serva OC1B 8bitów
    
    	ADMUX |= _BV(0)	;					// Wybór odpowiedniego wejścia ADC0
     	ADCSRA |= _BV(ADSC);       		  	// Rozpoczęcie przetwarzania
    
    	while(bit_is_set(ADCSRA,ADSC))		// Oczekiwanie na zakończenie przetwarzania
        {};	
    	pomiar2=ADCH;			     		// Zapisanie starszych 8 bitów wyniku konwersji
    
    
    	Send_Packet(RADDR, ~pomiar1); 		// Wyslanie wyniku !!!!!!!!!!!!!!!!!!!!!!!
    
    		_delay_ms(1);
    
    
    
    
    	RADDR=0x8E;							// sygnał adresu adres serva OC1B 8bitów
    
    	ADMUX &= ~_BV(0);					// Wybór odpowiedniego wejścia ADC1
    	ADCSRA |= _BV(ADSC);        		// Rozpoczęcie przetwarzania
    
    	while(bit_is_set(ADCSRA,ADSC))		// Oczekiwanie na zakończenie przetwarzania
        	{};	
    	pomiar1=ADCH;						// Zapisanie starszych 8 bitów wyniku konwersji 	  
    
    	Send_Packet(RADDR, ~pomiar2); 		// Wyslanie wyniku !!!!!!!!!!!!!!!!!!!!!!!
    
    	_delay_ms(1);
    	}
    	return 0;
    }
    
    

    
    
    
    
    
    
    //***************************************************************
    //	Odbiornik 
    //	Atmega8 UsART
    //***************************************************************
    
    #include <avr/io.h>							// wejścia wyjścia 
    #include <avr/interrupt.h>					// przerwania
    #include <util/delay.h>						//
    
    //********************************************************************************
    //	DEKLARACJA dla UsART
    //********************************************************************************
    #ifndef F_CPU
    #define F_CPU 8000000
    #endif
    
    #define BAUDRATE 1200							// prędkość transmisji
    #define UBRRVAL ((F_CPU/(BAUDRATE*16UL))-1)
    
    #define SYNC 0xAA								// sygnał synchronizacji 8bitów
    #define RADDR1 0x8E								// dopiero w pętli głwnej
    #define RADDR2 0x35
    //***************************************************************
    // 	INICJOWANIE UsART
    //***************************************************************
    void USART(void)						
    {
    	UBRRL=(uint8_t)UBRRVAL;								// ustawienie  prędkości transmisji 
    	UBRRH=(UBRRVAL>>8);	
    	
    	UCSRC=	(1<<URSEL)|			// ustawienie formatu ramki 
    			(0<<UMSEL)|			// 0 Asynchronous Operation	// 1 Synchronous Operation
    			(0<<UPM1)|
    			(0<<UPM0)|	
    			(0<<USBS)|			// 0 1-bit stopu // 1 2-bity stopu 
    			(0<<UCSZ2)|			// 8bitów danych,
    			(1<<UCSZ1)|		
    			(1<<UCSZ0);	
    	
    	UCSRB=	(1<<RXEN)|			// włączenie nadajnika i odbiornika
    			(1<<RXCIE);						
    }
    
    //********************
    // ODBIERANIE DANYCH 
    //********************
    uint8_t USART_vReceiveByte(void)
    {
        while((UCSRA&(1<<RXC)) == 0);
        return UDR;
    }
    
    //********************
    // DESZYFROWANIE DANYCH
    //********************
    ISR(USART_RXC_vect)
    {
    	uint8_t raddress, data, chk;		
    	raddress=USART_vReceiveByte();
    	data=USART_vReceiveByte();
    	chk=USART_vReceiveByte();
    	if(chk==(raddress+data))				
    		{
    
    		if(raddress==RADDR1)
    			
    			{
    			  OCR1A = 0;
    			  OCR1A = data*0x10+260;	// podaj na servo 1	
    			}
    
    		else if(raddress==RADDR2)
    			
    			{
    			  OCR1B = 0;
    			  OCR1B = data*0x10+280;	// podaj na servo 2	
    			}
    
    					else
    		{
    			  OCR1A = 740;
    			  _delay_ms(10);
    			  OCR1B = 740;
    			  _delay_ms(10);	
    		}
    		}
    
    }
    
    //********************************************************************************
    //	DEKLARACJA PWM SERVA
    //********************************************************************************
    #include <avr/interrupt.h> 
    #include <string.h> 
    #include <avr/signal.h>
    
    //********************************************************************************
    //	INICJOWANIE PWM SERVA
    //********************************************************************************
    void SERVO(void) 
    { 
    
    //  int s1=750; 						//	1400 , 750 , 300
    //  int s2=750; 						//	wpisywanie ręczne 
    
      DDRB = (1<<PB1) | (1<<PB2);			//OC1A OC1B jako wyjscia 
    
      ICR1  = 10000; 						// gorna granica timera
    //  OCR1A = s1;  						//	wpisywanie ręczne
    //  OCR1B = s2; 
    
    	TCCR1A= (1<<COM1A1) | (1<<COM1B1);	// COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10
    	TCCR1B = (1<<WGM13) | (1<<CS10); 	// ICNC1 ICES1 --- WGM13 WGM12 CS12 CS11 CS10
    
    } 
    
    //********************************************************************************
    //	Program główny
    //********************************************************************************
    int main(void)
    {
    	USART();
    	SERVO();
    	sei();
    	while(1)
    	{
    	}
    	//nothing here interrupts are working
    	return 0;
    }
    
    
    

    Fragment odpowiedzialny za ustawienie serw w pozycji 90 stopni
    	if(chk==(raddress+data))				
    		{
    
    		if(raddress==RADDR1)
    			
    			{
    			  OCR1A = 0;
    			  OCR1A = data*0x10+260;	// podaj na servo 1	
    			}
    
    		else if(raddress==RADDR2)
    			
    			{
    			  OCR1B = 0;
    			  OCR1B = data*0x10+280;	// podaj na servo 2	
    			}
    
    					else
    		{
    			  OCR1A = 740;
    			  _delay_ms(10);
    			  OCR1B = 740;
    			  _delay_ms(10);	
    		}
    		}
    
    }
    


    Maziu
  • REKLAMA
REKLAMA