AVR C fråga, bit_is_clear/set vimsig?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
toffie
Inlägg: 1888
Blev medlem: 22 juli 2004, 21:38:07
Ort: Töreboda / Stockholm
Kontakt:

AVR C fråga, bit_is_clear/set vimsig?

Inlägg av toffie »

Hej på er,

Sitter med ett AVR projekt, som skrivs i C, där jag har problem med att avläsa ett värde från UARTen.
Jag skickar ett enstaka tecken, exempelvis "0" (noll).

Detta tecken, i binärt, ser ju ut som 0000.

Om jag då med följande kod;

Kod: Markera allt

	if (bit_is_set(data, bitReply))
	{
		LCDGotoXY(0,0);
		LCDWriteString("Reply");
		PORTB &= ~(1<<bitReply);
	}
	else
	{
		LCDGotoXY(0,0);
		LCDWriteString("No Reply");
		PORTB |= 1<<bitReply;
	}
.. tittar ifall bitReply biten är satt, som i mitt fall är bit 0, på inkommande datan från UART (ett tecken) så ska jag få ett "No Reply" värde på displayen. Här är allt korrekt och det fungerar.

Det fungerar så länge jag skickar ett tecken mellan 0-9. Men när jag går upp på hex värdena, A-F så blir det istället inverterat. Det vill säga, jag behöver då alltså använda bit_is_clear för att få samma funktion på tecken A-F.

Det känns lite mysko, eller ska det vara så?

Jag behandlar inte inkommande data på något sätt, jag testar data direkt när det tas emot i en ISR rutin. Det hela är väldigt mycket på debug stadie just nu, så det ska snyggas till och ändras en del. Men jag vill ju att det ska se rätt ut redan på debug stadiet, annars blir det ju jobbigt när man tar bort den enkla vägen för att se vad man får in i processorn ;)

Vidare verkar det som om värdet "f" bara innehåller binära bitarna 1 och 2 men inte 0 och 3.. när jag som ovan kör en kodsnutt som tar fyra lysdioder och visar det binära värdet;

Kod: Markera allt

	if (bit_is_set(data, bitReply))
	{
		LCDGotoXY(0,0);
		LCDWriteString("Reply");
		PORTB &= ~(1<<bitReply);
	}
	else
	{
		LCDGotoXY(0,0);
		LCDWriteString("No Reply");
		PORTB |= 1<<bitReply;
	}
	if (bit_is_set(data, bitChecked))
	{
		PORTB &= ~(1<<bitChecked);
	}
	else
	{
		PORTB |= 1<<bitChecked;
	}
	if (bit_is_set(data, bitSubType1))
	{
		PORTB &= ~(1<<bitSubType1);
	}
	else
	{
		PORTB |= 1<<bitSubType1;
	}
	if (bit_is_set(data, bitSubType2))
	{
		PORTB &= ~(1<<bitSubType2);
	}
	else
	{
		PORTB |= 1<<bitSubType2;
	}
I headern på main.c filen har jag följande;

Kod: Markera allt

#define bitReply 0
#define bitChecked 1
#define bitSubType1 2
#define bitSubType2 3
Detta ska då sätta ett namn på de olika bitarna. Ja.. ni kan ju sånt ;)

Att notera, det fungerar helt utmärkt med värden 0-9 på samtliga lysdioder, men så fort man går upp på A-F så blir det fel :S

Hoppas det går att förstå när jag skriver i nattmössan ;)

Tack på förhand för att ni tittar in :)


Edit...
Ok, nu kom jag på att jag skickar i decimal istället för i hex.. ändrade jag det så fungerar det!
Men jag är nu orolig för om jag "lyckas" skriva exempelvis ett eget terminalprogram på PC som klarar att skicka just i hex.. Samma sak för hur jag ska få exempelvis en annan AVR att kommunicera med min första AVR genom att skicka hex över UART..

Är det något speciellt jag behöver tänka på här?
Kaggen
Inlägg: 432
Blev medlem: 29 januari 2005, 03:06:02

Re: AVR C fråga, bit_is_clear/set vimsig?

Inlägg av Kaggen »

> Jag skickar ett enstaka tecken, exempelvis "0" (noll).
> Detta tecken, i binärt, ser ju ut som 0000.

Nja, om man skall vara petig blir det väl 00000000 (8-bitar i en byte). Om du nu inte bara bryr dig om lägsta nibblen (nibble = halv byte, 4 bitar)?

