Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien
Toon posts:

Moodlight Atmega8535, programmeren

Pagina: 1
Acties:
  • 225 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Hallo :)

Even kort vertellen waarom ik dit topic open. Ik heb met de hulp van wat een paar mensen op Circuitsonline.net een Moodlight gebouwd dat uitendelijk moet draaien op een Atmega8535.
Hij is helemaal afgebouwd, afgezien dat de 3 torren waarmee de leds gestuurd worden nog worden vervangen door de BC337.

Voor mijn moodlight gebruik ik 5 RGB-modules van sk.net (zie hieronder voor een foto). Deze gebruiken per kleur, per module 20mA. Aangezien dit dus in totaal max. 100mA wordt en dit meteen de max is van een bc547 worden deze vervangen door een stelletje bc337's.

Waar het mij uiteindelijk om gaat hier....
Het programmeer werk kan dus beginnen! Het probleem is, ik heb geen enkele programmeer ervaring :X. Mijn vraag is dus, zou iemand mij een zetje in de goede richting kunnen geven. Op welke manier dan ook, goed boek, een heldere tutorial van internet, een eigen voorbeelden, stukje code. Wat dan ook, ik sta overal voor open.

De leds zijn btw aangesloten op 3 PWM uitgangen. Wil de kleuren langzaam in elkaar over laten lopen.

Ik heb AVR Studio 3.5 en Ponyprog al op mijn pc staan. Het lezen/schrijven van de AVR gaat prima heb ik het idee, het programmeer-ledje gaat namelijk dan branden.

Ik hoop dat iemand mij verder kan helpen :).

Alvast bedankt,

Evilcreature




Afbeeldingslocatie: http://aycu06.webshots.com/image/21045/2000723648392388974_rs.jpg
De RGB-modules.

Afbeeldingslocatie: http://aycu18.webshots.com/image/23417/2002106032451959277_rs.jpg
De print met de Atmega8535.

Afbeeldingslocatie: http://aycu11.webshots.com/image/21530/2001407710537114299_rs.jpg
Het schema.

[ Voor 7% gewijzigd door Verwijderd op 23-07-2007 18:55 ]


  • SA007
  • Registratie: Oktober 2002
  • Laatst online: 20-11 21:12

SA007

Moderator Tweaking
Is daar niet gewoon een standaard firmware voor? dan kan je met je programmeerpakket gewoon die erin laden.

Verwijderd

Topicstarter
Een standaard firmwire? Voor mijn Atmega8535, zodat ik mijn leds kan aansturen?

  • blackangel
  • Registratie: April 2002
  • Laatst online: 21:41
De eerste stap is, as usual, altijd om een ledje te laten knipperen. Nu weet ik niet of je in assembly of C wil gaan programmeren. Assembly is leuk, snel, maar niet al te leuk als je de basisprinciepes van programmeren niet weet. Al hoewel, als je de assembly door hebt weet je ook hoe het goed gaat. C is, denk ik, een logischere keus. Je zit dan nog steeds dicht bij de hardware te programmeren, maar het is minder moeilijk.

Dus laten we aannemen dat je wat in C gaat klooien. C heeft altijd een main-program, van waaruit je functies kunt aanroepen.
C:
1
2
3
void main(void) {
  // code
}
(note: void betekend niks. Dat betekend dus, dat wanneer de main-functie is afgesloten er niks wordt teruggegeven. Daarnaast is er geen parameter).

Die code die hierboven staat is dus tamelijk nutteloos, aangezien main wordt aangeroepen, er niks gebeurd, en het programma zich afsluit. Je wil een ledje laten knipperen tenslotte :P Zoals je kunt zien, is het ledje aangesloten op poort D. Om te kunnen schrijven naar poort D, zul je de opdracht moeten geven aan de atmel, dat deze een outputpin is. Het commando hiervan is :

C:
1
TRISD=0x00
(note: dit wordt binair gegeven voor iedere pin. =0xFF geeft dus alles is inputpin.

Goed, dan heb je dus ingesteld dat het een output pin is. Vervolgens wil je er ook wat naar schrijven. Dat kan met de hoogstaande regel:

C:
1
LATD=0x00
(note: alle inputpinnen laag, =0xFF is dus hoog.)

Wat blijft er dan nog over? Je wil het programma constant laten draaien. Dus die code zet je tussen een while-lus. While(true) { ... code ... } dus. C kent geen true, maar 1 is hetzelfde.

C:
1
2
3
4
5
6
7
void main(void) {
  TRISD=0x00;
  while(1) {
    LATD=0x00;
    LATD=0xFF;
  }
}

Het ledje knippert nu \o/. Alleen wel met 1 nadeel, het gaat met een frequentie van ongeveer 1/3e van je kloksnelheid, een aantal MHz dus.

Dit leid tot twee dingen. Ten eerste, je zou een vertraging erin kunnen zetten. Dit kan met de hoogstaande code
C:
1
2
int i;
for(i=0;i<65536;i++);

(note: bij c moet je de declaratie bovenaan in de functie doen).
Erg nuttig, maar niet efficient. De tweede oplossing is door het te doen met interrupts. Dat is iets waar ik wel eens mee heb gewerkt, maar dat zou je zelf mogen uitzoeken.

Goed, maar met het bovenstaande programma is nog een ander iets. Doordat het met 1/3e van de snelheid knippert, heb je dus 1/3e van de power en 1/3e van de lichtopbrengst. En dat wil je uiteindelijk, maar dan ook voor de andere kleurtjes. Dit fenoneem heet PWM, en Atmel's hebben daar hardwarebased functies voor inzitten. Al hoewel ik eerst het knipperen iets beter onder de knie zou krijgen.


Overigens is dit idee rechtsstreeks naar assembly te vertalen, het zei iets moeilijker. Maar aangezien ik nu ga eten, wens ik je alvast veel succes met dit :)


