Nybörjare i behov av get-started-hjälp med AVR MCU
Nybörjare i behov av get-started-hjälp med AVR MCU
Hej,
Jag har skrivit här tidigare, för några månader sedan, då jag hade tänkt börja med ett litet projekt. Har varit upptagen tills nu, så jag har tyvärr inte hunnit. Nu är jag är redo att börja igen. =)
En fråga:
- Exakt hur fungerar det med DDRx, Portx och Pinx, dvs vad 1/0 resp input/output betyder för dessa? Har inte hittat någonstans där systemet är printat. Skriv gärna också varför det är som det är, tänker då främst på resistans (pullup?). En enkel sammanfattning vore väldigt uppskattad.
Mvh
Simon
Edit: Rubrik/blueint
Jag har skrivit här tidigare, för några månader sedan, då jag hade tänkt börja med ett litet projekt. Har varit upptagen tills nu, så jag har tyvärr inte hunnit. Nu är jag är redo att börja igen. =)
En fråga:
- Exakt hur fungerar det med DDRx, Portx och Pinx, dvs vad 1/0 resp input/output betyder för dessa? Har inte hittat någonstans där systemet är printat. Skriv gärna också varför det är som det är, tänker då främst på resistans (pullup?). En enkel sammanfattning vore väldigt uppskattad.
Mvh
Simon
Edit: Rubrik/blueint
Senast redigerad av sica06 7 november 2008, 00:43:03, redigerad totalt 1 gång.
Jag tycker inte att man ska behöva gissa vad det är för
processorer du tänker jobba med, men det ser i alla fall ut som AVR...
På fråga 1 så är jag övertygad att databladet har en full och komplett
förklaring. Det är bättre att du talar om vad du inte förstog från databladet
så att vi kan fokusera på just det. Det är ju lite onödigt att *här* förklara
sådan som du redan har fattat...
På fråga 2 så får någon svara som kan de verktygen, men jag har i alla
fall en liten kommentar...
> När jag ändå väljer någon så får jag felmeddelande...
Right, *VILKET* felmeddelande ?
processorer du tänker jobba med, men det ser i alla fall ut som AVR...
På fråga 1 så är jag övertygad att databladet har en full och komplett
förklaring. Det är bättre att du talar om vad du inte förstog från databladet
så att vi kan fokusera på just det. Det är ju lite onödigt att *här* förklara
sådan som du redan har fattat...
På fråga 2 så får någon svara som kan de verktygen, men jag har i alla
fall en liten kommentar...
> När jag ändå väljer någon så får jag felmeddelande...
Right, *VILKET* felmeddelande ?
Jag håller medsodjan,det ser ut att kunna vara fråga om AVR.
Nu kommer jag helt fräckt att anta att vi snackar om AVR i programspråket C.
DDRx(Data Direction Register), här anger argumentet vilka pinnar som är ingångar resp. utgångar. 1'a betyder utgång. Default är alla I/O satta till ingångar(nollade). Om du vill sätta pinnarna PB5-PB7 till utgångar, och resten till ingångar skriver du: alternativt:
PORTx har 2 funktioner. Om DDRx på önskad pinne är satt till '0', ingång. Då kommer en 1'a på PORTx att innebära att pull-up-resistorn kopplas in, och en 0'a att den kopplas ur.
Här aktiveras alltså ingång PB0s pull-up-resistor.
Är DDRx däremot satt till utgång kommer skrivning till PORTx att sätta pinnen till önskat värde.
Här kommer utgångarna PB5-PB7 att sättas till 1'a, utgångarna PB3-PB4 sättas till 0'a och ingångarna PB0-PB2 att inte att ha pull-up aktiverad.
PINx används för att läsa det digitala värdet på en ingång(egentligen alla 8 ingångarna på en port, men man kan maska bort dom övriga 7). Enklast att kolla med en if-sats. Säg att hela Port B är satt till ingång och vi vill kolla värdet på PB3:
Hoppas att detta kan hjälpa dig en bit på vägen.
Nu kommer jag helt fräckt att anta att vi snackar om AVR i programspråket C.
DDRx(Data Direction Register), här anger argumentet vilka pinnar som är ingångar resp. utgångar. 1'a betyder utgång. Default är alla I/O satta till ingångar(nollade). Om du vill sätta pinnarna PB5-PB7 till utgångar, och resten till ingångar skriver du:
Kod: Markera allt
DDRB = 0b11100000;
Kod: Markera allt
DDRB = 0xE0;
Kod: Markera allt
DDRB = 0b00000000;
PORTB = 0b00000001;
Är DDRx däremot satt till utgång kommer skrivning till PORTx att sätta pinnen till önskat värde.
Kod: Markera allt
DDRB = 0b11111000;
PORTB = 0b11100000;
PINx används för att läsa det digitala värdet på en ingång(egentligen alla 8 ingångarna på en port, men man kan maska bort dom övriga 7). Enklast att kolla med en if-sats. Säg att hela Port B är satt till ingång och vi vill kolla värdet på PB3:
Kod: Markera allt
DDRB = 0b00000000; //Kan tyckas onödigt, då den initieras till detta
if((PINB & 0b00001000) == 0b00001000) LightCandle(); //Maskar ut bit 3, kollar om den är '1', och i så fall anropar funktionen LightCandle()
Är inte det där i princip bara en avskrift/tolkning av vad databladet säger ?
Och är det inte en risk att man gör en tabbe när man skriver själv
som bara förvillar mer än hjälper (jag säger inte att det var så här). Eller
att man missar något viktigt ? Jag tycker att det är bäst att invänta besked
om vad det igentligen var som var oklart, så att man vet att man "svarar"
på rätt saker. OK, vem som helst får skriva vad som helst, så klart, men
jag är inte övertyygad att det alltid är det bästa och det som hjälper mest.
Och är det inte en risk att man gör en tabbe när man skriver själv
som bara förvillar mer än hjälper (jag säger inte att det var så här). Eller
att man missar något viktigt ? Jag tycker att det är bäst att invänta besked
om vad det igentligen var som var oklart, så att man vet att man "svarar"
på rätt saker. OK, vem som helst får skriva vad som helst, så klart, men
jag är inte övertyygad att det alltid är det bästa och det som hjälper mest.
Stinrews svar må vara en avskrift/tolkning, men å andra sidan bad ju frågeställaren om en sammanfattning...
Vad som var oklart är väl relativt klart
. Frågeställaren:
* förstår inte skillnaden mellan DDR,PORT och PIN, vilket stinrew förklarade
* hittar inget RTL schema för utgången (t.ex. figur 23 & 24 under "I/O Ports" i databladet för atmega 88 )
* Önskar en sammanfattning och kan möjligen beskyllas för slöhet då han inte orkar RTFM. Å andra sidan är databladet rätt långt och en sammanfattning kan nog spara honom en vecka eller två.
Vad som var oklart är väl relativt klart

