Skicka seriell data över UART.

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Snouser
Inlägg: 107
Blev medlem: 15 november 2006, 22:07:55
Ort: Göteborg

Skicka seriell data över UART.

Inlägg av Snouser »

Jag får inte sändningen av data att skickas korrekt över UARTen. Som det ser ut nu så anländer bara en massa skräp.

Baudraten är inställd rätt, för det fungerar bra att ta emot och skicka tillbaka datan som nyss anlänt, men jag kan inte skicka vanliga tecken.

Så här ser koden ut.

Kod: Markera allt

#include <avr/io.h> 
#include <util/delay.h>
#include <avr/iom88.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <avr/uart.h>
#include <math.h>

void send_hello(unsigned char *data)
{
	cli();
	int a = 0;
	do
	{
		while (!(UCSR0A & (1<<UDRE0)));
		UDR0 = data[a];
		a++;
	}
	while(a != 10);
	sei();
}
int main()
{

		int a = 0;
		unsigned char *testing;
		do
		{
			testing[a] = a;
			a++;
		}
		while (a != 10);
		send_hello(testing);
}
USARTen är redan inställd.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Hur ser "skräp" ut ?

Om du ska testa/felsöka, varför inte göra koden mycket enklare ?

> men jag kan inte skicka vanliga tecken.

Vad är ett "vanlig tecken" ? Var det inte "vanliga tecken" som
du ekade tillbaka i första testen som gick bra ??

Eftersom du kan returnera tecken så är det ju ganska tydligt att
det inte har med USART'en i sig att göra, utan hur du har
snott ihop dina variabler och funktionsanrop i C-koden.

Börja med att skicka med "UDR0 = <konstant>", t.ex "UDR0 = 65"
(eller "40" i hex) vilket borde skicka ett "A". Fungerar det så är det bara felsökning
kurs 1A för att se varför de inte får iväg det du nu vill sända (det är inte
helt uppenbart för mig vad du förväntar dig ska sändas).
thepirateboy
EF Sponsor
Inlägg: 2109
Blev medlem: 27 augusti 2005, 20:57:58
Ort: Borlänge

Inlägg av thepirateboy »

Testa unsigned char testing[15] istället för unsigned char *testing;
ie
EF Sponsor
Inlägg: 1379
Blev medlem: 23 oktober 2006, 13:12:57
Ort: Tyresö

Inlägg av ie »

...dessutom ser det ut som att du lagrar talen 0-9 i arrayen (som var felinitierad) och sen skriver ut. Skrivbara ASCII-tecken börjar på 32 (space).
Snouser
Inlägg: 107
Blev medlem: 15 november 2006, 22:07:55
Ort: Göteborg

Inlägg av Snouser »

Tack för alla svar hittils.

Jag har nu testat att skicka 65 och 23, men inget fungerar särskilt bra.

Detta anländer på datorn.
.....................
<00><00><00>
.....................
Så här ser koden ut som jag använder.

Kod: Markera allt

#include <avr/io.h> 
#include <util/delay.h>
#include <avr/iom88.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <avr/uart.h>
#include <math.h>
#define F_CPU 4915200 // 4 Mhz 
#define sBit(byte,bit) (byte |= 1<<bit)
#define cBit(byte,bit) (byte &= ~(1<<bit))
#define tBit(byte,bit) (byte & (1<<bit))

void USART_Init(void) 
{ 
	int MYUBRR = 127;
	UBRR0H = (unsigned int)(MYUBRR>>8); 
	UBRR0L = (unsigned int)MYUBRR; 
	//Aktiverar mottagning
	UCSR0B = (1<<RXEN0)|(1<<TXEN0); 
	//S√§tter en stopbit inget paritet och 8 bitar
	UCSR0C = (0<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00)|(0<<UPM01)|(0<<UPM00);
}
 
void init(void)
{
	USART_Init(); //St√§ller in USARTen
}