edit:
Zie de opmerking van Sprite hieronder ergens. Paar woordjes verwisseld met een andere architectuur :Y)

[ Voor 2% gewijzigd door blackangel op 23-07-2007 20:01 . Reden: edit en nog wat domme foutjes :P ]


Verwijderd

Topicstarter
Hee, cool! Ik ga er eens mee stoeien :D . Alvast bedankt!!!

  • Sprite_tm
  • Registratie: September 2002
  • Laatst online: 29-10 06:07

Sprite_tm

Semi-Chinees

Waarbij TRISD dus typisch een PIC-register is ;) Je programma zou eerder zoiets moeten zijn:
code:
1
2
3
4
5
6
7
int main(void) {
 DDRD=0;
 while(1) {
  PORTD=0xFF;
  PORTD=0;
 }
}


Zoek vooral ook eens op 'avr tutorial' of 'avr howto' ofzo, er zijn er zat van.

Relaxen und watchen das blinkenlichten. | Laatste project: Ikea Frekvens oog


  • blackangel
  • Registratie: April 2002
  • Laatst online: 21:41
Heb jij ook wel eens dat je een testprogramma opent, maar vergeet of het voor de pic of voor de atmel is? :+

Verwijderd

Topicstarter
Op een of andere manier kom ik er niet uit :? .
Ik heb die code in WinAVR gegooid maar kan hem niet compileren...
Hoe kan ik dat het beste doen. Kom ook op internet de term ''makefile'' tegen, wat moet ik hiermee?

Is er ergens een tutorial waarin stapsgewijs is uitgelegd hoe ik de C code omzet naar een .hex bestand wat ik met PonyProg in mijn Atmel kan zetten?

[ Voor 16% gewijzigd door Verwijderd op 23-07-2007 20:33 ]


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Verwijderd schreef op maandag 23 juli 2007 @ 18:08:
Ik heb AVR Studio 3.5 en Ponyprog al op mijn pc staan.
Als dat versienummer klopt download dan even een nieuwere versie, we zijn ondertussen bij 4.13.
Zorg ook dat je de allernieuwste versie van WinAVR hebt en als het goed is moeten AVR Studio en WinAVR dan samenwerken. Gewoon een GCC project (GCC is de compiler van WinAVR) aanmaken in AVR Studio en je C code erin zetten. Je hoeft dan zelf niets te doen met makefiles. F7 = compileren en de hex file verschijnt vanzelf in je project map. Ook kun je de simulator draaien.

edit: leuke beginners tutorial in het nederlands: http://expand.xs4all.nl/avr/intro.html

[ Voor 7% gewijzigd door madwizard op 23-07-2007 21:20 ]

www.madwizard.org


Verwijderd

Topicstarter
Heb nu de nieuwste AVR Studio gedownload, maar wanneer ik wil compileren krijg ik deze foutmelding:

avr-gcc.exe -mmcu=atmega8535 -Wall -gdwarf-2 -O0 -MD -MP -MT Moodlight.o -MF dep/Moodlight.o.d -c ../Moodlight.c
../Moodlight.c: In function 'main':
../Moodlight.c:2: error: 'DDRD' undeclared (first use in this function)
../Moodlight.c:2: error: (Each undeclared identifier is reported only once
../Moodlight.c:2: error: for each function it appears in.)
../Moodlight.c:4: error: 'PORTD' undeclared (first use in this function)
make: *** [Moodlight.o] Error 1
Build failed with 4 errors and 0 warnings...

Wat moet ik eigenlijk bij ''Debug Platform'' bij de Project wizard invoeren?

[ Voor 9% gewijzigd door Verwijderd op 23-07-2007 22:06 ]


  • ReneK
  • Registratie: Juni 2007
  • Laatst online: 20:51