* förstår inte skillnaden mellan DDR,PORT och PIN, vilket stinrew förklarade
* hittar inget RTL schema för utgången (t.ex. figur 23 & 24 under "I/O Ports" i databladet för atmega 88 )
* Önskar en sammanfattning och kan möjligen beskyllas för slöhet då han inte orkar RTFM. Å andra sidan är databladet rätt långt och en sammanfattning kan nog spara honom en vecka eller två.
Tack för hjälpen!
Ja, jag var otydlig där, det gäller AVR.
Jag undrar också exakt vad som händer när jag 1/0 DDRx och Portx.
Alltså, du menar:
1. Om DDRB är satt till 0 så gäller ingång, resp utgång vid 1. Detta betyder alltså vid 1 så skickar MCU'n en signal (oftast 5v) ut på den pinnen. Vid 0 är den redo att ta emot en motsvarande signal på den pinnen?
Försöker förstå PORTB:
2. Om DDRB är satt till 1 (utgång) och motsvarande pinne sätts till 0 på PORTB, så kommer en signal att gå ut på den pinnen, om PORTB däremot är satt till 1 på motsvarande pinne så kommer signalen ej att gå ut - PORTB aktiverar helt enkelt en resistans så att signalen ej går igenom?
(Jag antar också att samma gäller om DDRB är satt till 0 (ingång), dvs att signalen går fram till pinnen om resistorn inte är aktiverad (0).)
- Om det fungerar så, varför?
3. Är lite osäker på hur du menar att PINB skiljer sig från de andra. Menar du att istället för att kolla om DDRB skickar eller ta emot signaler på vissa pinnar, så kollar PINB på själva signalerna för att avgöra om det skickas eller tas emot på vissa pinnar?
Mvh
Simon
Ja, jag var otydlig där, det gäller AVR.
Jag undrar också exakt vad som händer när jag 1/0 DDRx och Portx.
Alltså, du menar:
1. Om DDRB är satt till 0 så gäller ingång, resp utgång vid 1. Detta betyder alltså vid 1 så skickar MCU'n en signal (oftast 5v) ut på den pinnen. Vid 0 är den redo att ta emot en motsvarande signal på den pinnen?
Försöker förstå PORTB:
2. Om DDRB är satt till 1 (utgång) och motsvarande pinne sätts till 0 på PORTB, så kommer en signal att gå ut på den pinnen, om PORTB däremot är satt till 1 på motsvarande pinne så kommer signalen ej att gå ut - PORTB aktiverar helt enkelt en resistans så att signalen ej går igenom?
(Jag antar också att samma gäller om DDRB är satt till 0 (ingång), dvs att signalen går fram till pinnen om resistorn inte är aktiverad (0).)
- Om det fungerar så, varför?
3. Är lite osäker på hur du menar att PINB skiljer sig från de andra. Menar du att istället för att kolla om DDRB skickar eller ta emot signaler på vissa pinnar, så kollar PINB på själva signalerna för att avgöra om det skickas eller tas emot på vissa pinnar?
Mvh
Simon
Sica: Se figurerna jag nämnde i databladet, de visar precis på gate-nivå hur det hänger ihop.
Svar på 3: PIN läser vad som verkligen finns på pinnen. PORT innehåller vad du önskar ska finnas på pinnen. Sätter du PORT till 1 men kortsluter pinnen till 0 så kommer PIN att läsa 0 och inte 1 (och din avr blir varm). Detta framgår av de tidigare nämnda figurerna
Svar på 3: PIN läser vad som verkligen finns på pinnen. PORT innehåller vad du önskar ska finnas på pinnen. Sätter du PORT till 1 men kortsluter pinnen till 0 så kommer PIN att läsa 0 och inte 1 (och din avr blir varm). Detta framgår av de tidigare nämnda figurerna
Fortfarande så är det databladet som har det korrekta och kompletta svaret, så *kolla där* !
1. Exakt!
(Förrutom att "skicka" och "ta emot" inte är bra begrep i sammanhanget,
det hela handlar om nivåer, det är inget som rör på sig...).
2. Nej.
Om pinnen är en utgång (styrs av DDRx) så sätts den till 0 eller 1 via PORTx (alltså de logiska nivåerna
"låg" resp "hög" eller de elektriska nivåerna "0V" eller "5V", förutsatt att processorn drivs med 5V).
Om en pinne är en ingång, så läser man bara av den med PINx (och eventuell intern
pull-up styrs av PORTx registret, men det kan du glömma tillsvidare).
3. Nej.
DDRx styr om en pinne ska vara utgång eller ingång. Den varken skickar eller gör något annat!
PINx används för att läsa av den aktuella nivån på pinnen (oavsett hur DDRx är konfigurerat).
Säg inte "skickas" och "ta imot" om pinnarna, det rör bara till det för dig.
Det är ingenting som "rör på sig", allt handlar om nivåer (d.v.s "hög" resp "låg"
eller "1" resp "0").
1. Exakt!
(Förrutom att "skicka" och "ta emot" inte är bra begrep i sammanhanget,
det hela handlar om nivåer, det är inget som rör på sig...).
2. Nej.
Om pinnen är en utgång (styrs av DDRx) så sätts den till 0 eller 1 via PORTx (alltså de logiska nivåerna
"låg" resp "hög" eller de elektriska nivåerna "0V" eller "5V", förutsatt att processorn drivs med 5V).
Om en pinne är en ingång, så läser man bara av den med PINx (och eventuell intern
pull-up styrs av PORTx registret, men det kan du glömma tillsvidare).
3. Nej.
DDRx styr om en pinne ska vara utgång eller ingång. Den varken skickar eller gör något annat!
PINx används för att läsa av den aktuella nivån på pinnen (oavsett hur DDRx är konfigurerat).
Säg inte "skickas" och "ta imot" om pinnarna, det rör bara till det för dig.
Det är ingenting som "rör på sig", allt handlar om nivåer (d.v.s "hög" resp "låg"
eller "1" resp "0").
Hittade detta i bladet nu (sida 73-74) och har läst det.
Måste säga att jag blev mindre klok än tidigare, men det beror väl på att jag hade visse bestämda uppfattningar tidigare som inte riktigt stämmer.
Gällande fråga 3 så är vi överens, för det var vad jag egentligen menade, dvs att det den läser ut är det "egentliga" "värdet" på pinnen.
Jag blir dock konfunderad över fråga 2:
- När både DDRB och PORTB är 1, så blir det HIGH på den pinnen. Då menar ni att 5V lägger sig på den pinnen. Detta låter helt logiskt även för mig, mitt problem är dock att detta går stick i stäv med utfallet av den minimala kodning jag har gjort hittills på en AT90s8515. När jag sätter DDRB till 0xFF och PORTB till 0xFE så tänds endast en diod av åtta (och inte sju) - det borde väl med ovan logik vara tvärtom, eller?
Mvh
Simon
Måste säga att jag blev mindre klok än tidigare, men det beror väl på att jag hade visse bestämda uppfattningar tidigare som inte riktigt stämmer.
Gällande fråga 3 så är vi överens, för det var vad jag egentligen menade, dvs att det den läser ut är det "egentliga" "värdet" på pinnen.
Jag blir dock konfunderad över fråga 2:
- När både DDRB och PORTB är 1, så blir det HIGH på den pinnen. Då menar ni att 5V lägger sig på den pinnen. Detta låter helt logiskt även för mig, mitt problem är dock att detta går stick i stäv med utfallet av den minimala kodning jag har gjort hittills på en AT90s8515. När jag sätter DDRB till 0xFF och PORTB till 0xFE så tänds endast en diod av åtta (och inte sju) - det borde väl med ovan logik vara tvärtom, eller?
Mvh
Simon
>>BEEP, jag förstår inte riktigt vad du menar med "lysdioderna på den kopplade till plus" och vad det egentligen innebär, men, JA - det är en STK500.
Men om vi bortser från det jag skrev innan och helt enkelt utgår från att två logiska ettor innebär Output High. Då undrar jag vad det innebär att DDRB är 0 (input) och PORTB 0 eller 1?
Vore tacksam om någon kunde förklara, i text, varför dessa funktioner finns. Försöker få en helhetssyn över det så att jag kan förstå varför jag programmerar som jag gör.
Vad är tanken bakom PINB, varför finns det ett kommando som på något vis kör över de andra? På sida 74 står det om Pin configurations, är PUD (MCUCR) lika med "PIN"?
Men om vi bortser från det jag skrev innan och helt enkelt utgår från att två logiska ettor innebär Output High. Då undrar jag vad det innebär att DDRB är 0 (input) och PORTB 0 eller 1?
Vore tacksam om någon kunde förklara, i text, varför dessa funktioner finns. Försöker få en helhetssyn över det så att jag kan förstå varför jag programmerar som jag gör.
Vad är tanken bakom PINB, varför finns det ett kommando som på något vis kör över de andra? På sida 74 står det om Pin configurations, är PUD (MCUCR) lika med "PIN"?
> JA - det är en STK500.
OK, eftersom lysdioderna tydligen är anslutna till 5V på dessa, så blir
det ju precis så som du beskrev det. Inget problem alltså.
> Då undrar jag vad det innebär att DDRB är 0 (input) och PORTB 0 eller 1?
Sidan 63-63 har en perfekt beskrivning av det.
Det är enklare att förstå vad som är problemet om du anger
mer exakt vad som är oklart i den beskrivningen. Om DDRx är "0"
så styr PORTx pullup på/av.
Jag kan klippa in texten här i tråden också, men det verkar lite onödigt.
> varför dessa funktioner finns.
För att få lite fler alternativ som utvecklare. Vad man sedan väljer att
använder beror på vad man håller på med i varje aktuellt fall.
> Vad är tanken bakom PINB,
Att man ska kunna läsa *pinnen* direkt, oberoende av hur PORTx är satt.
> varför finns det ett kommando som på något vis kör över de andra?
Vilket *kommando* gör det ?
> På sida 74 står det om Pin configurations, är PUD (MCUCR) lika med "PIN"?
Jag hittar ingenting om "PUD" någonstans i databladet (DOC0841).
Var har du hittat något om det ??
OK, eftersom lysdioderna tydligen är anslutna till 5V på dessa, så blir
det ju precis så som du beskrev det. Inget problem alltså.
> Då undrar jag vad det innebär att DDRB är 0 (input) och PORTB 0 eller 1?
Sidan 63-63 har en perfekt beskrivning av det.
Det är enklare att förstå vad som är problemet om du anger
mer exakt vad som är oklart i den beskrivningen. Om DDRx är "0"
så styr PORTx pullup på/av.
Jag kan klippa in texten här i tråden också, men det verkar lite onödigt.
> varför dessa funktioner finns.
För att få lite fler alternativ som utvecklare. Vad man sedan väljer att
använder beror på vad man håller på med i varje aktuellt fall.
> Vad är tanken bakom PINB,
Att man ska kunna läsa *pinnen* direkt, oberoende av hur PORTx är satt.
> varför finns det ett kommando som på något vis kör över de andra?
Vilket *kommando* gör det ?
> På sida 74 står det om Pin configurations, är PUD (MCUCR) lika med "PIN"?
Jag hittar ingenting om "PUD" någonstans i databladet (DOC0841).
Var har du hittat något om det ??
- Swech
- EF Sponsor
- Inlägg: 4750
- Blev medlem: 6 november 2006, 21:43:35
- Ort: Munkedal, Sverige (Sweden)
- Kontakt:
Anledningen till att man har både PORT, PIN och DDR register är
det begränsade antalet ben på processorn.
Processortillverkaren vet inte om deras kunder vill styra en massa lysdioder
(utgångar) eller ansluta en massa knappar (ingångar) till processorn
Så... lösningen är att man kan programmera en pinne på processorn att
vara ingång eller utgång
Processorn har internt ett antal 8 bitars register för utgångar
- dessa kallas PORTx x kan vara A,B,C,D,E beroende på vilken AVR man har
Sen finns samma antal 8 bitars register för ingångar.
- dessa kallas PINx x kan vara A,B,C,D,E beroende på vilken AVR man har
Nu måste vi ha ett sätt att välja om pinnen på processorn skall vara en
ingång eller utgång, Den kan inte vara båda delarna samtidigt
(egentligen kan den vara det men det är överkurs)
Nu använder vi DDR registret.
Detta bestämmer om pinnarna skall vara ingågar eller utgångar.
Exempel
DDRA = 00001101 -> PA3,PA2 och PA0 är utgångar.
Övriga PA7,PA6,PA5,PA4,PA1 är ingångar.
Skriver vi nu 0000001 till PORTA så kommer PA3 och Pa2 vara 0. Pa0 kommer att vara 1
För att läsa av t.ex. tryckknappar som är anslutna till
PA7,PA6,PA5,PA4,PA1 i vårt exempel så läser vi
från PINA. får vi t.ex. tillbaks 11011000 innebär det att
PA7=1 PA6=1 PA5=0 PA4=0 PA3,Pa2 är utgångar, PA1=0, PA0 är en utgång
Hoppas att det klarnat....
Swech
det begränsade antalet ben på processorn.
Processortillverkaren vet inte om deras kunder vill styra en massa lysdioder
(utgångar) eller ansluta en massa knappar (ingångar) till processorn
Så... lösningen är att man kan programmera en pinne på processorn att
vara ingång eller utgång
Processorn har internt ett antal 8 bitars register för utgångar
- dessa kallas PORTx x kan vara A,B,C,D,E beroende på vilken AVR man har
Sen finns samma antal 8 bitars register för ingångar.
- dessa kallas PINx x kan vara A,B,C,D,E beroende på vilken AVR man har
Nu måste vi ha ett sätt att välja om pinnen på processorn skall vara en
ingång eller utgång, Den kan inte vara båda delarna samtidigt
(egentligen kan den vara det men det är överkurs)
Nu använder vi DDR registret.
Detta bestämmer om pinnarna skall vara ingågar eller utgångar.
Exempel
DDRA = 00001101 -> PA3,PA2 och PA0 är utgångar.
Övriga PA7,PA6,PA5,PA4,PA1 är ingångar.
Skriver vi nu 0000001 till PORTA så kommer PA3 och Pa2 vara 0. Pa0 kommer att vara 1
För att läsa av t.ex. tryckknappar som är anslutna till
PA7,PA6,PA5,PA4,PA1 i vårt exempel så läser vi
från PINA. får vi t.ex. tillbaks 11011000 innebär det att
PA7=1 PA6=1 PA5=0 PA4=0 PA3,Pa2 är utgångar, PA1=0, PA0 är en utgång
Hoppas att det klarnat....
Swech