Time interupt schneller machen

OP #2699778
Lesenswert?
• ▲
▼
Hallo ich hab eine LED Matrix  16X(noch16) soll später 16x192 (12x16) 
werden für die 16 Zeilen verwende ich einen ATmega32 und für die je 16 
spalten einen weiteren ATmega32 alle laufen mit 16MHz die sync. zwischen 
zielen und spalten läuft auch die Verwendung von den vielen ATmega32 
hängt damit zusammen das ich jede LED über soft PWM mit 255 stufen 
dimmen will und dabei komme ich nun zu einem Problem ich wollte dabei 
auch das menschlich Auge Ausgleich und muss dazu die kleinsten dimm 
stufen sehr klein machen stoße dabei aber an ein Problem mit dem zeit 
Interrupt der scheint leider etwa 136 (Vorteiler 8 x Zählerwert 17) 
takte zu brauchen. Hier der Interrupt:
1
ISR (TIMER1_COMPA_vect)
2
  {
3
  cli();
4
  OCR1A = coderunT[y][i];  //Aktualisirung Zeitwert OCR1A
5
  PORTA = coderunA[y][i];  //Aktualisirung Port A
6
  PORTC = coderunC[y][i];  //Aktualisirung Port C
7
  i++;  
8
  sei();
9
  }

die Idee für Soft PWM stammt hier her:
http://www.mikrocontroller.net/articles/Soft-PWM Version 3

die Idee zum Ausgleich des menschlich Auges von hier:
http://www.mikrocontroller.net/articles/LED-Fading

hat jemand eine Idee wie ich den Time-Interrupt verkürzen könnte?
#2699806
Lesenswert?
• ▲
▼
Hallo,

da wir nicht den gesamten Code sehen, rate ich mal.

Man muss den gesamten logischen Aufbau deines Programms überarbeiten !

In der Main könnte man
1
<datentype> * coderun_ptr= &coderunT[y];

zuweisen.

Was soll das ?
1
cli(); sei();

Welchen Datentyp hat |i++| ?
#2699818
Lesenswert?
• ▲
▼
Als erstes entfernst du mal das cli/sei. Das ist nicht nur komplett 
überflüssig, sondern sogar gefährlich.

Und dann probiere es mit "vorberechneten" Zeigern statt eines Indexes 
für die 1. Dimension.
Statt
1
uint8_t y;
2

3
main ...
4
  y = 2;
5

6
ISR ...
7
  OCR1A = coderunT[y][i];
eher so was
1
uint8_t *yT;
2

3
main ...
4
  yT = &coderunT[2][0]
5

6
ISR ...
7
  OCR1A = yT[i];
OP #2699832
Lesenswert?
• ▲
▼
hab eben komplett auf eindimensional umgebaut bring fast eine Halbierung 
der zeit SUPER cli/sei werde ich gleich mal probieren.

bezüglich:

"Du könntest dir im übersetzen Code ansehen, was in der ISR alles auf 
dem
Stack gesichert wird, Überflüssiges rauschschmeißen und den Rest als
Assemblercode in dein Programm einbinden."

ich verwende AVR Studo 4.17 neuer geht nicht wenden isp programmiert 
Gerät
wo kann ich das anschauen? Hab das noch nie gemacht!
OP #2699865
Lesenswert?
• ▲
▼
ok dann schau mal drüber vielleicht siehst du ja was was ich falsch 
mache.
variablen Tabellen lass ich mal weg die brauchen zu fiel platz.
1
#include <stdint.h>
2
#include <string.h>
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5

6
int main()
7
{
8
DDRA = 0xFF; 
9
DDRC = 0xFF;
10
DDRD = 0x00;
11
DDRB = 0x00;
12

13
  //ext inetrupt
14
  GIMSK |= (1<<INT1); //(External Interrupt Request 1 Enable) 
15
  GIMSK |= (1<<INT0); //(External Interrupt Request 0 Enable) 
16
  MCUCR |= (1<<ISC11); //Die steigende Flanke an INT1 erzeugt einen Interrupt
17
  MCUCR |= (1<<ISC10); //Die steigende Flanke an INT1 erzeugt einen Interrupt
18
  MCUCR |= (1<<ISC01); //Die steigende Flanke an INT0 erzeugt einen Interrupt.
19
  MCUCR |= (1<<ISC00); //Die steigende Flanke an INT0 erzeugt einen Interrupt.
20

21

22
// Timer 1 konfigurieren (16bit)
23
  TCCR1B |= (1<<WGM12); // CTC Modus
24
//  TCCR1B |= (1<<CS12); // Prescaler 256/1024
25
  TCCR1B |= (1<<CS11); // Prescaler 8 /64
26
//  TCCR1B |= (1<<CS10); // Prescaler 64/1024/1
27
// (16000000/64/1600) = 156,25
28
// (16000000/8/408000) = 4,9
29
  OCR1A= 20000;
30
// Compare Interrupt erlauben
31
  TIMSK |= (1<<OCIE1A);
32
  
33

34

35

36

37

38
// Global Interrupts aktivieren// Global Interrupts aktivieren
39
  sei();
40
//hauptrotine
41
while( 1 ) 
42
{
den code zum füllen des RAMs (neues Bild) lass ich auch weg der greift 
in den anderen code nicht ein.
1
 
2
ISR(INT0_vect)
3
  {
4
  TCNT1 = 0;  //sync Timer
5
  y=0;    //sync Bild
6
  OCR1A = 1;  //direkter aufruf time interupt  
7
  }
8
ISR(INT1_vect)
9
  {
10
  y++;    //sync Zeile Zählen
11
  if (y==16)y=0;
12
  i=y*16;    //sync Zeile PWMwert  
13
  PORTA = 0x00;  //Verhindert schaten von vorhergegangener zeile Port A
14
  PORTC = 0x00;  //Verhindert schaten von vorhergegangener zeile Port C      
15
  }
16
//time interupt
17
ISR (TIMER1_COMPA_vect)
18
  {
19
  cli();
20
  OCR1A = coderunT[i];  //Aktualisirung Zeitwert OCR1A
21
  PORTA = coderunA[i];  //Aktualisirung Port A
22
  PORTC = coderunC[i];  //Aktualisirung Port C
23
  i++;  
24
  sei();
25
  }
die ersten beiden Interrupts synchronisieren die zwei Atmega32 für Zeile 
und Spalte der code hier ist für Spalte

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.