Verwijderd schreef op maandag 23 juli 2007 @ 18:08:
Voor mijn moodlight gebruik ik 5 RGB-modules van sk.net (zie hieronder voor een foto). Deze gebruiken per kleur, per module 20mA. Aangezien dit dus in totaal max. 100mA wordt en dit meteen de max is van een bc547 worden deze vervangen door een stelletje bc337's.
Ik zie geen enkele vorm van stroombegrenzing voor de led's in je schema (of zit dat
in die modules?). Met 12V voedingsspanning en relatief kleine basisweerstanden
R1 t/m R3 betekent dat een ongecontroleerde stroom door je led's, waarschijnlijk
verniel je ze zodra je ze inschakelt.
Neem dus serieweerstanden op bij de led's om de stroom te begrenzen, 20 mA
is meestal prima. Ook een BC547 volstaat hier prima, hoeft geen BC337 te zijn.

  • rauzer
  • Registratie: Februari 2007
  • Laatst online: 20-04-2024
Verwijderd schreef op maandag 23 juli 2007 @ 21:52:
Heb nu de nieuwste AVR Studio gedownload, maar wanneer ik wil compileren krijg ik deze foutmelding:

avr-gcc.exe -mmcu=atmega8535 -Wall -gdwarf-2 -O0 -MD -MP -MT Moodlight.o -MF dep/Moodlight.o.d -c ../Moodlight.c
../Moodlight.c: In function 'main':
../Moodlight.c:2: error: 'DDRD' undeclared (first use in this function)
../Moodlight.c:2: error: (Each undeclared identifier is reported only once
../Moodlight.c:2: error: for each function it appears in.)
../Moodlight.c:4: error: 'PORTD' undeclared (first use in this function)
make: *** [Moodlight.o] Error 1
Build failed with 4 errors and 0 warnings...

Wat moet ik eigenlijk bij ''Debug Platform'' bij de Project wizard invoeren?
volgens mijn moet je nog een file van de atmega8535 includen, ik ben ook pas super beginner, maar dat zag ik in wat andere programma's, kijk maar ff rond op circuitsonline ofzo.

  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Je moet inderdaad wat files includen:

#include <avr/io.h>

Bovenin je code. Kan zijn dat je nog andere nodig hebt op een gegeven moment, in de libc documentatie die bij winavr zit staat wel waar de functies uit komen. Maar dingen als poortnamen enzo zitten in avr/io.h.

Debug platform: kies hier maar de simulator (versie 1), tenzij je een development kit hebt die erbij staat (stk500, jtag ice etc.) is de simulator de beste keus. Je krijgt sowieso een hex file.

[ Voor 26% gewijzigd door madwizard op 24-07-2007 00:24 ]

www.madwizard.org


Verwijderd

Topicstarter
ReneK schreef op maandag 23 juli 2007 @ 23:24:
[...]

Ik zie geen enkele vorm van stroombegrenzing voor de led's in je schema (of zit dat
in die modules?). Met 12V voedingsspanning en relatief kleine basisweerstanden
R1 t/m R3 betekent dat een ongecontroleerde stroom door je led's, waarschijnlijk
verniel je ze zodra je ze inschakelt.
Neem dus serieweerstanden op bij de led's om de stroom te begrenzen, 20 mA
is meestal prima. Ook een BC547 volstaat hier prima, hoeft geen BC337 te zijn.
Er zitten voorschakelweerstanden op de modules :) . En idd, volgens de specs van een bc547 kan hij 100mA sturen. Ik zit dan wel meteen aan de max, vandaar dat ik er liever wat bc337 torren inzet.

[ Voor 10% gewijzigd door Verwijderd op 24-07-2007 17:37 ]


Verwijderd

Topicstarter
madwizard schreef op dinsdag 24 juli 2007 @ 00:23:
Je moet inderdaad wat files includen:

#include <avr/io.h>

Bovenin je code. Kan zijn dat je nog andere nodig hebt op een gegeven moment, in de libc documentatie die bij winavr zit staat wel waar de functies uit komen. Maar dingen als poortnamen enzo zitten in avr/io.h.

Debug platform: kies hier maar de simulator (versie 1), tenzij je een development kit hebt die erbij staat (stk500, jtag ice etc.) is de simulator de beste keus. Je krijgt sowieso een hex file.
Oke, ik ga het straks eens proberen. Eerst eten 8) .

Cool! :D Ik zie leds branden! :9~ :P
Alleen ze branden niet op volle sterkte. Zal zo eens meten op mijn torretjes wel volledig opengestuurd worden... Maar ze werken iig :).

Maar nu wil ik natuurlijk verder en het niet bij dit simpel programmatje laten. Hoe doe ik dit?

[ Voor 18% gewijzigd door Verwijderd op 24-07-2007 18:21 ]


  • blackangel
  • Registratie: April 2002
  • Laatst online: 21:41
Over welk programma heb je het nu? Als het die van Sprite is, ik heb daarboven (in PIC-taal) uitgelegd waarom het ledje niet op volle sterkte knipperd.

