Portausgänge shiften am Atmega 32

OP #3147647
Lesenswert?

Hallo zusammen, ich hab ein kleines Problem und hoffe ihr könnt mir 
helfen.
Ich will an meinem ATMEGA32 PORTA ( von PA0 bis PA7) jeweils eine "1" 
durchshiften...Prinzip Lauflicht...ABER irgendwie macht mein µC nciht 
das was er soll oder ich hab ein kleinen Denkfehler....
hier mein Quellcode:

#define F_CPU 8000000
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

ISR(TIMER1_COMPA_vect)
{
  PORTA = PORTA >>1 ;
  if(PORTA == 0x00)
    PORTA = 0x80;
}


int main(void)
{
DDRA |= 1<<PD0;
DDRA |= 1<<PD1;
DDRA |= 1<<PD2;
DDRA |= 1<<PD3;
DDRA |= 1<<PD4;
DDRA |= 1<<PD5;
DDRA |= 1<<PD6;
DDRA |= 1<<PD7;


while(1)
{

}

//Timer konfigurieren
TCCR1B |= (1<<WGM12) | (1<<CS11); //| (1<<CS10);//CTC Mode mit WGM12, 
Prescaler von 8 mit CS11
//TCNT1 = 64286;
TIMSK |= (1<<OCIE1A);
OCR1A |= 675;          //Vergleichswert zur BEstimmung von 1,25ms

TIMSK |= (1<<OCIE1A);
TCCR1A |= (1<<COM1A0);

sei();
}


ich will einfach nur, dass jeder Port etwa für 0,1ms einen high-Pegel 
hat.
Der Timer ist jetzt auf 800Hz eingestellt...der sollte natürlich auf 
100Hz stehen.
Noch besser wäre es wenn man diese Funktion ohne einen Timer Baustein 
bewerkstelligen kann, da ich die 3 Timer im Atmega eigentlich für was 
anderes benötige.

Danke schonmal für´s durchlesen...

LG Paavo
Gast #3147692
Lesenswert?

Ich bin im Moment nicht mit Atmegas vertraut, aber ich denke
OCR1A |= 675;
wird nicht klappen, da der Atmega nur 8 bit Register hat, also nur Werte 
bis 255 annehmen kann.
Du musst dir wohl einen anderen Vorteiler und eine andere Timerschwelle 
ausrechnen.

PS: Siehst du irgendetwas auf dem Scope?

PSS:

  if(PORTA == 0x00)
sieht auch nicht gut aus. Ich würde die Abfrage auf 0x01 machen.
Der Shifter ist glaube eh ein Kreisshifter (oder irre ich mich da?)
OP #3147703
Lesenswert?

Der Timer läuft im CTC Modus...TCCR1B |= (1<<WGM12)
Dersweiteren habe ich einen Rrescaler von 8 eingestellt hier nochmal die 
Zeile:

TCCR1B |= (1<<WGM12) | (1<<CS11);
//| (1<<CS10);
//CTC Mode mit WGM12, Prescaler von 8 mit CS11

Das mit dem Timer haut schon in da ich ihn am PD5 messen kann mit hilfe 
des scopes...!
Ich will ja eigentlich nur den gesamten PORTA aktivieren. Dass macht er 
auch mit DDRA = 0xFF // somit sind alle Pins als Ausgänge definiert.
...if(PORTA = 0x00)PORTA 0x80; ist nur dafür gedacht, dass er wieder von 
vorne anfängt zu zählen und nicht ins nirvana shiftet:D
#3147726
Lesenswert?

Ich auch.
Einfach einen Breakpoint in die ISR setzen.
Im Bild wo der gelbe Pfeil ist mit der linken Maustaste klicken.
Dieses Programm benutze ich:
1
#define F_CPU 8000000
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <util/delay.h>
5

6
ISR(TIMER1_COMPA_vect)
7
{
8
  PORTA = PORTA >>1 ;
9
  if(PORTA == 0x00)
10
  PORTA = 0x80;
11
}
12

13

