AVR PWM Register wie schieberegister befüllen

Gast #4960245
Lesenswert?
• ▲
▼
Hallo,

Wahrscheinlich stelle ich mich einfach blöd an.

Will die SPI Schnittstelle eines Attiny44 nicht nutzen. Da mir dann PWM 
Ports verloren gehen.

Also habe ich folgende Funktion zum befüllen des OCR0A Registers 
verwendet.
1
void readdata(){
2
  int bitcounter = 0;
3
  char daten = "" ;
4
  while(bitcounter < 8){
5
    if(PINA &  ( 1 << PINA0 )){
6
      value = true;
7
      PORTA |= (1 << PA2);
8
    }
9
    else{
10
      value = false;
11
      PORTA &= ~(1 << PA2);
12
    }
13
    
14
    if((oldvalue == false) & (value == true)){
15
      
16
      
17
      if (PINA & (1 << PINA1))
18
      {
19
        OCR0A |= (1 << i);
20
      } 
21
      else
22
      {
23
        OCR0A &= ~(1 << i);
24
      }
25
                        bitcounter++;    
26
                  }
27
    
28
    oldvalue = value;
29
  }
30
  
31
}

PA2 ist lediglich eine Kontrolleuchte. Wo liegt der fehler?
#4960323
Lesenswert?
• ▲
▼
Du schreibst hier direkt in ein aktives Hardware Register:
1
if (PINA & (1 << PINA1))
2
      {
3
        OCR0A |= (1 << i);
4
      } 
5
      else
6
      {
7
        OCR0A &= ~(1 << i);
8
      }

Das wird schief gehen.
Nimm dir eine Hilfsvariable und schreibe die erst am Ende in Register.

"char" ist übrigens eine blöde Idee, das ist i.d.R. mit Vorzeichen! Wenn 
dann uint8_t (braucht <stdint.h>) oder "unsigned char".

Ansonsten fehlt mir hier auch eine Beschreibung, was für ein Fehler denn 
genau auftritt.
Gast #4960359
Lesenswert?
• ▲
▼
1
void readdata(){
2
  bool oldvalue = false;
3
  bool value = false;
4
  int bitcounter = 0;
5
  unsigned char daten = "" ;
6
  while(bitcounter < 8){
7
    if(PINA &  ( 1 << PINA0 )){
8
      value = true;
9
      PORTA |= (1 << PA2);
10
    }
11
    else{
12
      value = false;
13
      PORTA &= ~(1 << PA2);
14
    }
15
    
16
    if((oldvalue == false) & (value == true)){
17
      
18
      
19
      if (PINA & (1 << PINA1))
20
      {
21
        daten |= (1 << i);
22
        PORTA |= (1 << PA3);
23
      } 
24
      else
25
      {
26
        daten &= ~(1 << i);
27
        PORTA &= ~(1 << PA3);
28
      }
29
      bitcounter++;
30
    }
31
    
32
    oldvalue = value;
33
  }
34
  OCR0A = daten;
35
}

Jetzt hat das PWM immer einen festen Tastgrad, auch scheiße.
Angehängte Dateien:
Gast #4960403
Lesenswert?
• ▲
▼
1
void readdata(){
2
  bool oldvalue = false;
3
  bool value = false;
4
  int bitcounter = 0;
5
  uint8_t daten = 0 ;
6
  while(bitcounter < 8){
7
    if(PINA &  ( 1 << PINA0 )){
8
      value = true;
9
      PORTA |= (1 << PA2);
10
    }
11
    else{
12
      value = false;
13
      PORTA &= ~(1 << PA2);
14
    }
15
    
16
    if((oldvalue == false) & (value == true)){
17
      
18
      
19
      if (PINA & (1 << PINA1))
20
      {
21
        daten |= (1 << bitcounter);
22
        PORTA |= (1 << PA3);
23
      } 
24
      else
25
      {
26
        daten &= ~(1 << bitcounter);
27
        PORTA &= ~(1 << PA3);
28
      }
29
      bitcounter++;
30
    }
31
    
32
    oldvalue = value;
33
  }
34
  OCR0A = daten;
35
  daten = 0;
36
}

die Variable heißt bitcounter nicht i.

Aber jetzt habe ich ein anderes Problem jedes mal wenn ich den bitstream 
sende wird der Tastgrad größer und bleibt nicht gleich. mir scheint es, 
als wuerde das Register OCR0A immer mehr befüllt wo kann das problem 
liegen?

als beispiel habe ich einen Bitstream mit dem Wert 64 im Dezimalsystem 
gesendet. Wie auf dem Screenshot vom Oszilloskop.
Gast #4960964
Lesenswert?
• ▲
▼
1
/*
2
 * PWMShifter.c
3
 *
4
 * Created: 28.03.17 17:55:08
5
 * Author : jan
6
 */ 
7

8
#include <avr/io.h>
9
#include <stdbool.h>
10
#include <stdint.h>
11

12
int i = 0;
13

14

15

16
void readdata(){
17
  bool oldvalue = false;
18
  bool value = false;
19
  int bitcounter = 0;
20
  uint8_t daten = 0 ;
21
  while(bitcounter < 8){
22
    if(PINA &  ( 1 << PINA0 )){
23
      value = true;
24
      PORTA |= (1 << PA2);
25
    }
26
    else{
27
      value = false;
28
      PORTA &= ~(1 << PA2);
29
    }
30
    
31
    if((oldvalue == false) & (value == true)){
32
      
33
      
34
      if (PINA & (1 << PINA1))
35
      {
36
        daten |= (1 << bitcounter);
37
        PORTA |= (1 << PA3);
38
      } 
39
      else
40
      {
41
        daten &= ~(1 << bitcounter);
42
        PORTA &= ~(1 << PA3);
43
      }
44
      bitcounter++;
45
    }
46
    
47
    oldvalue = value;
48
  }
49
  
50
  daten = 0;
51
}
52

53
int main(void)
54
{
55
  DDRA = (0b00001100);
56
  DDRB = (0b00000100);
57
  TCCR0A |= (1 << WGM00)|(1 << WGM01)|(1 << COM0A1);
58
  TCCR0B |= (1 << CS00);
59
  
60
    /* Replace with your application code */
61
    while (1) 
62
    {
63
    readdata();
64
    
65
    
66
    
67
    
68
    }
69
}
#4961005
Lesenswert?
• ▲
▼
Jan R. schrieb:
> Wo liegt der fehler?

Zu einem Programm gehört erstmal eine Funktionsbeschreibung, also was es 
eigentlich machen soll.
Falls es ein SPI-Slave-Receiver werden soll, fehlt zuerst mal die 
Synchronisation mit dem Master, also die Auswertung des /CS Signals.

Auch kannst Du Dich nicht für einen Code entscheiden. Mal ist OCR0A da, 
mal dort oder gar nicht drin.
Häng endlich mal den wirklichen Code als *.c an.
#4961053
Lesenswert?
• ▲
▼
Man kann die Flankenerkennung auch deutlich einfacher machen:
1
#define SCK     (1<<PINA0)
2
#define MOSI    (1<<PINA2)
3

4
uint8_t readdata( void )
5
{
6
  uint8_t daten = 0;
7
  
8
  for( uint8_t i = 8; i; i-- ){
9
    while( (PINA & SCK) == 0 ); 
10
    while( (PINA & SCK) != 0 );         // SCK: 1 -> 0 transition
11
    daten >>= 1;                        // LSB first
12
    if( (PINA & MOSI) != 0 )
13
      daten |= 0x80;
14
  }
15
  return daten;
16
}

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

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.