Overigens is het vanaf nu gewoon de datasheet uitpluizen. Kijken welke functies je zou kunnen gebruiken, en vervolgens hoe je deze in C implementeerd :) Voor jouw doel heb je eigenlijk maar één functie waar je naar moet kijken, namelijk PWM :)

[ Voor 35% gewijzigd door blackangel op 24-07-2007 18:29 ]


  • TrailBlazer
  • Registratie: Oktober 2000
  • Laatst online: 19:09

TrailBlazer

Karnemelk FTW

Dit is mijn PWM assembly code voor een tiny 2313

TrailBlazer in "PWM output geen 0 Volt"

Overigens is assembly echt niet zo moeilijk en volgens mij wel handig als je begint.

Hmm ik zie dat die code die daar geplakt is niet helemaal tof/compleet is. Hieronder staat de wel goede.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
.include "tn2313def.inc"

.equ delay=5
.equ constant=50

.def temp=R16
.def pwml=R17
.def pwmh=R18
.def timer=R19
.def timer1=R20
.def timer2=R21
.def comgre=R22

;interrupt vector
.org 0x0000
   rjmp RESET

RESET:
;STACK INIT!!!
ldi temp, RAMEND
out    SPL, temp
;STACK INIT!!!

;enable ports for PWM outputs

ldi temp, 28
out DDRB, temp

;timer0
;enable PWM A of Timer0
ldi temp, 195

out    TCCR0A, temp

;set prescaling of Timer0
ldi temp, 1
out    TCCR0B, temp

;timer1
;enable PWM A and B of Timer1
ldi temp,241

out    TCCR1A, temp

;set prescaling of Timer1 and 8 bit operation mode
;
ldi temp,9

out    TCCR1B, temp


ldi comgre,128;
;set PWM values timer 0
;red
ldi pwml, 0
out OCR0A, pwml

;set PWM values timer 1
;blue
ldi pwmh, 0
ldi pwml,  255
out OCR1AH, pwmh
out OCR1AL, pwml
;green
ldi pwmh, 0
ldi pwml, 255 
out OCR1BH, pwmh
out OCR1BL, pwml

ldi pwml, 0


RED:
;red down
out OCR0A, pwml
;blue up
mov temp, pwml
com temp
lsr temp
add temp, comgre

out OCR1AH, pwmh
out OCR1AL, temp

ldi timer, delay
rcall longDelay
inc pwml
brne RED

ldi timer, constant
rcall verylongDelay

BLUE:

;blue down
mov temp, pwml
lsr temp
add temp, comgre

out OCR1AH, pwmh
out OCR1AL, temp

;green up


mov temp, pwml
com temp
lsr temp
add temp, comgre

out OCR1BH, pwmh
out OCR1BL, temp
ldi timer, delay
rcall longDelay
inc pwml
brne BLUE

ldi timer, constant
rcall verylongDelay


GREEN:
;green down
mov temp, pwml
lsr temp
add temp, comgre

out OCR1BH, pwmh
out OCR1BL, temp;
;red up
com pwml
out OCR0A, pwml
com pwml
ldi timer, delay
rcall longDelay
inc pwml
brne GREEN

ldi timer, constant
rcall verylongDelay

rjmp RED

;FUNCTIONS
longDelay:
  clr timer1
delay_1:
dec timer1
brne delay_1
  dec timer
  brne delay_1
  ret

verylongDelay:
  clr timer1
  clr timer2
delay_2:
dec timer1
brne delay_2
dec timer2
brne delay_2
  dec timer
  brne delay_2
  ret


maar begin inderdaad met een ledje aan/uit te zetten.

[ Voor 84% gewijzigd door TrailBlazer op 24-07-2007 18:35 ]


Verwijderd

Topicstarter
blackangel schreef op dinsdag 24 juli 2007 @ 18:26:
Over welk programma heb je het nu?

Overigens is het vanaf nu gewoon de datasheet uitpluizen. Kijken welke functies je zou kunnen gebruiken, en vervolgens hoe je deze in C implementeerd :)
Het programmatje om gewoon poort D hoog te maken en hoog te laten.

''Gewoon de datasheet uitpluizen en kijken welke functies ik zou kunnen gebruiken en hoe ik deze dan in C invoer''.
Uhm, je verteld het wel heel simpel maar voor iemand die nog nooit heeft geprogrammeerd is het toch wel even andere koek.

Die code die Blackangel gaf was dus voor een PIC, ik heb geprobeerd om die in mijn code te stoppen maar dat werkt niet echt...

[ Voor 9% gewijzigd door Verwijderd op 24-07-2007 19:48 ]


Verwijderd

Op het forum van http://www.avrfreaks.com vindt je een paar prachtige tutorials. Ik ben ook bezig met een soort van moodlight (het wordt een hele hype hier ;) ) en hoop heel binnenkort ook wat code online te kunnen zetten. Laat vooral weten hoe het verder gaat!

  • TrailBlazer
  • Registratie: Oktober 2000
  • Laatst online: 19:09

