Hallo,
ich bin neu in der Welt der Mikrocontroller und habe eine Frage
ich habe das AVR MK2 Board mit einem Atmga8 ich benötige mehr Eingänge
und habe mir hierfür zwei 74HC165 kaskadiert. Schaltplan siehe
angehängtes Bild.
ich Programmiere in C leider habe ich ich nur eine Assembler Code finden
können. Kann mir evtl. jemand den Code in C übersetzen? Wäre echt super.
Schon mal Danke im voraus.
Hier der Code:
1
; Porterweiterung für Eingänge mit Schieberegister 74xx165
Peter Bauer schrieb:> ich Programmiere in C leider habe ich ich nur eine Assembler Code finden> können.
cbi - Clear Bit
sbi - Set Bit
ori - bitweises oder
u.s.w.
Wenn du C kannst sollte das kein Problem sein. Die Befehlsbeschreibungen
stehen in Kurzform alle im Datenblatt im Anschnitt "Instruction Set
Summary"
so hab mal das C-Programm geschrieben, lässt sich auch ohne Fehler
übersetzen, funktioniert aber leider nicht.
Jemand ne Idee??
nach dem Durchgang sollte das Eingansregister ja eingelesen sein und im
Array eingang_mux stehen macht es aber nicht.
1
intmain(void)
2
{
3
DDRB|=((1<<DDB0)|(1<<DDB1));// Port B Pin 0 und 1 als Ausgang
4
PORTB&=~((1<<DDB0)|(1<<DDB1));// auf 0 setzen
5
DDRB&=~((1<<DDB2));// Port B Pin 2 als Eingang
6
PORTB&=~(1<<DDB2);// Pullup aus
7
8
inteingang_mux[16];
9
10
while(1)
11
{
12
13
HC165_Lesen(eingang_mux);
14
15
16
}// End While
17
}// End Main
18
19
voidHC165_Lesen()
20
{
21
intwerte[16]={0};// Array mit Eingangsdaten initalisiert mit 0
22
inti;// Zählvariable
23
// PB0 = PL
24
// PB1 = CLK
25
// PB2 = Q7 (DIN)
26
PORTB|=(1<<PB1);// CLK auf 1 setzen
27
28
PORTB&=~(1<<PB0);// PL = 0;
29
PORTB|=(1<<PB0);// PL = 1;
30
31
for(i=0;i<16;i++)
32
{
33
if(PINB&(1<<PB2))// Eingang Q7 ist 1
34
{
35
werte[i]=1;// dann schreibe 1 ins Register
36
37
}
38
else// sonst
39
{
40
werte[i]=0;// schreibe 0 ins register
41
}
42
43
// Eingansregister eins weiter takten
44
45
PORTB&=~(1<<PB1);// CLK = 0;
46
PORTB|=(1<<PB1);// CLK = 1;
47
}
48
returnwerte[16];// Eingangsregister an Hauptprogramm übergeben
Peter Bauer schrieb:> nach dem Durchgang sollte das Eingansregister ja eingelesen sein und im> Array eingang_mux stehen macht es aber nicht.
Warum sollte es denn in eingang_mux stehen?
Du möchtest das sicher gern, aber dazu muß es auch jemand reinschreiben.
HC165_Lesen schreibt die eingelesenen Werte in die lokale Variable
"werte", und zwar index 0..15. Dann wird der Inhalt von werte[16]
zurückgegeben, der gar nicht existiert. Ist aber egal, denn der
Rückgabewert wird ja sowieso nicht benutzt.
Dauergast schrieb:> Warum sollte es denn in eingang_mux stehen?> Du möchtest das sicher gern, aber dazu muß es auch jemand reinschreiben.
ich gebe mit Werte[16] das ganze Array zum Hauptprogramm zurück und
schreibe es dort in das Array eingang_mux
ich kann auch einfach nur
1
returnwerte;
schreiben, ändert aber nichts
hier nochmal der Code habe noch einen Ausgang der mit eingang_mux
gesetzt wird ergänzt
@Dauergast: wenn du eine Idee hast wies richtig geht wäre es schön wenn
du meinen code an denn entsprechenden stellen korrigierst, dann kann ich
auch verstehen was ich falsch mache.
1
intmain(void)
2
{
3
DDRB|=((1<<DDB0)|(1<<DDB1)|(1<<DDB3)|(1<<DDB4));// Port B 0, 1, 3 als Ausgang
4
PORTB&=~((1<<DDB0)|(1<<DDB1)|(1<<DDB3)|(1<<DDB4));// auf 0 setzen
5
DDRB&=~((1<<DDB2));// Port B 2 als Eingang
6
PORTB&=~(1<<DDB2);// Pullup aus
7
8
inteingang_mux[16];
9
while(1)
10
{
11
12
HC165_Lesen(eingang_mux);
13
14
if(eingang_mux[0]=1)// wenn 1 dann
15
{
16
PORTB|=(1<<DDB3);// Ausgang auf 1 setzen
17
}
18
else// sonst
19
{
20
//DDRB |= (1<<DDB3);
21
PORTB&=~(1<<DDB3);// Ausgang auf 0 setzen
22
}
23
}// End While
24
}// End Main
25
26
intHC165_Lesen()
27
{
28
intwerte[16]={0};// Array mit Eingangsdaten initalisiert mit 0
29
inti;// Zählvariable
30
// PB0 = PL
31
// PB1 = CLK
32
// PB2 = Q7 (DIN)
33
PORTB|=(1<<PB1);// CLK auf 1 setzen
34
35
PORTB&=~(1<<PB0);// PL = 0;
36
PORTB|=(1<<PB0);// PL = 1;
37
38
for(i=0;i<16;i++)
39
{
40
if(PINB&(1<<PB2))// Eingang Q7 ist 1
41
{
42
werte[i]=1;// dann schreibe 1 ins Register
43
}
44
else// sonst
45
{
46
werte[i]=0;// schreibe 0 ins register
47
}
48
49
// Eingansregister eins weiter takten
50
51
PORTB&=~(1<<PB1);// CLK = 0;
52
PORTB|=(1<<PB1);// CLK = 1;
53
}
54
returnwerte;// Eingangsregister an Hauptprogramm übergeben
Du kannst kein Array zurückgeben, höchstens eine Pointer darauf. Ein
Pointer auf Dein lokales "werte" ist allerdings nach Rückkehr aus der
Funktion HC165_lesen ungültig, da "werte" nicht mehr existiert.
Du übergibst also eingang_mux als Parameter, und benutzt das für Deine
Ergebnisse:
1
voidHC165_Lesen(int*werte);
2
3
intmain(void)
4
{
5
inteingang_mux[16];
6
7
DDRB|=((1<<DDB0)|(1<<DDB1)|(1<<DDB3)|(1<<DDB4));// Port B 0, 1, 3 als Ausgang
8
PORTB&=~((1<<DDB0)|(1<<DDB1)|(1<<DDB3)|(1<<DDB4));// auf 0 setzen
Peter Bauer schrieb:> Dauergast schrieb:>> Warum sollte es denn in eingang_mux stehen?>> Du möchtest das sicher gern, aber dazu muß es auch jemand reinschreiben.>> ich gebe mit Werte[16] das ganze Array zum Hauptprogramm zurück und> schreibe es dort in das Array eingang_mux
Wie kommst du denn da drauf??????
Dauergast schrieb:
nitpicking
> if(eingang_mux[0]=1) // wenn 1 dann
if(eingang_mux[0] == 1) // wenn 1 dann
Nicht dass der TO in seinem nicht vorhandenem C-Buch auch danach noch
stundenlang sucht.
Peter Bauer schrieb:> leider habe ich ich nur eine Assembler Code finden> können.
Dann hast Du aber sehr schlecht gesucht.
Es gibt haufenweise SPI-Code in C.
Peter Bauer schrieb:> int werte[16]={0}; // Array mit Eingangsdaten initalisiert mit 0
Ja, man kann die Hose auch mit der Kneifzange anziehen. Warum diese
16-fache Verschwendung von SRAM?
Ein 16 Bit Wert (unsigned int) reicht völlig. Es passen ganze 16 Bit
hinein, wer hätte das gedacht.
Danke für die Antworten, ich werde das heute ausprobieren sobald ich von
der Arbeit Zuhause bin.
@Peter Dannegger
wollte das ohne SPI machen wie im AVR Tutorial beschrieben (unters
drittel):
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Schieberegister
Im Tutorial ist ja leider nur Assembler Code dabei was ich leider gar
nicht kann.
Falls du aber noch irgendwo eine bessern C-Code gesehen hast kannst du
Ihn gerne Posten, habe leider bisher nichts funktionierendes gefunden.
mit dem unsigned int hast du natürlich recht.
Peter Bauer schrieb:> Danke für die Antworten, ich werde das heute ausprobieren sobald ich von> der Arbeit Zuhause bin.>>> @Peter Dannegger> wollte das ohne SPI machen wie im AVR Tutorial beschrieben (unters> drittel):> http://www.mikrocontroller.net/articles/AVR-Tutorial:_Schieberegister>> Im Tutorial ist ja leider nur Assembler Code dabei was ich leider gar> nicht kann.
Wichtig ist das Prinzip - und das geht aus dem ganzen beschriebenen
Vorgeplänkel eindeutig hervor.
> Falls du aber noch irgendwo eine bessern C-Code gesehen hast kannst du> Ihn gerne Posten, habe leider bisher nichts funktionierendes gefunden.
Du musst endlich einsehen, dass eine Programmiersprache nicht einfach
nur irgendwie schmückendes Beiwerk ist, sondern dass man das LERNEN
muss. Es hat keinen Sinn sich über die Feinheiten einer SPI
Programmierung zu unterhalten, wenn du das dafür notwendige C nicht
beherrscht.
Wer malen anfangen will, muss lernen Farben zu mischen und Pinsel
auszuwaschen. Solange er das nicht kann, ist es sinnlos, sich über
Farbkomposition und Bildaufbau mit ihm zu unterhalten. Wir können
stundenlang die alten Meister studieren und wie sie ihre Bilder
komponiert haben und wo sie welchen Trick eingesetzt haben, wenn der
Lehrling dann an der ganz banalen Frage "wie mische ich meine Farbe,
welchen Pinsel nehme ich und wie kriege ich ihn wieder sauber"
scheitert. Mit dem einen Unterschied, dass man diese Malgrundlagen in
einer Stunde lernen kann, eine Programmiersprache zu lernen aber Monate
dauert. Ok, den Teil, den man hier braucht, hat man in ein paar
Tagen/Wochen intus. Aber alleine die Formulierung "ein Array
zurückgeben" zeigt schon, dass da etwas wesentliches im Grundverständnis
fehlt. Und da geht es nicht um SPI bzw. wie man das geschickt anstellt.
Denn bei SPI geht es im Grunde nur um zeitlich richtiges Wackeln mit
µC-Pins und entsprechendes Setzen bzw. Abfragen von Werten. Und genau
das ist hier NICHT dein eigentliches Problem. Dein eigentliches Problem,
wie man es aus der ganzen Art der Fragestellung ablesen kann, besteht
darin, dass dein C generell noch viel zu schwach ist. Die
Schwierigkeiten mit SPI sind nur eine logische Folgeerscheinung davon.
Und ich möchte hinzufügen: Du bist damit nicht alleine, wie sich hier im
Forum jeden Tag zeigt. Es tauchen immer wieder Leute auf, denen man im
Grunde sagen muss: Sorry, aber deine ganze Ausdrucksweise, dein genazer
Code zeigt, dass du mit deinen Kentnissen und mit deinem Wissen über die
Programmiersprache noch nicht soweit bist, ein reales Projekt in Angriff
zu nehmen. Wer einen Hammer nicht richtig rum in die Hand nehmen kann,
sollte nicht (noch nicht) anfangen, ein Haus bauen zu wollen, sondern
erst mal 20 Übrungsnägel in ein Stück Übungsholz einschlagen.
Danke Peter für den Code
ich habe noch ein Frage dazu. Wie Frage ich jetzt das bit der Struktur
ab?
normalerweise ja Strukturvariable.Struckturelement aber was ist hier
dann die Strukturvariable?
z.B.
Du hast doch keine Struktur, sondern einen 16Bit-Wert.
Und da fragst Du eben ein Bit ab, indem Du alle anderen maskierst.
Genau, wie Du einen Portpin abfragst.