Tror det råder lite begreppsförvirring. Oftast säger man att man skickar binärt eller ASCII. Du säger Hexadecimalt, normalt brukar man då mena ASCII, så jag antar att det är det du menar?

Skickar du binärt får du ju samma tal du skickar i mottagande ände. Dvs skickar du 3 bytes t.ex 0, 12, 45 får du ju 0, 12 , 45 i andra änden.

Skickar du däremot 2 teckens ASCII koder för hexadecimala värden omvandlar du ju t.ex 12 till 0C och 45 till 2D där 0C består av två bytes som representerar ascii värdet för tecknet '0' och 'C' vilket är 0x30 och 0x43.

Så länge du skickar ASCII koden för 0-9 och bara hanterar lägsta nibbeln så är det ju så fiffigt att lägsta nibbeln för tecknet '0' är 0 och lägsta nibbeln för tecknet '1' är 1 o.s.v. När du däremot skall översätta A-F så gäller inte detta längre då dessa koder inte ligger på värden som gör att lägsta nibbeln passar. Du kan ju söka på nätet på "ASCII to binary", "hex to binary" eller liknande för mer info. Du har dessutom en ASCII tabell på t.ex http://www.asciitable.com/
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4750
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Re: AVR C fråga, bit_is_clear/set vimsig?

Inlägg av Swech »

ascii för "0" är 48 0b00110000
ascii för "A" är 65 0b01000001

Tittar du bara på de lägsta bitarna så bör det nu bli aha varför det blir inverterat
med A....F

Swech
Användarvisningsbild
Icecap
Inlägg: 26652
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: AVR C fråga, bit_is_clear/set vimsig?

Inlägg av Icecap »

Och jag kan inte bli klok på vad som sänds fram och tillbaka.
Är 0 det samma som 0x00?
Eller är det '0'? (alltså 0x30)

Och A då? Samma sak: är det 0x0A? Eller 'A' (0x41)? Eller 'a'? (0x61)?
Användarvisningsbild
toffie
Inlägg: 1888
Blev medlem: 22 juli 2004, 21:38:07
Ort: Töreboda / Stockholm
Kontakt:

Re: AVR C fråga, bit_is_clear/set vimsig?

Inlägg av toffie »

Hej på er,

Tack för era svar!
Först och främst måste jag hålla med dig Icecap
Icecap skrev:Och jag kan inte bli klok på vad som sänds fram och tillbaka...
Jag vet verkligen inte alls vad som "egentligen" skickas fram och tillbaka, mer än att det är elektriska 0/1 signaler ;)

Det jag "vill" i slutändan är att jag ska kunna skicka exempelvis åtta bitar, en byte, ett helt tecken. Exempelvis U och sen ska detta tecken behandlas som en 8-bitars variabel. Processorn ska då ha 8 bitar, som i binärt, att läsa av för olika funktioner.

Om jag exempelvis skickar U så blir det hex 55, eller istället binärt 10011001
Här ska då processorn se att bit 7 är satt och göra en specifik sak på grund av det, bit 3 och 4 aktiverar andra funktioner osv.
Förstår ni hur jag tänker? Förmodligen.. :P


När jag skrev att jag skickat exempelvis 0 eller F så tänkte jag att jag skickade just det tecknet. Inget annat, bara ett F. Varken den decimala versionen eller ASCII eller så. Jag förmodar, inte helt säker, att jag egentligen vill skicka hex.

Jag använder AVR Studio 6, där en fin liten terminal klient kan installeras.. Väldigt enkel men verkar fungera bra. När jag ställde in den på att skicka hex och bara skickade ett tecken, exempelvis F. Då blev resultatet korrekt även med bit_is_set. För då blev resultatet bara 4 bitar och det är ju ultimat det jag ville ha.

Skickade jag två tecken, som en 8-bitars ..? Eh, jag skickade två tecken i hex som resulterar i 8-bitar, då blev resultatet att processorn behövde 8 lysdioder för att visa hela värdet. Även här helt korrekt! Eller, som jag vill ha det vill säga.


Jag förstår det ni skriver om ASCII och givetvis, skickar man ASCII tecken så blir det helt "fel" för det jag tänkt.

Vidare kan jag själv konvertera mellan de olika formerna utan problem, Hex->Binärt->Decimal->Hex->Decimal->Binärt.. Alla olika kombinationer, men jag förstår inte riktigt hur processorn gör det, inte mindre vad datorn gör när den skickar ut värden på serieporten.