TrailBlazer

Karnemelk FTW

Verwijderd schreef op dinsdag 24 juli 2007 @ 18:31:
[...]

Het programmatje om gewoon poort D hoog te maken en hoog te laten.

''Gewoon de datasheet uitpluizen en kijken welke functies ik zou kunnen gebruiken en hoe ik deze dan in C invoer''.
Uhm, je verteld het wel heel simpel maar voor iemand die nog nooit heeft geprogrammeerd is het toch wel even andere koek.

Die code die Blackangel gaf was dus voor een PIC, ik heb geprobeerd om die in mijn code te stoppen maar dat werkt niet echt...
mijn code is wel voor een AVR maar een ander type alle registers en dergelijke zullen niet kloppen maar alle functies wel. Lees mijn code gewoon ff door en kijk desnoods met het datasheet van die attiny2313 wat ik overal doe.

  • Sissors
  • Registratie: Mei 2005
  • Niet online
1 ding wat mij al meteen opviel, en ik ook voor de zekerheid na heb gekeken, DDRD moet gewoon hoog zijn voor output. Oftewel: DDRD=255 (0xFF).

Ik weet nou nog steeds niet precies wat jouw code is, maar misschien branden ze niet op volle sterkte omdat poort D als input is gedefinieerd.

EDIT: ik zie dat je een BJT gebruikt. Die hebben basisstroom nodig. Als jij hem inderdaad als ingang hebt gedefinieerd dan is het enige resultaat dat je de pull up weerstanden hebt aangezet. Er zijn nogal wat soorten van jouw transistor (en ook de pull up weerstand kan nogal verschillend zijn), maar met rekensommetje kom ik erop uit dat er in het positieve geval 100mA door je LEDs gaan, en in het negatieve geval maar 10mA. Oftewel de stroom door je leds kan nu overal tussen de 10 en 100 mA liggen.

[ Voor 64% gewijzigd door Sissors op 24-07-2007 21:35 ]


  • blackangel
  • Registratie: April 2002
  • Laatst online: 21:41
Verwijderd schreef op dinsdag 24 juli 2007 @ 18:31:
[...]

Het programmatje om gewoon poort D hoog te maken en hoog te laten.
Die van Sprite dus.
''Gewoon de datasheet uitpluizen en kijken welke functies ik zou kunnen gebruiken en hoe ik deze dan in C invoer''.
Uhm, je verteld het wel heel simpel maar voor iemand die nog nooit heeft geprogrammeerd is het toch wel even andere koek.
Dat snap ik, maar ik kan, wil en ga je helaas ook niet alles voorkouwen. Dit forum is om te helpen, niet om kant en klaar af te leveren. Vandaar dat ik dat laatste niet voor je ga doen, maar een schop in de goede richting kan altijd wel :) Daarnaast, ik weet ook niet alles. En ik heb hier 0 avr's liggen, 0 programmers etc :+

Hetgene is niet dat het programmeren moeilijk is. Hetgene wat ik tot nu toe heb geprogrammeerd bestaat vooral uit wat functies maken en aanroepen, en hier en daar wat bit-operaties. Simpel gezegd, jij hebt daar niet de voorkennis van, maar het is echt niet zo moeilijk dat je het niet kunt leren. Gewoon ervoor gaan zitten en je hebt het zo door.

