USART med MPCM på en AVR

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
davrex
Inlägg: 149
Blev medlem: 18 januari 2009, 22:05:15

USART med MPCM på en AVR

Inlägg av davrex »

Håller nu på med att försöker att få MPCM att funkar mellan just nu 2 st avr:er har fått det att funka utan MPCM men efter som jag ska ha flera sedan så börja jag kolla på MPCM. Problmet jag har är att jag tar en en knapp tryckning på mastern och skickar den till slaven som sak skiva ut det till PORTB men det som kommer ut på PORTB är adressen inte data. Så skulle behöva lite hjälp med att fatt vad jag har missuppfattat.

MASTER koden:

Kod: Markera allt

#include <avr/io.h>
#include <util/delay.h> 

#define F_CPU 8000000
#define USART_BAUDRATE 9600 
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) 

int main (void) 
{ 
   DDRC = 0x00;
   DDRB = 0xFF;
   UCSRC = (1<<URSEL)|(0<<UMSEL)|(0<<UPM1)|(0<<UPM0)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);
   UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<TXCIE)|(1<<RXCIE)|(1<<UCSZ2); 

   UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register 
   UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register 

   for (;;) // Loop forever 
   { 

  
      while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it 
      
      UCSRB |= (1<<TXB8); 
      UDR = 0x02;
      
      while ((UCSRA & (1 << UDRE)) == 0) {}; 
      PORTB = PINC;
      UCSRB &= ~(1<<TXB8); 
      UDR = PINC; 
   }    

}

SLAVE kod :

Kod: Markera allt

#include <avr/io.h> 
#include <avr/interrupt.h> 

#define bit_on(BYTE, BIT)  BYTE |= 1 << BIT
#define bit_off(BYTE, BIT) BYTE &= ~(1 << BIT)

#define F_CPU 8000000
#define USART_BAUDRATE 9600 
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) 
#define rx_address 0x02


int main (void) 
{ 
   DDRB = 0xFF;
   DDRC = 0xFF;
   UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register 
   UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register 

   UCSRC = (1<<URSEL)|(0<<UMSEL)|(0<<UPM1)|(0<<UPM0)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);
   UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<TXCIE)|(1<<UCSZ2); 
   UCSRA |= (1<<MPCM); 
    sei();
    PORTB = 0xFF;
    PORTC = 0x00;
   for (;;) // Loop forever 
   { 
         // Do nothing - echoing is handled by the ISR instead of in the main loop 

   }    
} 

ISR(USART_RXC_vect) 
{ 
   unsigned char inData; 
   inData = UDR;    //Read data register    
   if(UCSRB & (1<<RXB8)) //Address frame? 
   { 
      if((inData) == rx_address)    //Verify address 
      { 
         UCSRA &= ~(1<<MPCM);//Disable MPCM filtering 
         bit_on(PORTC,4);
      } 
      else // not our address, ignore any data 
      { 
         UCSRA |= (1<<MPCM);//Enable MPCM filtering 
         bit_off(PORTC,4);
 
      } 
    bit_off(PORTC,3);
   } 
   else                   //Data Frame received 
   { 
        bit_on(PORTC,3);
        PORTB = inData; 
        UCSRA |= (1<<MPCM); //Enable MPCM 

   } 
} 

Tack på förhand.
davrex
Inlägg: 149
Blev medlem: 18 januari 2009, 22:05:15

Re: USART med MPCM på en AVR

Inlägg av davrex »

Kod: Markera allt

  if(UCSRA & (1<<MPCM)) //Address frame? 
Kör jag med nu istället vilket det då funkar mellan mina 2 avr som jag som test. Fast jag blir inte klok på hur det är tänkt har läst mycket på http://www.avrfreaks.net och där säger folk olika. http://www.avrfreaks.net/index.php?name ... 334#644334 där skriver han att man inte ska använda som jag gör nu utan dom jag hade innan. Någon som har koll och kan förklara för mig vilket det är som gäller och varför det "korrekta" sättet inte funkar för mig.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: USART med MPCM på en AVR

Inlägg av sodjan »

I första posten, du har inte någon interrupt-flagga man ska stängas av i ISR(USART_RXC_vect) ?
Jag tänkte om din rutin blir anropad två gånger direkt efter varandra (innan data byten
har kommit på USART linan) så kommer kanske inData = UDR att läsa adressen två gånger ?
D.v.s samma data från UDR. Du stänger av MPCM filtering första gången så andra gången
kommer väl den att trilla igenom ner till där du sätter PORTB... ?
davrex
Inlägg: 149
Blev medlem: 18 januari 2009, 22:05:15

Re: USART med MPCM på en AVR

Inlägg av davrex »

hmm intressant tänkte USART_RXC_vect ska ju dock bara anropas när en byte är framme. Och har inte läst något om att man måste noll ställa det.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: USART med MPCM på en AVR

Inlägg av sodjan »

Nej, och jag vet inte riktigt hur det fungerar på AVR med C heller... :-)

På andra processorer sätts en flagga (och ett interrupt genereras om det
är enablat). Om man inte clearar flaggan innan man gör "return-from-interrupt"
så kommer interruptet att anropas direkt igen. Men som sagt, kanske att
C-kompilatorn tar han om det.

Hur som helst, din beskrivning på symptomet skulle stämmer med dubbelt anrop.
davrex
Inlägg: 149
Blev medlem: 18 januari 2009, 22:05:15

Re: USART med MPCM på en AVR

Inlägg av davrex »

