Stark behov av hjälp med att skriva och ta emot av USART !

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Jennie
Inlägg: 173
Blev medlem: 8 februari 2014, 13:23:00

Stark behov av hjälp med att skriva och ta emot av USART !

Inlägg av Jennie »

Hej!

Har en kod härne på bilderna som jag arbetat med här till min Arduino 2560-mikrokontroller, som jag arbetar med i Atmel Studio.
Jag tänker skriva och ta emot en (ASCII-konverterad) bokstav genom en USB-sladd, men av någon anledning så visas ingenting på mina terminalfönster. Har prövat med Atmel Studios inbyggda terminal och programmet puTTY men det sker ingenting.

Någon som har en hint om vad jag gjort för fel?
När jag sänder koden ner i mikrokontrollern så ser jag att det blinkar snabbt på TX- och RX-lamporna, så något borde väl bli sänt, eller?

Jag har ju satt COM3 och baudraten i terminalprogrammen riktigt (dvs. COM3 och 19200 bps) men kommer ingenstans nu så skulle vara evigt tacksam ifall du ville hjälpa mig i så fall! :)

Bild

Jag har alltså tänkt ställa in för att ha:
1 start och 1 stoppbit
8 databits
19200 baudrate
Ingen paritet eller sånt och asynkroniskt läge
Använda COM3-porten
Användarvisningsbild
BEEP
EF Sponsor
Inlägg: 1593
Blev medlem: 21 januari 2006, 16:57:56
Ort: Mölndal

Re: Stark behov av hjälp med att skriva och ta emot av USART

Inlägg av BEEP »

Om du skickar tecken från Arduino till datorn så händer det ingenting?
Jennie
Inlägg: 173
Blev medlem: 8 februari 2014, 13:23:00

Re: Stark behov av hjälp med att skriva och ta emot av USART

Inlägg av Jennie »

Alltså skriver jag in tecken i terminalfönstret med tangentbordet på datorn så får jag ingenting tillbaka, nej.
Användarvisningsbild
BEEP
EF Sponsor
Inlägg: 1593
Blev medlem: 21 januari 2006, 16:57:56
Ort: Mölndal

Re: Stark behov av hjälp med att skriva och ta emot av USART

Inlägg av BEEP »

Börja med att bara skicka tecken från µC och när det fungerar så bråkar du med kommunikationen från dator till µC.
Jennie
Inlägg: 173
Blev medlem: 8 februari 2014, 13:23:00

Re: Stark behov av hjälp med att skriva och ta emot av USART

Inlägg av Jennie »

^ Hur kan en sådan kod se ut?

Jag vet i alla fall att den där receive-funktion bör fungera då jag ser RX-lampan lysa ifall jag har terminalprogrammet på och trycker på tangentbordet, så någonting tas ju emot i UART0. Men att få tillbaka någonting fungerar ju inte?

Jag vet verkligen inte hur jag ska skriva den där transmit-funktionen på annat vis för att få det till att fungera?
Användarvisningsbild
BEEP
EF Sponsor
Inlägg: 1593
Blev medlem: 21 januari 2006, 16:57:56
Ort: Mölndal

Re: Stark behov av hjälp med att skriva och ta emot av USART

Inlägg av BEEP »

Eftersom bägge lysdioderna blinkar så vet vi att det är rätt port på datorn och att µC skickar ut någonting. Prova att skicka tecken från µC genom att göra en funktion som sänder ett tecken eller fler varje sekund och tala om för oss om du ser något i terminalen eller på lysdioden.

Edit:
Ett tecken är kanske för lite för att man ska kunna hinna se något blink på lysdioden.

Edit:
Ändrat texten.
Senast redigerad av BEEP 15 mars 2015, 13:27:03, redigerad totalt 4 gånger.
Användarvisningsbild
BEEP
EF Sponsor
Inlägg: 1593
Blev medlem: 21 januari 2006, 16:57:56
Ort: Mölndal

Re: Stark behov av hjälp med att skriva och ta emot av USART

Inlägg av BEEP »

När det gäller koden så är det lättare att analysera den om du postar den med kod taggar(klicka på Code och klistra in kopierad text från utvecklingsprogrammet).

Kod: Markera allt

/*
* Created 2015-03-14 21:01:34
*
*/

#define BAUD 19200 // 19 200 baud
#define FOCS 1843200
Muppis
Inlägg: 275
Blev medlem: 15 februari 2007, 10:26:28
Ort: Halmstad

Re: Stark behov av hjälp med att skriva och ta emot av USART

Inlägg av Muppis »

Jag är inget vidare begåvad på C, men i USART_Receive() använder du aldrig data, och det du returnerar från USART_Receive() använder du aldrig i main()!?
Användarvisningsbild
baron3d
EF Sponsor
Inlägg: 1341
Blev medlem: 1 oktober 2005, 23:58:43
Ort: Torestorp

Re: Stark behov av hjälp med att skriva och ta emot av USART

Inlägg av baron3d »