Det jag är oroad över är, jag har ju fått det att fungera som jag vill, tror jag.. Med att ställa in terminalen i AVR Studio till att skicka hex. Vad är det då den skickar när jag exempelvis skickar ett "F" ? Skickar den fyra siffror, dvs binärt? 1111

Eller skickar den bara F som det är och instruerar mottagaren att det är ett hex värde? Hur då? 0xF?

För inte kan den väl skicka F som ASCII, för det motsäger ju funktionen att jag valt att skicka som hex och att då skulle jag ju inte få rätt output på mina lysdioder på processorn.. Så att skicka som ASCII är ju bara att stryka.


Det jag i slutändan vill, är att skicka ett rent tecken, som en del av en HEX kod. dvs, skickar jag F ska jag ha fyra bitar 1111. Skickar jag ett till tecken efter ex. 3 ska jag ha fyra bitar till 0011.


En fråga till, hur säkerställer jag att jag kan skicka ut detta både från dator, men även mellan AVR via UARTen? Jag har tittat på flera bibliotek och source koder, men jag kan inte hitta att detta går att ställa in eller liknande någonstans.. :?


Edit...
Jag blandar ihop namn, beskrivningar osv.. Försök ha överseende med det ;)

Det jag vill använda är bas 16, dvs hex. 0123456789ABCDEF. Sen vill jag inte "bry" mig om vad ASCII representationen ska bli, utan endast använda de enskilda bitarna som varje bas 16 tecken står för.

F = 1111
A = 1010
9 = 1001
3 = 0011
0 = 0000

Aaaahh.. det blir så krångligt, men jag hoppas att ni förstår.. hoppas verkligen :P


Edit2...
Jag har nu testat att skicka en sträng med tecken, 0-F, som hex.. De tas upp som 4-bitar två åt gången, dvs ett helt 8-bitars nummer. Jag ser det genom att lägga en delay efter att jag tagit emot data på UARTen.

Om jag kan förklara det bara.. Efter två hex tecken, ex F0 så sker en delay på 200ms. Vilket betyder att min buffert för UARTen fungerar :D

Så om jag skickar F120F6F5 så tas de upp i form av F1 delay 20 delay F6 delay F5 och visar detta då över alla 8 lysdioderna som en 8-bitars sträng.

Fortfarande, skickar jag bara ett hex tecken så är det bara fyra bitar som visas på lysdioderna, vilket också är helt korrekt.

Snacka om att jag är nöjd så här långt :D

Denna sista edit kanske inte har så mycket med frågorna i tråden att göra, ville nog mest bara dela med mig :D
Senast redigerad av toffie 23 juli 2012, 10:44:22, redigerad totalt 1 gång.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: AVR C fråga, bit_is_clear/set vimsig?

Inlägg av sodjan »

> Här ska då processorn se att bit 7 är satt och göra en specifik sak på grund av det, bit 3 och 4 aktiverar andra funktioner osv.

Det finns "bit test" instruktioner för det. Alltså assembler/maskin instruktioner.
Sen finns det andra sett att göra "bit test" i C. Se t.ex :
http://en.wikipedia.org/wiki/Bit_manipu ... g_language

> Inget annat, bara ett F...

När du skriver "ett F" så kan det inte tolkas på annat sätt än bokstaven F enligt ASCII.
Alltså 46 i hex eller "01000110" binärt.

> Det jag "vill" i slutändan är att jag ska kunna skicka exempelvis två bitar, en byte, ett helt tecken.

En USART skickar alltid och tar emot antingen 8 bitar (vanligast) eller 7 bitar.

> Jag förmodar, inte helt säker, att jag egentligen vill skicka hex.

Det beror på vad du menar med att "skicka hex". Du måste skillja bättre på
faktiska värden och på representationen av dom. "Hex" är bara ett sätt att skriva
värden så att de blir "läsbara" på ett praktiskt sätt. Uttrycket att "skicka hex"
är oegentligt och felaktigt.

> Med att ställa in terminalen i AVR Studio till att skicka hex. Vad är det då den skickar när
> jag exempelvis skickar ett "F" ? Skickar den fyra siffror, dvs binärt? 1111

Sannolikt skickar den alltid 8 bitar. Om du anger "F" så skickas sannolikt "0F", alltså "00001111".
USART'en i din AVR jobbar alltid med *8* bitar.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: AVR C fråga, bit_is_clear/set vimsig?

