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.
#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;
}
}
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.
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... ?
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.
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å.
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)
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...
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).
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.
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:
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.
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