Ik ben ook begonnen met microcontrollers programmeren terwijl ik er niks vanaf wist, en daarmee wist ik nog meer dan de docent (van AVR's in ieder geval). Programmeren kon ik wel, en daarmee heb ik uiteindelijk ook wel alles aan de praat gekregen :) Ik zou je dan ook echt aanraden om ook je even wat meer in C te verdiepen als je daarmee verder wilt gaan, of assembly als je de andere richting op wilt gaan natuurlijk.



Wat je bijvoorbeeld kunt doen, is
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//niet rechtstreeks te implementeren, maar wel als achtergrond gedachte
while(1) {
  // zet port D op 0
  PORTD=0x00;

  for(i=0;i<255;i++) {
    if(i>=waardeBlauw)
      PORTD|=0x80;
    if(i>=waardeRood)
      PORTD|=0x20;
    if(i>=waardeGroen)
      PORTD|=0x10;
    
    for(j=0;j<4000;j++);
  }
}

(note: PORTD|=0x10 wil niet veel meer zeggen dan dat je de waarde van PORTD, namelijk 00000000, binair OR'd met 00010000. PORTD is dan 00010000, waarmee je de outputpin van groen dan omhoog zet :))

Het idee hierachter is. Je laat de waarde altijd op 0 springen op een bepaald moment. Stel je wil blauw op 1/4e kracht, rood op 1/4e en groen op 1/2e. Dan declareer je waardeBlauw als 255-256*(1/4)=191. Rood eveneens en groen op 127. Wat je vervolgens als basis-idee doet, is je laat een programma heel snel lopen. Je krijgt vervolgens dat blauw op 1/4e van de tijd hoog is, en 3/4e laag. Omdat je dit heel snel doet, komt het gemiddelde op 1/4e uit. 25% lichtopbrengst dus :) Zelfde voor rood en groen dus.

Het snel laten lopen doe je binnen de while-lus. Het is een oneindige loop. Echter is er een nadeel, en daarvoor zou je eigenlijk wat meer in assembly moeten weten. Om dit even kort samen te vatten, iedere if-statement, whilelus of iets in die richting is eigenlijk vergelijkbaar met een goto, of jumps in assembly. Dat is ook het merkbaare bij het progje van Sprite. Je start het programma en wat er gebeurt is: Alles aan, alles uit, jump. In feite is dus bij 2/3e van de instructies het gevolg dat het ledje uit is, en maar 1/3 van de tijd aan. 33% licht dus :) Als je bijvoorbeeld
C:
1
2
3
4
5
6
7
int main(void) {
 DDRD=0;
 while(1) {
  PORTD=0x00;
  PORTD=0xFF;
 }
}
zou doen, zou die feller moeten branden :) Al hoewel de meeste elektronica voor mij ook een raadsel is geworden sinds ik met m'n studie gestopt ben. Het kan ook aan je torretjes/fetjes liggen, dat die niet snel genoeg kunnen schakelen :)

Maar terug naar mijn bovenstaande progsel, ook die laatste for-lus is niet nauwkeurig, dus wat doe je dan? Heel simpel. Je laat het systeem deze functie aanroepen op vaste tijdstippen, de zogenaamde timer interrupts. Dan heb je helemaal geen forlus nodig. Alleen een counter om te bepalen met de hoeveelste interrupt hij dan weer bezig is.

In ieder geval, als je wat gewend bent aan de programmeertaal of assembly die je wilt gaan gebruiken, dan kun je wat dieper in gaan op de hardwarefunctionaliteit. Dat wil dus zeggen over interrupts, hoe worden ze gebruikt, hoe werken ze, en vooral, hoe gebruik ik interrupts. En daar had ik het dus over met de datasheet. Echt waar, die datasheets van atmel zijn geweldig :) Daanrnaast, ik heb al gezien dat avr-gcc ook een nette implementatie van interrupts heeft :)
Die code die blackangel gaf was dus voor een PIC, ik heb geprobeerd om die in mijn code te stoppen maar dat werkt niet echt...
Nee, ik zat blijkbaar verkeerd te kijken. Ik heb zelf met 3 microcontroller-architecturen zitten stoeien. Die van de 8051 herken ik wel redelijk, maar de PIC en atmel nog niet echt veel. Ik opende een verkeerd bestand om de TRIS uit te halen, wat dus DDR moest zijn. My bad, 't is niet mijn eerste keer en het zal zeker niet mijn laatste keer zijn :P

Verwijderd

Topicstarter
blackangel schreef op dinsdag 24 juli 2007 @ 21:32:

Dat snap ik, maar ik kan, wil en ga je helaas ook niet alles voorkouwen. Dit forum is om te helpen, niet om kant en klaar af te leveren. Vandaar dat ik dat laatste niet voor je ga doen, maar een schop in de goede richting kan altijd wel :) Daarnaast, ik weet ook niet alles. En ik heb hier 0 avr's liggen, 0 programmers etc :+
Het is ook zeker niet de bedoeling van me om zo alles kant en klaar te ontvangen van jullie. Zeker niet. Maar zoals ik al zei, het begin maken is een beetje lastig als je zoals ik, helemaal geen voorkennis hebt.
Als je bijvoorbeeld ...zou doen, zou die feller moeten branden :) Al hoewel de meeste elektronica voor mij ook een raadsel is geworden sinds ik met m'n studie gestopt ben. Het kan ook aan je torretjes/fetjes liggen, dat die niet snel genoeg kunnen schakelen :)
Helaas, echt feller branden ze niet. Ik heb mijn ledjes gewoon aan een 12V adapter hangen. Als ik meerdere modules aan elkaar koppel gaan ze allemaal minder fel branden. Misschien dat mijn spanning inzakt ofzo...


Ik heb een stukje code van internet geplukt en een beetje aangepast.
This one:
C: Knipper Groene led
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <avr/io.h>
#include <util/delay.h>

// delay routine
void delay_ms(unsigned int t)
{
  while(t > 0)
  {    
    /*
    _delay_loop_2 doorloopt 4 clock cycles
    per tel. 4 x 250 = 1000 cycles
    bij 1Mhz clock is dit +/- 1ms delay
    zie ook de AVR libc documentatie
    */
    _delay_loop_2(250);
    t--;
  }  
}