Inlägg av sodjan »

> Fortfarande, skickar jag bara ett hex tecken så är det bara fyra bitar som visas på lysdioderna, vilket också är helt korrekt.

NEJ NEJ NEJ!
Dina 8 lysdioder visar *alltid* 8 bitar !
Att fyra av dom inte är tända (alltså visar "noll") är ju en helt annan sak...

> > Fortfarande, skickar jag bara ett hex tecken

Det kan du inte, det går helt enkelt inte. Du skickar *alltid* 8 bitar.
Om du bara anger ett hex tecken så kommer det att läggas till en nolla före.
Användarvisningsbild
Icecap
Inlägg: 26652
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: AVR C fråga, bit_is_clear/set vimsig?

Inlägg av Icecap »

Om inte UART'en är en synnerligt speciell version (som inte finns på AVR efter vad jag vet) sänder den en hel byte varje gång!!! OK, den kan kanske ställas till 7, 8, eller 9 bits men jag skulle tro att den står till 8 bit - men det vet du ju bäst själv, det är ju du som ställer registerna i enlighet med databladet eller hur? (Jag har en aning om vad svaret är men jag vill att du själv ska erkänna...)

Så när UART'en tar emot en byte är det just en byte, inget annat.

Om du använder ett terminalprogram och trycker på 0 skickas byten 0x30 över, det motsvarar ASCII-karaktären för noll.
0-9 blir alltså 0x30-0x39 eller om du vill: 0011 1000 - 0011 1001

Sedan skriver du A till F - vilket blir sänd som 0x41 till 0x46 eller binärt: 0100 0001 till 0010 0110.
Skriver du a till f blir det 0x61 till 0x66 eller binärt: 0110 0001 till 0110 0110

När man skriver detta i programmeringssyfte anges 'A' vilket betyder "ASCII tecknet A".
Med 0x41 menas den hexadecimala representation av samma värde som 0100 0001 vilket i decimal blir 65 vilket som ASCII-tecken är 'A'.

Om du vill att terminalprogrammet ska skicka värdet 0x00 till 0x0F behöver du ett terminalprogram som kan det, dessa är rimligt sällsynta dock. Men Ctrl-A blir då 0x01, Ctrl-B blir 0x02 osv. Jag har dock inte hittat hur man sänder nollan... Samtidig ska man ha klart för sig att dessa tecken under ' ' (mellanslag, ASCII 32, 0x20) alla är kontrolltecken.

EDIT: dina bitmönster går alltså:
'0': 0011 0000
'1': 0011 0001
'2': 0011 0010
'3': 0011 0011
'4': 0011 0100
'5': 0011 0101
'6': 0011 0110
'7': 0011 0111
'8': 0011 1000
'9': 0011 1001
'A': 0100 0001
'B': 0100 0010
'C': 0100 0011
'D': 0100 0100
'E': 0100 0101
'F': 0100 0110
Senast redigerad av Icecap 23 juli 2012, 11:22:35, redigerad totalt 1 gång.
Användarvisningsbild
toffie
Inlägg: 1888
Blev medlem: 22 juli 2004, 21:38:07
Ort: Töreboda / Stockholm
Kontakt:

Re: AVR C fråga, bit_is_clear/set vimsig?

Inlägg av toffie »

Tack Sodjan!
Jag använder en C funktion för att se om en bit är satt; bit_is_set
Det går väl bra också?

(började skriva innan ditt andra svar ;) Men jag förstår nog förhoppningsvis nu, som du kanske ser här under)
Nu börjar jag förstå hur det skickas. Det verkar ju ganska logiskt att om jag ställer in terminalen på att skicka hex och då sänder iväg F så borde det bli 0F, sänder jag FF så blir det just FF.

Så vad jag vill göra då i ett program på datorn som ska kommunicera med en AVR som ska förstå är att göra om ett binärt värde 10100011 (hex A3, dec 163) till ASCII versionen som verkar bli ú och sända iväg detta på UARTen?

Samma sak när AVRen ska skicka data.

I grunden vill jag ju arbeta med binära värden för att lämpligen ställa in olika inställningar i processorn. Bit 0 startar en funktion, bit 1 startar en annan osv. Så då måste jag sätta ihop ett 8-bitars binärt värde i processorn, som sen omvandlas till ett ASCII tecken, som sen skickas ut på UARTen?