int main(void) 
{	
	init();
	while (1)
	{
		while (!(UCSR0A & (1<<UDRE0)));
		UDR0 = 65;
		while (!(UCSR0A & (1<<UDRE0)));
		UDR0 = 23;
	}
}
Senast redigerad av Snouser 2 november 2008, 00:56:50, redigerad totalt 1 gång.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

OK.
Hur såg koden ut som "ekade" tecken ?
Snouser
Inlägg: 107
Blev medlem: 15 november 2006, 22:07:55
Ort: Göteborg

Inlägg av Snouser »

Det är inte riktigt så att jag skickar tecken till uC och sedan retunerar, utan det är istället så att jag har en RFID-läsare som skickar tecken till uC och sedan skickar vidare det till PCn.

Så här ser den koden ut.

Kod: Markera allt

#include <avr/io.h> 
#include <util/delay.h>
#include <avr/iom88.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <avr/uart.h>
#include <math.h>
#define F_CPU 4915200 // 4 Mhz 
#define sBit(byte,bit) (byte |= 1<<bit)
#define cBit(byte,bit) (byte &= ~(1<<bit))
#define tBit(byte,bit) (byte & (1<<bit))

volatile unsigned char *nr_phone;
volatile unsigned int antal_phone = 0;

void USART_Init(void) 
{ 
	int MYUBRR = 127;
	UBRR0H = (unsigned int)(MYUBRR>>8); 
	UBRR0L = (unsigned int)MYUBRR; 
	//Aktiverar mottagning
	UCSR0B = (1<<RXEN0)|(1<<TXEN0); 
	//Sätter en stopbit inget paritet och 8 bitar
	UCSR0C = (0<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00)|(0<<UPM01)|(0<<UPM00);
}

unsigned char *recive(void)
{	
	cli();
	unsigned char mellan; //Ställer in register
	unsigned char *value_recive; //Ställer in register
	int b; //Ställer in register
	while(1) //Loopar för evigt eller om retur ges
	{
		b = 1; //Sätter register till ett, eftersom första byten redan är satt
		do
		{
			while (!(UCSR0A & (1<<RXC0))); //Väntar på att information ska tas emot
			mellan = UDR0; //Lägger inkommande i mellan register
		}
		while(mellan != 0x0A); //Kontrollerar ifall byten inte är 0x0A
		value_recive[0] = mellan; //Lagrar 0x0A värdet i första arrayn

		do
		{
			while (!(UCSR0A & (1<<RXC0))); //Väntar på att information ska tas emot
			mellan = UDR0; //Lägger inkommande i mellan register
			value_recive[b] = mellan; //Sparar data och retunerar allt.. 
			b++;
		}
		while(mellan != 0x0D); //Kontrollerar så att sista biten är 0x0D
		
		//Kontrollerar så följande:
		//* Att första biten är 0x0A
		//* Att sista biten är 0x0D
		//* Att 12 bitar har tagits emot
		if (value_recive[0] == 0x0A && value_recive[11] == 0x0D && b == 12)
		{
			sei();
			return value_recive; //Retunerar värde i form av en array
		}
	}
}
 
void init(void)
{
	USART_Init(); //Ställer in USARTen
}

void send(unsigned char *value_recive)
{
	int a = 0;
	while(1)
	{
		while (!(UCSR0A & (1<<UDRE0)));
		UDR0 = value_recive[a];
		if(value_recive[a] == 0x0D)
		{
			break;
		}
		a++;
	}
}

int main(void) 
{	
	init();
	unsigned char *rec;
	while (1)
	{
		rec = recive();
		send(rec);
	}
}
Jag vet att receive är felstavat...
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4750
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Inlägg av Swech »

Vilke baudrate är det som du förväntar dig då?
trots att du säger att den är korrekt skadar det inte
att dubbelkolla.

Det ser ut som du vill ha 2400 baud men är inte säker
Swech