Dock efter min ändring i min andra post så funkar det som det är tänkt :/ det som gör mig lite förvirrad. Då jag har löst att det är "fel" sätt att göra på.
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: USART med MPCM på en AVR

Inlägg av jesse »

har du nån länk till definitionen av MCPM, med beskrivning av dataprotokollet?

Lite svårt att hitta på Google:
MPCM Evangelism Ministry
Marco Polo Capital Markets (MPCM)
MicroParticles in Cerebral Malaria
Massive Passive Cash Machine. MPCM
*Multichannel Pulse Code Modulation* (men ingen förklaring)
davrex
Inlägg: 149
Blev medlem: 18 januari 2009, 22:05:15

Re: USART med MPCM på en AVR

Inlägg av davrex »

Multi-processor Communication mode (MPCM)

EDIT:bara det jag har läst i atmega8 datablad har inte mycket hitta så mycket mer vettig info än det.
Senast redigerad av davrex 23 juli 2010, 17:44:05, redigerad totalt 2 gånger.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: USART med MPCM på en AVR

Inlägg av sodjan »

Som jag fattade det så är det en bit i något kontrollregister
som väljer om man ska ha USART adressering (med en nioende
bit sannolikt) påslaget eller inte...
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: USART med MPCM på en AVR

Inlägg av jesse »

aha.. ok :idea:
davrex
Inlägg: 149
Blev medlem: 18 januari 2009, 22:05:15

Re: USART med MPCM på en AVR

Inlägg av davrex »

sodjan skrev:Nej, och jag vet inte riktigt hur det fungerar på AVR med C heller... :-)

På andra processorer sätts en flagga (och ett interrupt genereras om det
är enablat). Om man inte clearar flaggan innan man gör "return-from-interrupt"
så kommer interruptet att anropas direkt igen. Men som sagt, kanske att
C-kompilatorn tar han om det.

Hur som helst, din beskrivning på symptomet skulle stämmer med dubbelt anrop.
Hitta detta i ATmega8 datablad så jag antar att den 0 ställs själv efter läsning.
RXC: USART Receive Complete
This flag bit is set when there are unread data in the receive buffer and cleared when the receive
buffer is empty (i.e. does not contain any unread data). If the Receiver is disabled, the receive
buffer will be flushed and consequently the RXC bit will become zero. The RXC Flag can be
used to generate a Receive Complete interrupt (see description of the RXCIE bit).
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: USART med MPCM på en AVR

Inlägg av sodjan »

OK. Så läsningen av mottagningsregistret clearar också flaggan. Rimligt.

Hm, antagligen är det mågot annat logiskt fel i hur koden hanterar MPCM flaggan o.s.v.
Spontant ser det lite konstigt ut att läsa UDR innan man har kollat adressbiten t.ex.
davrex
Inlägg: 149
Blev medlem: 18 januari 2009, 22:05:15

Re: USART med MPCM på en AVR

Inlägg av davrex »

TACK! Nu funkar det som det ska efter du sa det där så satte jag mig med databladet igen... och läst allt från början. Hitta då detta stycket:
Receiving Frames with 9 Data Bits
If 9-bit characters are used (UCSZ=7) the ninth bit must be read from the RXB8 bit in UCSRB
before reading the low bits from the UDR. This rule applies to the FE, DOR and PE Status Flags
as well. Read status from UCSRA, then data from UDR. Reading the UDR I/O location will
change the state of the receive buffer FIFO and consequently the TXB8, FE, DOR, and PE bits,
which all are stored in the FIFO, will change.
Så koden vart då såhär och det verkar funka som det ska:

Kod: Markera allt

ISR(USART_RXC_vect) 
{ 
 unsigned char status, control, inData; 
   status=UCSRA;    //Read register A 
   control=UCSRB;   //Read register B -- incl. RXB8 
   inData = UDR;    //Read data register      
   if(control & (1<<RXB8)) //Address frame? 
   { 
      if((inData) == rx_address)    //Verify address 
      { 
         UCSRA &= ~(1<<MPCM);//Disable MPCM filtering 
         bit_on(PORTC,4);
      } 
      else // not our address, ignore any data 
      { 
         UCSRA |= (1<<MPCM);//Enable MPCM filtering 
         bit_off(PORTC,4);
 
      } 
    bit_off(PORTC,3);
   } 
   else                   //Data Frame received 
   { 
        bit_on(PORTC,3);
        PORTB = inData; 
        UCSRA |= (1<<MPCM); //Enable MPCM 

   } 
} 

Så nu återstår bara problemet med att lyckas då den att skicka något tillbaka till master med.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: USART med MPCM på en AVR

Inlägg av sodjan »

OK, trevligt... :-)
Jag hade inte sett just det där, det bara kändes mer naturligt att
kolla flaggor och statusbitar först och sedan läsa själva datat.
Verkar ju som att det stämde... :-)

Jag ser att du löste det via ett par temp-variabler, min tanke var mer
att flytta in läsningen UDR *efter* kontrollen av RXB8, men det där
fungerar väl också.

Varför läser du UCSRA ? Du använder ju inte "status" någonstans.
davrex
Inlägg: 149
Blev medlem: 18 januari 2009, 22:05:15

Re: USART med MPCM på en AVR

Inlägg av davrex »

Körde med variabler för att slippa ha på 2 ställen att läsa av UDR är nog mer bara en sak jag brukar göra. Och status tog jag med bara i alla fall att jag skulle behöva kolla MPCM eller likande, har ju error flaggor där och så. Hellre en kod rad extra en en för lite :P
Skriv svar