Nej det känns fel.. Eller? om jag exempelvis vill skicka det binära 10011001 så blir det ju U som ASCII representation. Det borde väl betyda att jag skickar U som ASCII tecken? (i hex blir det två femmor, 55), för att få fram det rätta binära till mottagaren?

Fungerar detta verkligen för ASCII koder som de 31 första i ASCII alfabetet? ex. 00011011 (1B) som ska vara "escape"? Det är ju inget synligt tecken, bara någon sorts "kommando"? (Icecap tar upp det)

Krångligt helt klart.. för mig i alla fall ;)


I övrigt väldigt bra skrivet och när du skriver det, man ställer ju in både UARTen att jobba med just 8 bitar men även terminalprogrammet på datorn att använda 8 "Data bits". Så det var ju lätt att förstå när man väl kom dit :D Tack!



Jaha.. så svarade Icecap medan man skrev också.. :D
Yes, som skrivet ovan har jag satt UARTen till att använda 8 "Data bits", ganska logiskt när jag tänker efter.. (efter ni förklarat förstås ;))

Ah, jo jag tror jag börjar förstå..

Jag tror att jag behöver tänka mer på att jag ska använda ASCII när jag skickar över data och sedan tolka det binärt i mina funktioner i processorn för att göra om varje bit till det jag vill ha det till.

Jag blandar in hex bara för att det är ju en annan presentation av både den binära, decimala och ASCII versionen av det jag skickar. Blir det rätt tänkt?

Så vad jag behöver är att tänka ASCII och binärt.. "det räcker!" Är det korrekt?


Edit..
Så.. dessa kontrolltecken som jag skrev om ovan.. De "får" man inte använda i kommunikationen då eller? Blir det konstigheter eller räcker det med att ens terminalprogram alt. egenskrivna kommunikationsprogram som ska prata med AVR'en samt att AVR'en kan skapa/läsa dessa tecken för att det ska fungera?
Användarvisningsbild
Icecap
Inlägg: 26652
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: AVR C fråga, bit_is_clear/set vimsig?

Inlägg av Icecap »

Vad du får använda beror helt på hur din kommunikation tolkar allt - men använder du ett terminalprogram till att skicka tecken ska du veta om detta för att få en vettig kommunikation helt enkelt.

Av samma orsak använder jag "alltid" ASCII-kommunikation. Ska jag alltså överföra värdet 0x73 skickar jag "73", alltså ASCII-tecknen '7' och '3'. Sedan läsas detta av mottagaren och omvandlas till binärt värde om det behövs. Fördelen är att man kan "sniffa" kommunikationen utan problem.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: AVR C fråga, bit_is_clear/set vimsig?

Inlägg av sodjan »

> Jag använder en C funktion för att se om en bit är satt; bit_is_set
> Det går väl bra också?

Jag antar det, finns det ingen dokumentation ?

> Så vad jag vill göra då i ett program på datorn som ska kommunicera med en AVR som ska förstå är att göra om
> ett binärt värde 10100011 (hex A3, dec 163) till ASCII versionen som verkar bli ú och sända iväg detta på UARTen?

Ja, alltså. Över seriekommunikationen skickas det alltid 8 bitar. Hur du i din kod väljer att
ange vilket värde/tecken som ska skickas beror enbart på vad som är enklast och vad
som värdet "står för" så att säga.

Antag att du vill skicka bokstaven A, då finns det ju ingen anledning att ange det som 0x41 eller "01000001".
Det är ju mycket enklare att bara skriva "A" (på det sätt som den aktuella programmeringsspråket vill ha det).

Om du däremot vill skicka något där de olika bitarna har egna funktioner så skriver man det binärt.
Antag bitar 0-7 och att du vill skicka ett värde där bit 6 och bit 1 är "on", så skickar du "01000001".
Att detta, tolkat som ASCII, råkar vara bokstaven "A" är i detta fall *fullständigt ointressat och irrelevant* !
Det finns ingen som helst anledning att i detta fall skriva det som "A", det enbart förvillar och gör koden svårläst.

Så använd det skrivsätt som är mest rellevant för det aktuella behovet :0
- Skickar du text, använd ASCII.
- Skickar di bitmönster, använd binära värden.
- Skickar du "värden", används hex eller decimalt, beroende på omständigheterna.