// knipperende LED op PORTA.0 (PA0)
int main()
{
  // PA0 als output
  DDRD = (1 << PD7);  

  // oneindige lus
  while(1)
  {
    // 0.5 sec delay
    delay_ms(100);
    
    // PA0 hoog niveau
    PORTD |= (1 << PD7);
    
    // 0.5 sec delay
    delay_ms(100);
    
    // PA0 laag niveau
    PORTD &= ~(1 << PD7);
  }
  
  return 0;
}

Met deze code kan ik mijn groene leds aan/uit zetten. Heb alleen een vraagje. Die oneindige lus, hoe werkt dat precies? Wordt alles daaronder herhaald tot de return?

Als ik nou 2 leds wil laten knipperen, hoe doe ik dit?

  • TrailBlazer
  • Registratie: Oktober 2000
  • Laatst online: 19:09

TrailBlazer

Karnemelk FTW

Verwijderd schreef op donderdag 26 juli 2007 @ 19:34:

Met deze code kan ik mijn groene leds aan/uit zetten. Heb alleen een vraagje. Die oneindige lus, hoe werkt dat precies? Wordt alles daaronder herhaald tot de return?

Als ik nou 2 leds wil laten knipperen, hoe doe ik dit?
Je zet in ieder geval niet PortA hoog immers je gebruikt de registers van PORTD
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int main() 
{ 
  // PA0 als output 
  DDRD = (1 << PD7);   
 DDRD = (1 << PD6);   

  // oneindige lus 
  while(1) 
  { 
    // 0.5 sec delay 
    delay_ms(100); 
     
    // PA0 hoog niveau 
    PORTD |= (1 << PD7); 
    PORTD &= ~(1 << PD6);
     
    // 0.5 sec delay 
    delay_ms(100); 
     
    // PA0 laag niveau 
    PORTD &= ~(1 << PD7);
    PORTD |= (1 << PD6); 
    
} 
   
  return 0; 
}

zal het wel zijn alleen ik heb die dingen alleen geprogged in assembly

[ Voor 37% gewijzigd door TrailBlazer op 26-07-2007 20:31 ]


  • blackangel
  • Registratie: April 2002
  • Laatst online: 21:41
Verwijderd schreef op donderdag 26 juli 2007 @ 19:34:
Helaas, echt feller branden ze niet. Ik heb mijn ledjes gewoon aan een 12V adapter hangen. Als ik meerdere modules aan elkaar koppel gaan ze allemaal minder fel branden. Misschien dat mijn spanning inzakt ofzo...
Wat je zou kunnen doen om dit te controlleren, is redelijk makkelijk:

Zet alles uit
wacht
Zet groen aan
wacht
Zet ook rood aan
wacht
Zet groen uit.

Groen zou in alle gevallen even fel moeten branden. Als dat niet zo is, ligt het ergens dat je spanning daalt. En ik heb mijzelf aangeleerd dat het vanaf dat moment niet meer mijn fout is, dus ik kan je daarmee niet verder helpen.
Verwijderd schreef op donderdag 26 juli 2007 @ 19:34:
Met deze code kan ik mijn groene leds aan/uit zetten. Heb alleen een vraagje. Die oneindige lus, hoe werkt dat precies? Wordt alles daaronder herhaald tot de return?
Een lus die wordt uitgevoerd zolang het statement waar is. Bij while(1) { ... }, wordt het dus altijd uitgevoerd, aangezien het statement waar is. Overigens is een methode die daar ook voor wordt gebruikt for(;;) { ... }. Sommige mensen zeggen dat dat beter te lezen is, en dat het duidelijker is dat dat een endless loop is. Zelf gebruik ik while(1) altijd, maar je zult soms wel eens for(;;) tegen komen.
Verwijderd schreef op donderdag 26 juli 2007 @ 19:34:
Als ik nou 2 leds wil laten knipperen, hoe doe ik dit?
Wat bedoel je precies? Dat je bijvoorbeeld led1 en led3 van je schema laat knipperen? Want dat kan niet.

Als je bijvoorbeeld led1-3 en led4-6 wil laten knipperen, gewoon
C:
1
2
3
4
5
6
7
8
9
10
int main(void) {
  DDRD=0x90; 
  while(1) {
    delay_ms(100); 
    PORTD=0x90
    delay_ms(100); 
    PORTD=0x00;
  }
  return 0;
}

Eventueel met bitshiften als je dat leuk vind, maar dat is tamelijk nutteloos voor een test-iets zoals dit :)

  • virus.elektro
  • Registratie: Januari 2002
  • Laatst online: 20-11 20:33

virus.elektro

profesionele monitor sloper

ben ongeveer met het zelfde bezig. alleen in plaats van een atmega 8535 gebruik ik een atmega 16. ik gebruik trouwens n-fet's om de leds aan te sturen, in theorie zou de print 5A per kanaal kunnen doen, nog niet getest