Funktionen USART_Receive skall se t så här:
int USART_Receive(void) { ......


och i main.c:

data = USART_Receive();
Mupp
Inlägg: 134
Blev medlem: 25 februari 2006, 10:30:38
Ort: Linköping

Re: Stark behov av hjälp med att skriva och ta emot av USART

Inlägg av Mupp »

Nu har jag inte databladet i handen, utan en äggmacka, men är det verkligen rätt siffra du skriver till UBRR? Länge sen jag petade avr, men det där känns fel. Kollat databladet?
Jennie
Inlägg: 173
Blev medlem: 8 februari 2014, 13:23:00

Re: Stark behov av hjälp med att skriva och ta emot av USART

Inlägg av Jennie »

Funkar typ nu! Jag gjorde om det ganska mycket och tittade på ett exempel i en bok jag har så jag skriver om en hel sträng nu.

Men nu vill jag försöka få så att...

1. Jag har en sträng som skriver till användaren "Enter time in hh:mm:ss". Någon slags motsvarighet till "printf" här?
2. Sedan skannar av tidsvärdena från användarens värden för hh, mm och ss. Någon slags motsvarighet till "scanf" här?
3. Efter det vill jag att tiden ska uppdatera sig och räkna upp, så någon form av beräkning ska jag ha. Jag vet inte... men jag tänker mig nu en for-loop för varje enhet som börjar om efter räkning med nån slags fördröjning.

Någon som kan ge tips och förklara hur jag kan göra det utifrån den här koden jag har nedan?

Kod: Markera allt

#define BAUDRATE 19200
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/io.h>
#include <stdio.h>

//Deklaration av funktioner
void USART_init(void);
unsigned char getsUSART0(void);
void putchUSART0(unsigned char data);
void putsUSART0(char* str);
void nylinje(void);


char String[]=" Current time now is hh:mm:ss";    //String[] är egentligen an array behandlas som en string av kompilern i och med " "

char string2[]="Enter current time in hh:mm:ss"; //Den här strängen gör ingenting just nu då jag är osäker på hur jag ska använda den

int main(void){
	USART_init();        //Kallar på USART0 initialiseringsfunktionen
	
	while(1){	//Oändlig loop
		putsUSART0(String);    //Passar strängen till putsUSART0-funktion och sänder över det seriella värdet
		
		_delay_ms(1000);        //Fördröjer med 1 sekund så den återsänder strängen varje sekund
		
		nylinje(); //Kallar på funktionen som fixar en ny linje
	}
	return 0;
}


void USART_init(void){
	
	UBRR0 = BAUD_PRESCALLER;	//Ställer in baud rate register

	//Ställer in frame format: 8bit, 1 stoppbit, UCSZ01 och UCSZ00 båda två höga då de är med och bestämmer framestorleken	
	UCSR0C = ((1 << UCSZ01) | (1 << UCSZ00));	
	
		UCSR0B = (1<<RXEN0)|(1<<TXEN0);			  //Initaliserar receiver och transmitter			 
}

unsigned char getsUSART0(void)
{	
	while(!(UCSR0A & (1<<RXC0)));		//Väntar på att data ska tas emot
		return UDR0;					//Returnera sedan värderna som finns i buffern
}

void putchUSART0(unsigned char data)
{
	while(!(UCSR0A & (1<<UDRE0)));	// Vänta på att USART0s data register blir tomt
	
		UDR0 = data;				//Sätt sedan så här			
}

void putsUSART0(char* str)
{	
	// Här vill jag skriva att användaren ska skriva in tiden (som hh:mm:ss)!
	
	while(*str){
		putchUSART0(*str);
		
		str++;
		_delay_ms(200);
	}	
}

void nylinje(void) {
	putchUSART0(0x0D);		// ASCII-värdena för att göra en ny linje
	putchUSART0(0x0A);
}
Så här ser det ut i terminalfönstret just nu btw..
Bild
Senast redigerad av Jennie 15 mars 2015, 18:49:50, redigerad totalt 1 gång.
Användarvisningsbild
Icecap
Inlägg: 26226
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Stark behov av hjälp med att skriva och ta emot av USART

Inlägg av Icecap »

Jag gör sånt ganska mycket. Och det har inget med ATmega eller annan gammal grunka att göra, det är bara programmering.

Jag har dock tagit steget längre och gjort så att man skriver texten "set time hh:mm:ss"<Enter> (utan citationstecken) och programmet klurar sedan ut att det är "set" och att nästa ord är "time" och sedan skipper programmet alla whitespaces till siffrorna.

Kod: Markera allt

        case Command_Set_Time:
          Work[0] = Value; // Hour
          while((*Source >= '0') && (*Source <= '9') && *Source) Source++; // Skip  to ':'
          if(*Source == ':')
            {
            Source++;
            Work[1] = atoi(Source); // Minute
            while((*Source >= '0') && (*Source <= '9') && *Source) Source++; // Skip  to ':'
            if(*Source == ':')
              {
              Source++;
              if((*Source >= '0') && (*Source <= '9'))
                {
                Work[2] = atoi(Source); // Second
                Local_Time.Year   = Date_Time.Year;
                Local_Time.Month  = Date_Time.Month;
                Local_Time.Date   = Date_Time.Date;
                Local_Time.Hour   = Work[0];
                Local_Time.Minute = Work[1];
                Local_Time.Second = Work[2];
                Date_Time_Make_UTC(&Local_Time, Config.Timezone);
                Date_Time_Convert2UNIX(&Local_Time, &Check);
                Date_Time_Make_Local_Time(&Local_Time, Config.Timezone);
                Clock = Check; // Set clock
                RTC_Write_Time(&Check);
                sprintf(Buffer, "%s %s: %u:%02u:%02u\r\n", Comm_Text_Set, Comm_Text_Time, Local_Time.Hour, Local_Time.Minute, Local_Time.Second); Printout(Buffer);
                }
              }
            }
          break; // Command_Set_Time
Lite förklaring:
char* Source pekar på första tecken i timmarna.
unsigned char Work[3] är arbetsvariabler som timmar, minuter och sekunder sparas i till att börja med under omvandlingen.
Value är en variabel som redan håller värdet på första parameter som Source pekar på. Detta då det rör sig om många kommandon och många behöver ett värde och då kan man likaväl göra den omvandling direkt.

Och detta fungerar och är en del av programmet i min kontorsklocka.
Jennie
Inlägg: 173
Blev medlem: 8 februari 2014, 13:23:00

Re: Stark behov av hjälp med att skriva och ta emot av USART

Inlägg av Jennie »

^^ Najs! Tack. Jag ska pröva att göra likadant. Intressant.

Först behöver jag nog hjälp med hur jag ska kunna kommunicera fram och tillbaka med MCU:n?
Jag har fortfarande problemet att när jag skriver in någonting i terminalprogrammet, så får jag inte några värden tillbaka. Nu skriver ju programmet bara ut "Current time is hh:mm:ss" och jag kan ju som inte kommunicera med det fortfarande. Men den kan i varje fall skriva någonting till mig i den där strängen.
Användarvisningsbild
Icecap
Inlägg: 26226
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Stark behov av hjälp med att skriva och ta emot av USART

Inlägg av Icecap »

Frågan är hur du vill kommunicera med den. När du skriver terminalprogram antar jag att du vill kunde skriva just via ett terminalprogram.

Och då gör jag så att jag definiera en buffer - och lite annat:

Kod: Markera allt

struct
  {
  char Buffer[50];
  unsigned char In, Flag, Chars;
  } Rx;
Sedan aktiverar jag Rx-interrupten och gör en ISR:

Kod: Markera allt

void RS232_B_Rx_ISR(void)
  {
  // Recieve interrupt (if enabled)
  _UBYTE Incoming;
  Incoming = SCI0.RDR; // A read empties the Rx-buffer and removes the interrupt
  switch(Incoming)
    {
    case '\b':
    case 0x7F: // Backspace
      if(Rx.In)
        {
        Rx.Buffer[--Rx.In] = 0x00;
        }
      break;
    case '\r':
    case '\n': // Enter
      Rx.Chars = Rx.In;
      if(Rx.In) Rx.Flag = 10;
      Rx.In = 0;
      break;
    default:
      if(Rx.In < sizeof(Rx.Buffer) - 1)
        { // Så länge det finns plats i buffern läggs det mottagna in.
        Rx.Buffer[Rx.In++] = Incoming;
        Rx.Buffer[Rx.In]   = 0;
        }
    break;
    }
  }
Rx.Flag är egentligen en flagga som räknas ner av en timer-interrupt. Detta betyder att main-loop bara har en viss tid till att kolla flaggan och utföra ordern. Sker detta inte inom lagom tid kastas meddelandet. Man kan göra det utan timer-delen om man vill.

MEN - när Rx.Flag är icke-noll finns det ett meddelande att jobba med, det är iaf. pressat på <Enter>.

Sedan är det frågan om att dekoda vad som finns i buffern och vill man konde tolka kommandon v typen "set time hh:mm:ss", "get time", "set date yyyy-mm-dd" osv. krävs en hel del mer - men det har jag såklart löst och gjort till en fil jag kan hämta in utan att svettas. Det var dock lite jobb att fixa.
Användarvisningsbild
BEEP
EF Sponsor
Inlägg: 1593
Blev medlem: 21 januari 2006, 16:57:56
Ort: Mölndal

Re: Stark behov av hjälp med att skriva och ta emot av USART

Inlägg av BEEP »

Prova att använda USART_Receive funktionen från din första kod som väntar på tecken från terminalen. När programmet går ur while loopen och åtvänder till main så låter du µC skicka några tecken för att se om den går ur loopen. Om detta fungerar så är nästa steg att försöka skicka tillbaka motagen data till terminalen.

Om du har någon ledig lysdiod på Arduino så kan du använda den för debugging(felsökning). Lysdioden kan du t.ex. tända före en loop och släcka den efter loopen för att se om programmet är i funktionen och om den fastnar där.
Skriv svar