Wie hast du den angeschlossen? Der sollte eigentlich am Pin6 Vcc dran haben. Am Pin5 gehört GND dran und am Pin4 gehört ein PullUp nach Vcc dran und dein Atmel. Ob der PullUp nun wirklich 280R haben soll oder auch ein 1k reicht kann man ja mal testen. Auf jeden Fall ist der Empfänger ein IC und kein reiner Fototransistor.
jup, das hab ich schon richti gemacht denke ich. hab auch auf der anderen seite mit dem oszi geschaut. kommt schöner pegel raus...
Auf die Pinbelegung am Empfänger achten!! Da ist im Datenblatt zwischen Innenschaltung und IC-Bild Pin4 und Pin5 verdreht!! Also aufpassen. Das verwirrt an der Stelle leicht.
ja, das hab ich am anfang gleich mal verkehrt gemacht und den ersten OK gegrillt. und die dinger kosten sch** 1,70 € beim conrad!!
ich habe gestern das ganze nochmal auf ein neues board aufgelötet.
jetzt funktioniert es. das einzige, was ich geändert habe, war der ic-sockel, den ich jetzt weggelasen habe. offenbar hatter der so viel kapazitäten, dass dadurch die flanken unsauber wurden. jetzt werden die bytes richtig übertragen. ich werden das die tage nochmal mit sockel aufbauen, um endgültig zu klären ob es daran lag...
aber es droht schon ein neues problem.. irgendwie werde ich nicht fertig....:
mir ist aufgefallen, dass zwar die interrupts sauber ausgelöst werden, aber nur, wenn ich zwischen den einzelnen "tastendrücken" ein wenig zeit vergehen lassen. am besten wurde das deutlich, wenn ich einen drehpoti von meinem midi-controller bewegte. da war es dann so, dass zwar bei kurzen drehimpulsen der atmega8 all das tat, was man von ihm erwartete, wenn man aber ohne pause hin und her drehte, so geschah nur am anfang was, danach nichts. das machte mich stutzig, weil eigentlich sollten ja auch in dem fall des ununterbrochenen drehens die richtigen midi-nachrichten (also das 1. byte der drei) mit der richtigen kanalnummer durchkommen. dem war aber nicht so. es machte den anschein, als ob dann überhaupt nichts gesendet wird, was ja nicht sein kann. also habe ich da heute mal etwas hinterher geforscht.
tja, und jetzt bin ich wieder mal ziemlich frustriert, da ich gerade noch dachte, ich hätte uart und midi im griff, und jetzt geht nix wie es soll:
das kleine programm das ich schrieb sollte einfach nur in ner endlosschleife rumhängen und drauf warten, dass das uart-interrupt ein register ("flag0") mit einsen füllt. ist dem so, wird verzweigt, eine LED-kette angemacht und ein zählregister in einer schleife hochgezählt. wenn das 0xFF erreicht wird wieder verzweigt, die LEDs ausgeschaltet und die flag0 wieder zurück gesetzt. damit das nicht zu schnell geschieht, und man auch deutlich sieht, dass die LEDs an waren, habe ich in die zählschleife noch ein paar hundert NOPs eingefügt. (das ist zwar nicht die feine englische art, und bei mikrocontroller.net würde ich bestimmt auch mächtig war zu hören kriegen dafür, aber hier sollte es einfach mal um die funktionsprüfung gehen... quick an dirty)
anschließend wird wieder zurück in die haupt-schleife gesprungen, wo auf das nächste interrupt gewartet wird, das die flag0 mit 0xFF füllt. soweit die theorie.
ES FUNKTIONIERT EINFACH NICHT!! die LEDs gehen an, und nicht mehr aus. ganz so, als ob das programm nie die stelle erreicht an der die flag zurück gesetzt wird und die LEDs überschrieben werden. hab den ganzen (!!) tag damit verbrach herrauszufinden war da los ist. habe dazu zum test ein zweites interrupt (flankengesteuert) eingebaut, das ich einfach mit taster auslösen kann. DA HAT ES AUCH FUNKTIONIERT. die LEDs gehen kurz an, danach wieder aus. obwohl im uart interrupt-vektor exakt das gleiche steht wie im INT0-vektor. da wird nix anderes gemacht, als das flag0-register gesetzt.
Ganz offenbar habe ich etwas fundamental wichtiges bei interrupts und Uart noch nicht verstanden. oder es ist ein fehler in der matrix. letzters ist nicht unwahrscheinlich ;-)
hier mal der quellcode. vielleicht könnt ihr meinen denkfehler sehen:
Code:
#define __SFR_OFFSET 0
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#define flag0 r19
#define temp0 r20
#define zeit1 r24 //in diesen beiden register wird die zeit für die ausgabe hochgezählt
.section .text
.global main
main:
//*********************Stackpointer initialisierung*********************
ldi temp0, hi8(RAMEND)
out SPH, temp0 //über die vorgeschriebene reihenfolgen hier findet man überall abweichende angaben. ich hab beide varianten ausprobiert. hat keinen unterschied gemacht..
ldi temp0, lo8(RAMEND)
out SPL, temp0
//*********************Ports konfigurieren*********************
ldi temp0, 0xFF
out DDRB, temp0
//*********************Uart konfigurieren*********************
ldi temp0, 0b00000000 //läd das obere Baudratenregister. wichtig!: erst das high-register beschreiben, dann das low.
out UBRRH, temp0
ldi temp0, 0b00000111 //läd das untere Baudratenregister.
out UBRRL, temp0
ldi temp0, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0) //Frame format auf 8 bit setzten. kann man womöglich auch weglassen
out UCSRC, temp0
sbi UCSRB, RXCIE
sbi UCSRB, RXEN
//*********************INT0 initialisieren*********************
ldi temp0, (1<<ISC01) | (1<<ISC00) //INT0 auf steigende flanke konfigurieren
out MCUCR, temp0
ldi temp0, (1<<INT0) //INT0 aktivieren
out GICR, temp0
//*********************initialisieren*********************
ldi temp0, 0b11111110 //Eine LED leuchtet, wenn startbereit
out PORTB, temp0
ldi temp0, 0x00
ldi flag0, 0
ldi zeit1, 0x00
sei
//*********************main-loop*********************\\
loop0:
cpi flag0, 0xFF //hier wird verglichen, ob in dem flag0-register 1en stehen. wenn ja -> verzweigen
breq mrk1
rjmp loop0
//*********************blinken*********************\\
mrk1:
ldi temp0, 0b10101010 //hier weden die LEDs angeschaltet.
out PORTB, temp0
rjmp nopz //der besseren übersichtlichkeit wegen, stehen hier nicht direkt die vielen NOPs, sondern es wird gesprungen und danach wieder zurückgesprungen...
nopz_ret:
//cli
cpi zeit1, 0xFF //hier wird vergleichen, ob das zeit1-register schon mit 255 gefüllt ist.
breq mrk2
inc zeit1 // hier wird zeit1 hochgezählt
//sei
rjmp loop0
mrk2:
ldi flag0, 0x00 //flag0 wieder zurück setzten
ldi temp0, 0xFF
out PORTB, temp0 // LEDs ausschalten (negiert!)
ldi zeit1, 0 // zeit1 zurücksetzten
rjmp loop0
nopz:
nop
nop
.
.
.
// hier stehen eben wie gesagt ca. 250 NOPs. hab die mal weggelassen... bitte nicht zu sehr schimpfen deswegen...
.
.
nop
nop
rjmp nopz_ret
//*********************Uart interrupt*********************
.global INT0_vect
INT0_vect:
ldi flag0, 0xFF
reti
.global USART_RXC_vect
USART_RXC_vect:
ldi flag0, 0xFF
reti
diese stelle ist auch interessant:
//cli
cpi zeit1, 0xFF
breq mrk2
inc zeit1
//sei
wenn mal cli un sei hier mit rein nimmt, dann schaltet sich zwar die LEDs nach einem Uart-interrupt wieder aus, dafür kann man sowohl das uart- als auch das int0 interrupt nicht wiederholt abfeuern...
ich seh echt nicht durch. bitte helft mir, wenn ihr könnt...