Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Interfejs RS232-maly problem

desmo999 08 Feb 2009 22:31 2693 12
  • #1
    desmo999
    Level 12  
    Witam. oto mój programik który miał służyć do płynnej regulacji obrotów silnika DC.Literka "a" miała zwiększać obroty a literka "z" zmiejszać. Ogólnie przerwanie od RS-a jest bo zapala się dioda na porcie B0 ale tak jakby program sie potem wieszał bo dioda powinna się wygasić w petli głównej a tego nie robi.

    
    #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
    #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
    
    
    #define fcpu 4000000 //czestotl oscylatora
    #define baud 9600
    #define ubbr  fcpu/((16*baud)-1)
    
    
    
    
    #include <avr\io.h>
    #include <stdio.h>
    #include <inttypes.h>
    #include <avr\pgmspace.h>
    
    #include<avr\interrupt.h>
    char volatile komenda;
    char volatile fodbznak=0;
    volatile    char dana;
    
    
    
    
    SIGNAL(SIG_UART_RECV)
    {
     sbi(PORTB,0);
     komenda=UDR;
     fodbznak=1;
     
       }
    
    
    
    
    void czekaj (unsigned long zt)
    
     { 
       #define tau 10.38
       //int zt1;
       for(;zt>0;zt--)
          {
    	    //for(zt1=0; zt1<255; zt1++);
    		//{
    		 asm("nop");
            //     }
           }
      }
      
     int main(void)
     {	    
    
    
    
     //int odniesienie=5;
    
     union
      {
       unsigned int pwm;
       unsigned char pwmc[2];
       }volatile upwm;
    
    
       DDRB=0xff;
       PORTB=0b00000001;
      
       DDRD=0x02;
       PORTD=0x02;
    
       TCCR1A=1<<COM1A1|1<<1<<WGM10;
       TCCR1B=1<<CS11|1<<CS10;//
    
       TCNT1L=0x00;//wstepne ustawienie wartosci
       TCNT1H=0x00;
    
       UBRRH=0;
       UBRRL=103;
       UCSRB=1<<RXCIE|1<<TXCIE|1<<RXEN;
      // UCSRC=1<<USBS|3<<UCSZ0;
       sei();
       upwm.pwm=50;
    
    
    
    
     while(1)
      {
        //if(bit_is_set(UCSRA,RXC))
    	// {
    	//  odbior(dana);
    	//  }
        if(fodbznak)
    	  {
    	   fodbznak=0;
    	   switch (komenda)
    
    	    { 
    		case 'a':
        	upwm.pwm++;
         	if(upwm.pwm>255)
    	   {
    	    upwm.pwm=255;
    	    }
    		 czekaj(100*tau);
    	    break;
    		case'z':
    	    upwm.pwm--;
    	    if(upwm.pwm>255)
    	    {
    	    upwm.pwm=0;
    	     }
            czekaj(100*tau);
           break;
    	   }  
        }
    OCR1A=upwm.pwm;
    
    
      
     }
    }
    


    oto jedyne ostrzeżenie jakie daje mi avr-studio
    
    ../pwm-rs232.c:25: warning: 'SIG_UART_RECV' appears to be a misspelled signal handler
    


    Procek attiny 2313 prędkość transmisji 2400b/s

    Prosiłbym o jakąś wskazówkę co robię źle??

    Pozdrawiam
  • #3
    Freddie Chopin
    MCUs specialist
    wszedzie tylko SIGNAL, SIGNAL i SIGNAL, a od dawna wszedzie pisze, ze nalezy stosowac ISR - opis w dokumentacji.

    P.S. zmiennych globalnych i statycznych nie trzeba zerowac 'na dzien dobry' - zmienne takie domyslnie inicjalizowane sa wartoscia 0. dodatkowa inicjalizacja '=0' tylko marnuje pamiec kodu (jesli kompilator jest glupi i tego nie sprawdza, a wcale nie musi).

    4\/3!!
  • #5
    desmo999
    Level 12  
    No dobrze.Szczerze to nie wiem do końca co to te ISR ale może można coś zrobić by jakoś działał ten kod??

    Pozdr
  • #6
    dawid512
    Level 32  
    Balu wrote:
    G**zik prawda.
    Każesz mu zmienić na procek Atmega162... a Attiny ma:
    
    SIG_USART_DATA, SIG_UART_DATA
    


    Dziwne więc dlaczego w pliku o nazwie iotn2313.h znajdujemy
    /* USART, Rx Complete */
    #define USART_RX_vect			_VECTOR(7)
    #define SIG_USART0_RECV			_VECTOR(7)
    #define SIG_USART0_RX			_VECTOR(7)
    


    Czekam na odp.
  • #7
    desmo999
    Level 12  
    kolego Dawid512 z
    
    SIG_USART0_RECV
    


    też niestety mi to nie śmiga.pewnie jest gdzieś jakiś głupi błąd którego teraz nie widzę.No nic jutro z tym powalczę.

    Pozdr
  • #8
    Balu
    Level 38  
    @dawid512 ja mówię co pisze w dokumentacji, nie zaglądam do plików bo i po co?
    W dokumentacji (www) stoi jasno.
    To proszę wskazać miejsce, gdzie kolega to wyczytał.
    http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html
    [zumek]


    @Autor...stałe mama zwykła kazywać dużymi literami pisać:)
  • #9
    desmo999
    Level 12  
    napisałem tak jak w 1 poście i nadal klapa

    Dodano po 10 [minuty]:

    z tego co myslę to ten program błędnie przypisuje wartość do UDR. Po wciśnięciu któregokolwiek klawisza silnik albo staje albo idzie na maksa??Od czego to zależy to nie mam pojęcia:)
  • #10
    Balu
    Level 38  
    Ja tak inicjalizowałem tinego:
    
    UCSRC = 1<<UCSZ1 | 1<<UCSZ0;
    UCSRB = (1<<RXCIE)|(1<<TXEN)|(1<<RXEN);			// 8 Databits, receive and transmit enabled, receive complete interrupt enabled
    
    #define F_CPU 11059200
    #define BAUD 9600
    #include <util/setbaud.h>
    UBRRH = UBRRH_VALUE;
    UBRRL = UBRRL_VALUE;
    

    Spróbuj na poczatku programu po inicjalizacji dopisać
    
    UDR='H';
    UDR='e';
    UDR='l';
    UDR='l';
    UDR='o';
    UDR='!';
    

    I zobacz w konsoli czy działa.

    P.S. czemu wy wszyscy lubujecie się w liczeniu na piechotę UBRR?
  • #11
    desmo999
    Level 12  
    Poniżej zmieniona wersja-próbowałem już kilku i nadal coś nie do końca to działa jakby m chciał

    
    #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
    #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
    #include <avr\io.h>
    #include <stdio.h>
    #include <inttypes.h>
    #include <avr\pgmspace.h>
    #include<avr\interrupt.h>
    
    #define FCPU 4000000 //czestotl oscylatora
    #define BAUD 9600
    #define VUBRR  (FCPU/(16*BAUD))-1
    
    char volatile dana;
    char  znak;
    
    ISR(USART_RX_vect )
      
      {
      znak=UDR;
      //return znak;
      }
    
    int main (void)
    {
      DDRB=0xff; //wyjscia
      PORTB=0xff;
    
      DDRD=0x02; //PD1-wyjscie TXD
      PORTD=0x02; //podcigniete wyjscie
    
      //inicjacja RSA-a
     // UBRRH=(unsigned char)(VUBRR>>8);
      UBRRL=(unsigned char) VUBRR; //ustawienie predkosci transmisji
      UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN);//zezwolenia na nadawanie i odczyt
      UCSRC=(1<<USBS)|(3<<UCSZ0);
     //koniec inicjacji 
    
      sei();
      
         while(1)
    	  {
    	   
    
    	    if (znak=='a') 
    		
    		 {
    		 sbi(PORTB,0);
    		       }
    
    		if(znak=='z')  
    		 
    		 {
    		   cbi(PORTB,0);
    		      }
    
    		}
    }
    


    Dodano po 2 [godziny] 34 [minuty]:

    Dobra zamykam temat:)Dałem rade.

    Dzięki za chęci :)

    Pozdrawiam
  • #13
    desmo999
    Level 12  
    Oczywiście już piszę.Przepraszam że od razu nie napisałem ale trochę późno już było.Problem był w ustawianiach prędkości transmisji a konkretnie we właściwościach połączeń trzeba było ustawić Bufor transmisji na niski .Zmieniłem również przerwania tak jak pisaliście na ISR.Pozmieniałem też ustawinia rejestru UCSRC.Oto kompletny program
    
    #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
    #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
    
    
    #define FCPU 4000000 //czestotl oscylatora
    #define BAUD 9600
    //cunsigned long VUBRR = (FCPU/(16*BAUD))-1;
    
    
    
    #include <avr\io.h>
    #include <stdio.h>
    #include <inttypes.h>
    #include <avr\pgmspace.h>
    
    #include<avr\interrupt.h>
    char volatile komenda;
    char volatile fodbznak; 
    char volatile dana;
    ISR(USART_RX_vect)
    {
      
      komenda=UDR;
      cbi(PORTB,0);
      fodbznak=1;
     
       }
    
    
    
    
    void czekaj (unsigned long zt)
    
     {
       #define tau 10.38
       //int zt1;
       for(;zt>0;zt--)
          {
           //for(zt1=0; zt1<255; zt1++);
          //{
           asm("nop");
            //     }
           }
      }
     
     int main(void)
     {      
    
    
    
     //int odniesienie=5;
    
     union
      {
       unsigned int pwm;
       unsigned char pwmc[2];
       }volatile upwm;
    
    
       DDRB=0xff;
       PORTB=0;
     
       DDRD=0x02;
       PORTD=0x02;
    
       TCCR1A=1<<COM1A1|1<<1<<WGM10;
       TCCR1B=1<<CS11|1<<CS10;//
    
       TCNT1L=0x00;//wstepne ustawienie wartosci
       TCNT1H=0x00;
    
       UBRRH=(103>>8);
       UBRRL=103;
       UCSRB=1<<RXCIE|1<<TXCIE|1<<RXEN;
       UCSRC = 1<<UCSZ2|1<<UCSZ1 | 1<<UCSZ0;
       sei();
       upwm.pwm=0;
    
    
    
    
     while(1)
      {
       if(fodbznak==1)
        {
    	 fodbznak=0;
       
        if(komenda=='q')
    	  {
    	  upwm.pwm++;
    	   //czekaj(50);
    	         if (upwm.pwm>255)
    		   {
    		    upwm.pwm=255;
    			 }
    	   }
         if(komenda=='w')
    	  {
    	   upwm.pwm--;
    	   //czekaj(50);
    	     if (upwm.pwm>255)
    		   {
    		    upwm.pwm=0;
    			 }
    	   }
         }
           
    czekaj(10000);   
    sbi(PORTB,0);
    
    OCR1A=upwm.pwm;
    
    
     
     }
    } 
    
    


    Jeszcze raz dzięki za pomoc.

    Pozdrawiam