Ps. Editera ditt meddelande och slå ihjäl alla <00><00>
Användarvisningsbild
EagleSpirit
Inlägg: 1288
Blev medlem: 27 maj 2003, 23:15:48
Ort: Västerås
Kontakt:

Inlägg av EagleSpirit »

Ett fel skulle kunna vara som thepirateboy skrivit tidigare... Ändra unsigned char *rec och unsigned char *value_recived till t.ex. unsigned char rec[15] resp. unsigned char value_recived[15]

Kolla lite på hur pekare fungerar. T.ex. här:
http://home.netcom.com/~tjensen/ptr/pointers.htm
http://www.augustcouncil.com/~tgibson/tutorial/ptr.html

Problemet är att du inte har ordnat något lagringsutrymme för datat.
Snouser
Inlägg: 107
Blev medlem: 15 november 2006, 22:07:55
Ort: Göteborg

Inlägg av Snouser »

2400 buadrate stämmer bra.

Det kanske ska påpekas att koden jag nyss postade fungerar utmärk.

De som inte fungerar är att skicka data över UARTen.

Jag kan alltså inte skriva "UDR0 = 65" för då poppar det bara upp en massa konstiga tecken...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Vad är "konstiga tecken" ?

Hur som helst, *något* måste skillja mellan den kod där sändningen
fungerar och den där den inte fungerar. Bara att felsöka...

Du har ju två olika koder, du för fixa olika mellanlägen mellan dessa
och se vad som händer. Om det var mitt problem, så skulle jag
ta RFID koden som du postade och byta ut "rec = recive();" mot något
som inte kommer från recive(). Bara för att ta ett exempel... O.s.v. tills
jag hade hittat var det år snett.
Snouser
Inlägg: 107
Blev medlem: 15 november 2006, 22:07:55
Ort: Göteborg

Inlägg av Snouser »

Nu fungerar ingen utav koderna...

Efter lite sökande så har jag sett att man kan koppla in både 1uF till en MAX232 och 10uF, spelar detta någon roll för vilket information som kommer fram? Det har nämligen fungerat bra fram tills nu med 10uF, men som det ser ut nu så skickar den väldigt udda saker (te.x danska ö, a med hattar os.v).

Det verkar som att rätt kod anländer till uC, detta eftersom koden jag har skrivit kontrollerar så att den skickar rätt. Felet ligger någonstans mellan MAX232 kretsen och datorn som det ser ut nu. Frågan är bara vart...
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4750
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Inlägg av Swech »

danska ö och a med hattar brukar betyda att kommunikationen
faktiskt fungerar men det är fel på:

Antal bitar / stopbitar /parity
Baudrate i båda ändar
Frekvensdiff så att man inte har den baudrate man tror. Vanligast då
man kör intern RC... men du kör ju kristall så det bör inte vara problemet...

1uF - 10uF, dessa kondensatorer använder MAX232 för att skapa
de + - spänningar som behövs för att skicka RS232. De bör inte
skapa de problem du beskriver här, Har själv i alla år kört med 10uF

Prova att ta emot RS232 från din PC.
T.ex. läs och tänd en lysdiod om du får in "A" via rs232. Så trycker du
på PC´n och ser om det fungerar....

Swech
Snouser
Inlägg: 107
Blev medlem: 15 november 2006, 22:07:55
Ort: Göteborg

Inlägg av Snouser »

Nu börjar det bli lite intressant.

Jag har följt tre olika guider för att koppla in MAX232 uC, alla tre guider ger olika värden, vilket är lite konstigt.

Någon som har en guide som fungerar?

Den som jag kör efter nu ser ut så här.
http://sodoityourself.com/wp-content/up ... it_232.jpg

Den ger nästan bra värden, 90% av all information som skickas kommer fram rätt..
Mr M
Inlägg: 165
Blev medlem: 20 januari 2006, 21:35:14

Inlägg av Mr M »

Mät utdata från AVR med ett oscilloskop om du har tillgång till ett. Då ser du också enkelt om bit tiden är rätt.
Skriv svar