Själva seriekommunikationen ser bara 8 bitars bytes, den har inte en susning om vad
"hex", "ASCII" o.s.v är ! Det är enbart skrivsett för att göra koden enklare för *oss*...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: AVR C fråga, bit_is_clear/set vimsig?

Inlägg av sodjan »

> Så.. dessa kontrolltecken som jag skrev om ovan.. De "får" man inte använda i kommunikationen då eller?

Tja, själva kommunikationen (d.v.s de två USART'arna i varje ände, en i AVR'en och en i PC'n)
kommer inte att bry sig, de överför vilket 8 bitars värde som helst mellan 0x00 oxh 0xFF.

Däremot så kan det uppstå olika fenomen i nästa "lager" så att säga. T.ex så finns det
ju vanliga ASCII tecken som heter CR och LF som har väldigt väl standardiserade funktioner.
("Carriage Return" och "Line Feed".)

Om man har en rent binär överföring så kommer det ju någongång att bli ett värde som
motsvarar just CR eller LF (eller ESC eller något annat ASCII kontroll-tecken, i princip
de lägsta 32 tecknen) och detta kan få oväntade följder. Dessutom, som Icecap skriver,
det hela blir mycket jobbigare att felsäka, t.ex med ett terminalprogram just så som du gör.
Användarvisningsbild
toffie
Inlägg: 1888
Blev medlem: 22 juli 2004, 21:38:07
Ort: Töreboda / Stockholm
Kontakt:

Re: AVR C fråga, bit_is_clear/set vimsig?

Inlägg av toffie »

Icecap
Men nu blandar du in "hex" i det hela.. Fy dig!! :P
Så när du då skickar 7 och 3 så blir det binärt i mottagaren 00110111 och 00110011? I sådant fall förstår jag helt och hållet.
Annars vet jag inte.. :?

Jag förstår även att terminalprogrammen kanske inte klarar de lägsta bitarna, men det gäller väl ända upp till decimal 31 i ascii tabellen? (hex 1F) (ja som Sodjan skriver) Chansen att jag exempelvis kommer in på 0F finns ju, så jag vill ju gärna kunna använda de koderna också. Anledningen till det är ju att jag vill använda koderna som en 8-bitars sträng med 8 olika inställningar med på/av.

Sedan behöver man ju definiera ett start och stopp tecken som inte får användas i övrigt. Vilket förresten är ganska svårt.. Eller kanske inte.. Om man exempelvis bestämmer att binära 00000000 endast får användas som start och 00000001 får användas som stopp så kanske det går. Chansen att man får en sådan inställningskod är väldigt liten, möjligheten att man får den får man helt enkelt sätta stopp för.

Nu vet jag inte hur många inställningskoder man kan behöva, men på en 8-bitars sträng blir det väl 256 möjligheter. Låser man då bort kanske en fjärdedel till direkta kommandon som startar funktioner i processorn, så kan man använda 3/4 till utbyggnad av kommunikationsspråket (på något sätt).
Låter det vettigt?


Sodjan
Jo klart det borde finnas :roll: Jag tror mig förstå att det ska vara en bra funktion att använda för ändamålet och jag har sett i exempel hur den används. Jag tror det ska vara korrekt. Fast jag kommer nog få använda varianten bit_is_clear när jag slutar arbeta med lysdioderna ;) Men det är jag med på noterna om.
http://www.nongnu.org/avr-libc/user-man ... d6ea6bd0d9

Ah, va bra beskrivet Sodjan!
Men du säger, om jag vill "skicka något där de olika bitarna har egna funktioner så skriver man det binärt", då menar du att jag ska skicka 01000001.. Betyder det att jag ska skicka de som ASCII tecken? vilket binärt då blir
00000000 00000001 00000000 00000000 00000000 00000000 00000000 00000001

För jag vet inte hur jag annars skulle kunna skicka ett binärt värde.

Själva anledningen till att skicka 01000001 som ett ASCII värde är just för att det blir 8 bitar istället för 8*8 bitar som skickas. Förstår du hur jag menar? Detta endast, om du menar att jag ska skicka det binära värdet som ASCII tecken. Men du kanske har något annat i bakfickan att berätta om?


Ditt andra inlägg, jo jag förstår att kontrolltecknen används för CR, LF osv, som på linux ensamt skapar ny rad och i Windows? tillsammans skapar en ny rad. Givetvis tar ju terminalprogrammen det som att de ska göra just en ny rad istället för att exempelvis visa den binära representationen.

