Sida 3 av 5
Re: ATMega16 + USART +PC
Postat: 21 november 2010, 22:32:45
av PHermansson
Du måste läsa UDR för att cleara interrupten. Undrar om 'return'-satsen räcker? I de exempel jag sett brukar man ha typ "int temp = UDR" i interrupt-rutinen.
Edit: Fast du använder visst inte interrupt

Men din kod läser väl av UDR en massa gånger, oavsett om det kommit in ny data eller inte?
Nolla RXC kanske?
Re: ATMega16 + USART +PC
Postat: 21 november 2010, 23:07:00
av AndLi
PH: Jag misstänkte också att man skulle behöva nolla RXC flaggan, annars borde man kunna få det loopande betendet vi ser, men jag tolka det som att det var windowsprogrammet som skapade det. Vilket jag iof tycker låter konstigt.
Re: ATMega16 + USART +PC
Postat: 21 november 2010, 23:40:20
av sodjan
Ja, jag missänkte också från början att det var AVR progremmet som
lopade på UART registret och läste om samma tecken hela tiden.
Men det blir mest spekulationer innan vi vet varifrån de olika
loggningar som har presenterats kommer. Och det är ju också
ganska enkelt att isolera genom att stänga av sändningen från
PC helt. Eller genom att mäta på TX/RX pinnarna för att se i
vilken riktning som omsändningarna sker.
Re: ATMega16 + USART +PC
Postat: 22 november 2010, 07:32:12
av PHermansson
Det är ju enkelt att nolla RXC så det skadar ju aldrig att testa. I databladet står det:
The Receive Complete (RXCn) Flag indicates if there are unread data present in the receive buf-
fer. This flag is one when unread data exist in the receive buffer, and zero when the receive
buffer is empty (i.e., does not contain any unread data). If the Receiver is disabled (RXENn = 0),
the receive buffer will be flushed and consequently the RXCn bit will become zero.
When the Receive Complete Interrupt Enable (RXCIEn) in UCSRnB is set, the USART Receive
Complete interrupt will be executed as long as the RXCn Flag is set (provided that global inter-
rupts are enabled). When interrupt-driven data reception is used, the receive complete routine
must read the received data from UDRn in order to clear the RXCn Flag, otherwise a new inter-
rupt will occur once the interrupt routine terminates.
Så UDR måste läsas för att RXC ska nollas. Frågan är då ändå om en return-sats räcker för att UDR ska ses som läst?
Re: ATMega16 + USART +PC
Postat: 22 november 2010, 08:03:28
av AndLi
PH: Det verkar ju som att den återställs automatiskt på AVR, det gör den inte på den µC jag använder mest..
return UDR; borde vara tillräckligt. Kompilatorn måste ju på något sätt få ut värdet ur UDR för att retunera det.
Re: ATMega16 + USART +PC
Postat: 22 november 2010, 08:56:42
av vfr
Absolut! Håller helt med AndLi. För att returnera det inkommna tecknet så måste mottagningsregistret läsas. Inget annat hokus pokus ska behövas.
Re: ATMega16 + USART +PC
Postat: 22 november 2010, 11:19:49
av sodjan
Alltså är fortfarande det stora frågan *varifrån* den där
loggen en genererad som visar upprepade tecken...
Re: ATMega16 + USART +PC
Postat: 22 november 2010, 15:28:01
av exos
Hej allihoppa.
dubletterna genereras av AVr'en.
Programet skickar komandot en gång!
sen så är ju tanken att AVR'en skall svara tillbaka samma som jag skickat. Men som ni ser skickar den en massa likadana.
Ang return = UDR; så ligger det en sådan i " USARTReadChar() " som läser in värdet. sen så kör ju jag t.ex
FanCH = USARTReadChar(), och då laddas variabeln "FanCH" med inkommande data.
Här kommer hela koden igen. Copy - Paste
Kod: Markera allt
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <avr/iom16.h>
#include <inttypes.h>
void USARTInit(uint16_t ubrr_value)
{
//Set Baud rate
UBRRH=0x00;
UBRRL=0x33;
/*Set Frame Format
>> Asynchronous mode
>> No Parity
>> 1 StopBit
>> char size 8
*/
UCSRC=(1<<URSEL)|(3<<UCSZ0);
//Enable The receiver and transmitter
UCSRB=(1<<RXEN)|(1<<TXEN);
}
void InitPWM()
{
/*
TCCR0 - Timer Counter Control Register (TIMER0)
-----------------------------------------------
BITS DESCRIPTION
NO: NAME DESCRIPTION
--------------------------
BIT 7 : FOC0 Force Output Compare [Not used in this example]
BIT 6 : WGM00 Wave form generartion mode [SET to 1]
BIT 5 : COM01 Compare Output Mode [SET to 1]
BIT 4 : COM00 Compare Output Mode [SET to 0]
BIT 3 : WGM01 Wave form generation mode [SET to 1]
BIT 2 : CS02 Clock Select [SET to 0]
BIT 1 : CS01 Clock Select [SET to 0]
BIT 0 : CS00 Clock Select [SET to 1]
The above settings are for
--------------------------
Timer Clock = CPU Clock (No Prescalling)
Mode = Fast PWM
PWM Output = Non Inverted
*/
TCCR0|=(1<<WGM00)|(1<<WGM01)|(1<<COM01)|(1<<CS00);
TCCR2|=(1<<WGM00)|(1<<WGM01)|(1<<COM01)|(1<<CS00);
//Set OC0 PIN as output. It is PB3 on ATmega16
//Set OC2 PIN as output. It is PD7 on ATmega16
DDRB|=(1<<PB3);
DDRD|=(7<<PB7);
}
/******************************************************************
Sets the duty cycle of output.
Arguments
---------
duty: Between 0 - 255
0= 0%
255= 100%
The Function sets the duty cycle of pwm output generated on OC0 PIN
The average voltage on this output pin will be
duty
Vout= ------ x 5v
255
This can be used to control the brightness of LED or Speed of Motor.
*********************************************************************/
// Ställer in alla kanaler
void PWMOutputCH1(uint8_t duty)
{
OCR0=duty;
}
void PWMOutputCH4(uint8_t duty)
{
OCR2=duty;
}
/********************************************************************
Simple Wait Loop
*********************************************************************/
void Wait()
{
_delay_loop_2(10000);
}
void USARTWriteChar(char data)
{
//Wait untill the transmitter is ready
while(!(UCSRA & (1<<UDRE)))
{
//Do nothing
}
//Now write the data to USART buffer
UDR=data;
}
char USARTReadChar()
{
//Wait untill a data is available
while(!(UCSRA & (1<<RXC)))
{
//Do nothing
}
//Now USART has got data from host
//and is available is buffer
return UDR;
}
void main() {
USARTInit(51);
InitPWM();
int FanCH='a';
char data;
char channel='a';
int outval='0';
//Do this forever
while(1)
{
//Läser vilken kanal det handlar om. a,b,c eller d (och värde)
FanCH = USARTReadChar();
USARTWriteChar(FanCH);
// 97 = 'a'
if (FanCH=='a')
{
//Gå till kanal 1
channel='a';
}
// 98 = 'b'
else if (FanCH=='b')
{
//Gå till kanal 2
channel='b';
}
// 99 = 'c'
else if (FanCH=='c')
{
//Gå till kanal 3
channel='c';
}
// 100 = 'd'
else if (FanCH=='d')
{
//Gå till kanal 4
channel='d';
}
//CH1 Läser com port, skickar ut värde till OCR0
data = USARTReadChar();
if (data==48)
{
outval=0;
}
else if (data==49)
{
outval=30;
}
else if (data==50)
{
outval=90;
}
else if (data==51)
{
outval=120;
}
else if (data==52)
{
outval=190;
}
else if (data==53)
{
outval=210;
}
else if (data==54)
{
outval=225;
}
else if (data==55)
{
outval=235;
}
else if (data==56)
{
outval=245;
}
else if (data==57)
{
outval=255;
}
switch (channel)
{
case 'a':
PWMOutputCH1(outval);
_delay_ms(100);
break;
case 'd':
PWMOutputCH4(outval);
_delay_ms(100);
break;
}
}
}
I början på while loopen så läser jag in datan i "FanCH" sen skickar tillbaka det till mitt program med " USARTWriteChar() "
Men då tycker ju jag att när den har loopat en gång och skickat, så skall den inte skicka nån mer gång.
men jag kan ju ha helt fel här?!
Kod: Markera allt
while(1)
{
//Läser vilken kanal det handlar om. a,b,c eller d (och värde)
FanCH = USARTReadChar();
USARTWriteChar(FanCH);
Re: ATMega16 + USART +PC
Postat: 22 november 2010, 15:51:47
av sodjan
OK. då vet vi var felet är.
Bara att sätta igång och felsöka.
Inget konstigt med det, felsöknig kurs 1A...

Skala ner, isolera, identifiera, läs på. Det måste ju vara *något*
som i AVR'en signalerar att man redan har läst mottaget data...
Re: ATMega16 + USART +PC
Postat: 22 november 2010, 16:03:55
av bearing
Jag kan inte se något fel i koden. Möjligtvis är det något fel beroende på felplacerad blockparenteser {}. Dom ligger inte rätt indenterade, så det är svårt att se.
Man skulle kunna tro att det är fel i USART-rutinerna, men jag ser inte några fel där heller.
Här är USART-rutinerna från ett projekt jag gjort, och dom är skrivna lika som dina.
Kod: Markera allt
void sendChar(unsigned char data)
{
while(!(UCSR0A&(1<<UDRE0)));
UDR0 = data;
}
unsigned char getChar()
{
while(!(UCSR0A&(1<<RXC0)));
return UDR0;
}
Re: ATMega16 + USART +PC
Postat: 22 november 2010, 16:12:33
av exos
Hmm.. Lurigt det här.
En sak till som kanske kan vara intressant.
Som jag sagt innan, skickar jag t.ex "d1,d2,d3....osv, så får jag tillbaka det vi har sett innan tex. d1ddddddddddddddd, en massa "d" helt enkelt, samma gäller ju "a". MEN!
skickar jag då "d0" så slutar den skicka tillbaka, då tycker man ju att den skall göra likadant!? fortsätta skicka "d"... dettta gäller även "a"
Då Måste det ju ha nånting med att när jag skickar en 0 (nolla) så slutar den skicka tillbaka, och allt är frid och fröjd, men så fort jag skickar nåt mellan 1-9,
så svarar den tillbaka hela tiden.
Re: ATMega16 + USART +PC
Postat: 22 november 2010, 18:03:39
av sodjan
Sen är det ju bra du som kan vara 100% säker på att sändaren *inte*
sänder om. Vi andra måste ju lita på (eller inte lita på) vad du säger...
Aja, du får helt enkelt felsöka din seriella förbindelse, på något sätt...
> Som jag sagt innan, skickar jag t.ex "d1,d2,d3....osv,
Menar du "...skickar jag "d1" eller "d2" eller d3" o.s.v" ?
Eller menar du att du skickar "d1,d2,d3" som en gemensam sändning ??
Vad betyder den första dubbel-fnutten i din mening (före "d1") ?
Det finns ingen avslutande dubbel-fnutt så det blir svårt att tolka.
Sen så är det lite märkligt att det är första tecknet (t.ex "d") som
upprepas, inte det sista (t.ex "1") vilket hade varit mer rimligt om det
är UART läsningen som loopar.
Som sagt, kolla att du är väldigt tydlig när du beskriver saker och ting
och att det inte kan missförstås. Slarva inte och kontrollera allt.
Re: ATMega16 + USART +PC
Postat: 22 november 2010, 18:43:11
av jesse
Det kan ju vara kortslutning mellan RX och TX i hårdvaran nånstans... då kommer AVR'en att ta emot samma tecken som den själv skickar ut hela tiden. Annars borde den fastna i USARTReadChar() ända tills PC:n skickar något.
Re: ATMega16 + USART +PC
Postat: 22 november 2010, 19:56:05
av exos
100% säker på att sändarn inte skickar mer än en gång.
100% säker på att TX och RX inte är kortis.
J*vligt skumt detta.
Känns som ett, åker ner i lådan projekt, och kommer fram om en månad igen...
...då jag snart inte har nåt hår kvar.
Re: ATMega16 + USART +PC
Postat: 22 november 2010, 20:14:37
av bearing
Försök lär dig något av det här. Kommentera bort delar av programmet och se ifall problemen består. Testa t.ex. att kommentera bort hela IF- och CASE-blocken, så att whileslingan bara innehåller ett readChar och ett writeChar. Funkar det då? sätt sedan in ett block i taget för att se var det slutar fungera. Felsökningskurs 1A alltså, som sodjan tipsar om.