bij werkt het op de volgende manier

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 int main()
    {
    
    unsigned char pwm, rood, groen, blauw;
    char oud, nieuw;
    unsigned char fadeonoff,fadehola;
    unsigned int fade;
    init();
    pwm=rood=groen=blauw=0;
    fadehola=fadeonoff=0;
    //lcd_write_string("hoi");
    sei();
    while(1)
        {
        if(vlag==1)//alleen doen als de timer0 overflowt
            { 
            pwm++;
            if (pwm>rood){PORTA=PORTA&~ROOD;}
            if (pwm>groen){PORTA=PORTA&~GROEN;}
            if (pwm>blauw){PORTA=PORTA&~BLAUW;}
            if (pwm== 255)
                {
                pwm = 0;
                if (rood>0)PORTA=PORTA|ROOD;
                if (groen>0)PORTA=PORTA|GROEN;
                if (blauw>0)PORTA=PORTA|BLAUW;
                }
        vlag=0; //vlag resetten
            }
        }
    return 0;
    }


code:
1
2
3
4
5
6
7
8
9
10
11
12
// include's
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <ctype.h>
#include <stdint.h>
ISR(TIMER0_OVF_vect)
    {
    vlag= 1;
    return;
    }


ik heb wat code weg gelaten maar die is niet echt belangrijk voor jou. bij hangt er een toetsenbord en ook een display aan op dit moment

[ Voor 4% gewijzigd door virus.elektro op 26-07-2007 22:56 ]

elektrotechniek is leuk (nog wel). ik ga dus weer verder met leuke dingen ontwerpen. amd 2200+ 256mb 333mhz,gf4 440mx, 120gb,16X dvd. jarr-url


Verwijderd

Topicstarter
Dat includen, doe je dat in een los bestand of hoe werkt dat? Meestal staat dat toch bovenaan de code? Hoe werkt dat includen precies, je roept daar toch speciale functies mee aan?

[ Voor 79% gewijzigd door Verwijderd op 31-07-2007 19:24 ]


  • Paul
  • Registratie: September 2000
  • Laatst online: 19:01
Je zet gewoon beiden stukjes van virus.electro in 1 bestand, en wel precies andersom dan ze in die post staan :) Dan runnen en het moet werken :)

Virus.electro: Waarom die vlag en het dan in de main afhandelen? Is het niet netter om dat in de ISR te zetten?

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


  • virus.elektro
  • Registratie: Januari 2002
  • Laatst online: 20-11 20:33

virus.elektro

profesionele monitor sloper

de includes zitten bij mij in het zelfde bestand. ze horen inderdaad boven. ik was ze vergeten er bij te plakken. en tussen de include's en de main zit bij mij een behoorlijk stuk code/subfunctie om het toetsen bordje uit te lezen.

het includen zorgt er bij mij vooral voor dat ik PORTA kan schrijven in plaats van een ingewikkeld adres. verder kan met interupt.h gebruik maken van de interrupt's op de atmega.

@paul nieuwkamp
klopt het is netter zoals jij het zegt. echter als ik alles in de ISR zet, duurt die veel te lang. ik heb nu wel het aan/uitzetten van de lampjes er ingeplaatst. de rest gaat nog steeds via die vlag.

heeft er mee te maken dat ik mijn IRS's zo kort mogelijk wil houden, meesta wil ik wel weten dat ze geweest zijn maar is de timing niet al te kritisch. probleem is namelijk dat zolang je bezig bent met een ISR je niet kan reageren op andere interupt's

[ Voor 37% gewijzigd door virus.elektro op 31-07-2007 20:01 ]

elektrotechniek is leuk (nog wel). ik ga dus weer verder met leuke dingen ontwerpen. amd 2200+ 256mb 333mhz,gf4 440mx, 120gb,16X dvd. jarr-url


  • Ibex
  • Registratie: November 2002
  • Laatst online: 22:27

Ibex

^^ met stom.

virus.elektro schreef op dinsdag 31 juli 2007 @ 19:51:
probleem is namelijk dat zolang je bezig bent met een ISR je niet kan reageren op andere interupt's
Wanneer je in een ISR gaat zal je AVR normaal inderdaad interrupts uitschakelen. Je kan deze binnen je ISR echter terug aanzetten om geneste interrupts mogelijk te maken :).

Zo denk ik bijvoorbeeld aan een ISR die elk kwartier oid een aantal sensoren uitleest wat bijvoorbeeld een volle minuut duurt. Wanneer je systeem dan een scherm heeft die de gebruiker toelaat de verschillende waardes van de diverse sensoren te raadplegen, wil je wel dat je systeem nog reageert op het indrukken van knopjes door de gebruiker. Je kan dan binnen de ISR van het uitlezen van de sensoren de interrupts terug aanzetten, zodat het systeem kan blijven reageren bij het indrukken van een toets :).

Archlinux - Rode gronddingetjes zijn lekker - Komt uit .be

Pagina: 1