Men om man då skapar ett program på datorn som tolkar exempelvis kontrolltecknet CR (00001101), och visar det i binär form utan att det används för att skapa en ny rad, då "bör" det fungera?

Går det att göra/är det nödvändigt att göra detta i AVR'en? För det "övre lagret" som tolkar kontrolltecken finns väl inte i AVR'en om jag inte skapar det själv?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: AVR C fråga, bit_is_clear/set vimsig?

Inlägg av sodjan »

Om jag förstår det hela rätt så vill du skicka on/off kommandon för olika funktioner.
Och du har tänkt att koda dessa som individuella bitar i en byte (?).

Du kanske skulle fundera på ett enkelt protokoll för det hela. Det skulle t.ex
kunna vara något i stil med :

- Sätt funktion 3 "på" : "F1,3<CR>".
- Sätt funktion 5 "av" : "F0,5<CR>".

Alltså : [kommando][kommatecken][parameter]<CR>.

För att göra det hela enklare att avkoda i AVR'en, så kan du standardisera kommando till 2 tecken.
Hur parametern/parametrarna ser ut kan ju vara variabelt beroende på vilket kommando det är
men enklast är ju att standardisera det till en byte. En CR avslutar det hela och talar också om
för AVR'en att "nu har ett komplett kommando mottagits".

Som du ser av detta exempel så kan [parameter] inte skickas binärt eftersom det då skulle
kunna komma ett CR i denna position, vilket det *inte* får göra.

Detta format är också väldigt enkelt att testköra från t.ex en terminal på PC'n utan att
behöva strula med hex värden.

Sen vill man sannolikt ha kommandon som t.ex :

- Hello : "H1,0<CR>" (För att kolla om AVR'en är "vaken" vilken då svarar på lämplig sätt).
- Restart : "R1,0<CR> (Starta om firmware i AVR'en).
- Status : "S1, 3<CR> (AVR'en svarar med aktuellt status (on/off) för funktion nr 3).

AVR'en bör även skicka något lämpligt meddelande direkt när den har
starat upp så att PC'n vet att starten/omstarten gick bra.

O.s.v. :-)
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: AVR C fråga, bit_is_clear/set vimsig?

Inlägg av sodjan »

> För jag vet inte hur jag annars skulle kunna skicka ett binärt värde.

Hela diskussionen kring "hex", "ascii", "binärt" o.s.v har *enbart* med hur man
anger olika värden i själva C-koden. Överföringen mellan USART'erna sker
alltid binärt, en bit i taget, så att säga. :-)

Du har fortfarande lite svårt att skillja på hur du representerar olika värden
i själva C-koden och vad som sker i den färdiga (kompilerade) koden och i USART'en...

Att skriva ett värde i hex, binärt eller som ett ASCII tecken är *EXAKT SAMMA SAK* !
Och det ger exakt samma kompilerade kod i AVR'en.

På samma sätt som det inte är någon skillnad på 105 och "etthundrafem".
Det är också exakt samma sak, bara skrivet på lite olika sätt, men "kompilerat"
inne i våra hjärnor är det inget skillnad... :-)

Det jag försökte säga är att vilken representation som du väljer att använda
i din C-kod beror på vad värdet står för. Om det viktiga är att det är just
bokstaven "A" som du skickar, så skriver du bokstaven "A" (på lämligt sätt).
Annars väljer du det som passar bäst.

> Men om man då skapar ett program på datorn som tolkar exempelvis kontrolltecknet CR (00001101),
> och visar det i binär form utan att det används för att skapa en ny rad, då "bör" det fungera?

Ja, på AVR'en (där det inte finns något operativsystem mellan USART'en och din kod) så är det
inget problem. På Windows/Linux eller något annat, så kommer terminalrivern som ligger mellan
USART'en och din kod att sannolikt själv "trigga" på vissa kontrolltecken.

> För det "övre lagret" som tolkar kontrolltecken finns väl inte i AVR'en om jag inte skapar det själv?

Exakt. Den saknar ju operativsystem...

> Givetvis tar ju terminalprogrammen det som att de ska göra just en ny rad istället för att exempelvis visa den binära representationen.

Precis, det är därför en rent binär kommunikation är svår att felsöka med en
vanlig terminalemulator, det blir konstiga "return" och "ny rad" mitt i de värden
som man försöker "se" och tolka...
Skriv svar