14
int main(void)
15
{
16
  DDRA |= 1<<PD0;
17
  DDRA |= 1<<PD1;
18
  DDRA |= 1<<PD2;
19
  DDRA |= 1<<PD3;
20
  DDRA |= 1<<PD4;
21
  DDRA |= 1<<PD5;
22
  DDRA |= 1<<PD6;
23
  DDRA |= 1<<PD7;
24

25

26
  
27
  //Timer konfigurieren
28
  TCCR1B |= (1<<WGM12) | (1<<CS11); //| (1<<CS10);//CTC Mode mit WGM12,  Prescaler von 8 mit CS11
29
  //TCNT1 = 64286;
30
  TIMSK |= (1<<OCIE1A);
31
  OCR1A |= 675;          //Vergleichswert zur BEstimmung von 1,25ms
32

33
  TIMSK |= (1<<OCIE1A);
34
  TCCR1A |= (1<<COM1A0);
35

36
  sei();
37
  while(1)
38
  {
39

40
  }
41

42
}
Angehängte Dateien:
Gast #3147729
Lesenswert?

Hi

>Ich bin im Moment nicht mit Atmegas vertraut, aber ich denke
>OCR1A |= 675;
>wird nicht klappen, da der Atmega nur 8 bit Register hat, also nur Werte
>bis 255 annehmen kann.

Als 8-Bit-Register heißt das OCR1AL und OCR1AH. OCR1A ist für den 
Compiler ein 16-Bit-Register.

>TCCR1A |= (1<<COM1A0);

Dann solltest du aber auch OC1A (PD5) auf Ausgang setzen.

MfG Spess
#3147739
Lesenswert?

Benutzt du exakt mein Programm?
Gut, das Studio ist schon mal zickig.
Mach mal Folgendes:
- Den Breakpoint so setzen wie bei mir
- Alt+F5 (= Start debuging and break)
- jetzt sollte der Cursor in der ersten Zeile der main-Funktion stehen.
- F5 (=Run) drücken.
- nach einer kurzen Weile sollte der Cursor beim gesetzten Breakpoint in 
der ISR stehen bleiben.
OP #3147753
Lesenswert?

Ja alles super=) NUR wenn ich schiffte müsste doch auf jedem Port der 
Highpegel etwas woanders liegen oder?
Der Pegel sieht jetzt so aus....

____-_______-_____

aber ich will eigentlich einen Pegel haben , der wirklich 100 Hz an 
jedem Pin bleibt!

so dass ich insgesamt eine rotation von 800HZ habe.
OP #3147788
Lesenswert?

Nur zum verständnis...
Wenn ich den Timer1 nehme und im CTC modus betreibe und mit einem 
Prescaler von 8 rangehe und meine Taktfreuenz vom CPU bei 8Mhz liegt und 
ich eine Frrequenz von 800 Hz haben will rechne ich doch wie folgt oder?

ORC1A = (zeit *(CPU_takt/Prescaler)-1

oder?
#3147800
Lesenswert?

Du schreibst hier:
1
OCR1A |= 675;          //Vergleichswert zur BEstimmung von 1,25ms
Wie kommst du darauf? Der µC läuft mit 8MHz, der Timer 1:8 also mit 
1MHz,
also kommt der Interrupt alle 0,675 Millisekunden. Der richtige Wert 
wäre 1250.
Oh noch was: OCR1A |= 675;
GAAAANZ gefährliches Eisen! Was soll hier die Oder-Verknüpfung?
OCR1A enthält genau nur dann den Wert 675, wenn es vorher Null war. Wird 
hier in diesem Fall zwar funktionieren, später kann dir soetwas aber mal 
das Genick brechen.
Gast #3148474
Lesenswert?

Hi

>Ich habe auch 1249 errechnet! Aber damit bekomme ich leider auf dem
>Scope keine 800 Hz zusehen...

Und wo gemessen? An einem Pin von PortA solltest du Impulse mit einer 
Frequenz von 100 Hz messen. Am OC1A-Pin (PD5) müssen 400 Hz 
symmetrisches Rechteck rauskommen. Dann passt das Ganze.

MfG Spess
OP #3150845
Lesenswert?

Hwy:D
Also ich messe jetzt an PD5 eine Frequenz von 800Hz mit einem 
Vergleichswert von OCR1A =624,5; fragt mich nicht wie aber es 
geht...=)=)
Von der Taktung sieht es jetzt genau so aus wie ich es haben will...Also 
800Hz an PD5 und an PA0-7 jeweils einen Impuls der dann 7 Takte von PD5 
abwartet eh er wieder kommt!
Super super super=)

Nächste frage die ich habe ist, in welchen Register kann bzw muss ich 
eine 32bit große Bitfolge abspeichern...ich hab eigentlich ein 64 Bit 
wort wie ich es aufteile hab ich in C schon realisiert..nur muss ich dem 
Atmega doch sagen wo er es ablegen soll oder?

Kann ich eine Bitfolge einfach an PD4 rauschicken? Oder einen 
beliebeigen Pin?

LG

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren