Encoderwert seriell senden

#1078142
Lesenswert?

Hi zusammen,

Ich versuche schon seit Stunden einen Encoder auszulesen und dessen Wert 
seriell auf ein terminal zu senden.

Meine Hardware:
Encoder mit ??1000?? Incrementen (Habe leider keine Daten zu dem Teil)
STK500 mit Atmega 8515L und internem Oszilator

Hier mein Code:
(Ist zu großen Teilen aus dem Forum)
1
#ifndef F_CPU
2
#define F_CPU 36860000UL            // Interner Quarz  
3
#endif
4
    
5
#include <avr/io.h>
6
#include <avr/interrupt.h>
7
#include <stdlib.h>
8

9
#define PHASE_A  (PINC & 1<<PINC6)      // PINC.0
10
#define PHASE_B  (PINC & 1<<PINC7)      // PINC.1
11

12
#define BAUD        9600UL       // Baudrate
13
#define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)   // Baudrate berechen
14

15
              
16
void uart_init(void)        // USART initialisieren
17
{      
18
    UBRRH = (uint8_t) (UBRR_BAUD>>8);          // Baudrate einstellen
19
    UBRRL = (uint8_t) (UBRR_BAUD & 0x0ff);
20

21
    UCSRB = (1<<RXEN)|(1<<TXEN);    // Aktivieren von Rx und Tx
22

23
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);   // Einstellen 8,n,1
24
}
25

26
int uart_putc(unsigned char c)      
27
{
28
    while (!(UCSRA & (1<<UDRE)))     // warten bis Senden moeglich
29
    {
30
    }
31
    UDR = c;                            // Zeichen senden
32
    return 0;
33
}
34

35
void uart_puts (char *s)        
36
{
37
    while (*s)
38
    {   
39
        uart_putc(*s);
40
        s++;
41
    }
42
}
43

44
volatile int16_t enc_delta;            // -32768 ... 32767
45

46
int main( void )
47
{
48
  char text[7];                                         // itoa Variable
49
  
50
  uart_init();  
51
  
52
  TCCR0 = 1<<CS00;              //ohne Vorteiler
53
  TIMSK = 1<<TOIE0;              //enable timer interrupt
54
  
55
  DDRB = 0xFF;
56
  
57
  sei();
58

59
  while(1)                  // main loop
60
  {
61
  uart_puts( itoa(enc_delta,text,10) );      //In String gewandelte Tahl über UART senden
62
  PORTB = enc_delta;        // PORT B mit LED#s um den Wert paralell visuell zu sehen
63
  }
64
return 0;
65
}
66

67
// Encoder Code von  Peter Dannegger (leicht abgeändert ISR usw.)
68
ISR (TIMER0_OVF_vect)
69
{
70
  static int16_t enc_last = 0x01;
71
  int16_t i = 0;
72

73
  if( PHASE_A )
74
    i = 1;
75

76
  if( PHASE_B )
77
    i ^= 3;                      // convert gray to binary
78

79
  i -= enc_last;                 // difference new - last
80

81
  if( i & 1 )                    // bit 0 = value (1)
82
   {       
83
    enc_last += i;               // store new as next last
84
    enc_delta += (i & 2) - 1;    // bit 1 = direction (+/-)
85
   }
86
}

Ich hab schon alles probiert und weiß nicht mehr weiter :/

Hardware ist i.o. Die LED's zählen schön hoch wie es sein sollte,
das senden von normalen Strings geht auch ohne Probleme.

Ich hab die Vermutung das das senden vom Interrupt unterbrochen wird, 
kann das sein ??

Bin leider kein Held in C, aber ist ja noch kein Meister vom Himmel 
gefallen :)

Bouni

P.S. Danke schon mal im Voraus
Gast #1078163
Lesenswert?

Hi

>Atmega 8515L und internem Oszilator

solltest du schleunigst ändern. Mit dem bekommst du keine stabile 
Verbindung.

#define F_CPU 36860000UL            // Interner Quarz

Habe zwar nur rudimentäre C-Kenntnisse, das passt aber für mich nicht zu 
der anderen Aussage.

MfG Spess
#1078168
Lesenswert?

Hi,

spess53 wrote:
> #define F_CPU 36860000UL            // Interner Quarz
>
>.... das passt aber für mich nicht zu
> der anderen Aussage.

Also Ich hab keine Probleme mit dem UART!! der tut tadellos, ich kann 
lange Stringssenden ohne das was nicht/oder verkorkst ankommt !!

Daran kanns also nicht liegen!


Trotzdem Danke für die Antwort
Gast #1078193
Lesenswert?

Hi

>kann ich den einfach auf den Steckplatz vom STK500 stecken ??

Ja. Und die Jumper umstecken. Jumperbelegung steht auf der Unterseite 
des STK.

>uart_puts( itoa(enc_delta,text,10) );

Bist du sicher, das itoa einen string als Funktionsergebnis zurück gibt? 
Ich würde 'uart_puts' eher 'text' übergeben.

MfG Spess
#1078337
Lesenswert?

du meinst also:
1
...
2
 while(1)                  // main loop
3
  {
4
  itoa(enc_delta,text,10);
5
  uart_puts(text);      //In String gewandelte Tahl über UART senden
6
  PORTB = enc_delta;        // PORT B mit LED#s um den Wert paralell visuell zu sehen
7
  }
8
...

Werd das morgen mal testen.


Danke für die Hilfe :)

Bouni
#1078758
Lesenswert?

Hi zusammen,


Habs zum laufen gebracht :D
1
#include <avr/io.h>
2
#include <inttypes.h>
3
#include <util/delay.h>
4
#include <avr/interrupt.h>
5

6
#define F_CPU       3686400UL                               // internal clock 3.686Mhz
7

8
#define BAUD        9600UL                                  // Baudrate
9
#define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)                 // Baudrate berechen
10

11

12
#define PHASE_A  (PINC & 1<<PINC6)                          // PINC.6 -> A
13
#define PHASE_B  (PINC & 1<<PINC7)                          // PINC.7 -> B
14

15
volatile uint16_t enc_delta;                                // -32768 ... 32767
16

17
void uart_init(void)                                        // USART initialisieren
18
{
19
    UBRRH = (uint8_t) (UBRR_BAUD>>8);                       // Baudrate einstellen
20
    UBRRL = (uint8_t) (UBRR_BAUD & 0x0ff);
21
    UCSRB = (1<<RXEN)|(1<<TXEN);                            // Aktivieren von receiver und transmitter
22
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);               // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
23
}
24

25
int uart_putc(unsigned char c)                              // Einzelnes Zeichen über UART senden
26
{
27
    while (!(UCSRA & (1<<UDRE)))                            // Warten bis Senden möglich ist
28
    {
29
    }
30
    UDR = c;                                                // Zeichen senden
31
    return 0;
32
}
33

34
void uart_puts (char *s)                                    // String über UART senden
35
{
36
    while (*s)                                              // Senden bis zum Stringende
37
    {
38
        uart_putc(*s);                                      // Einzelnes Zeichen senden
39
        s++;                                                // Pointer erhöhen
40
    }
41
}
42

43
int main(void)                                              // MAIN
44
{
45
    uart_init();                                            // UART initialisieren
46
    uart_puts("Encoder Wert");                              // Test String senden
47

48
    volatile uint16_t last_enc_delta;                       // Variable für den letzten Encoder Wert
49

50
    TCCR0 = 1<<CS00;                                        // Timer ohne Vorteiler
51
    TIMSK = 1<<TOIE0;                                        // Timer interrupt aktivieren
52
    
53
    sei();                                                  // Globale Interrupts aktivieren
54
    
55
    while (1)                                               // Für immer
56
    {
57
    if(last_enc_delta != enc_delta)                         // Wenn sich der Zähler geändert hat
58
      {
59
      char text[7];                            
60
      itoa(enc_delta,text,10);                              // Zählerwert in String wandeln
61
      uart_puts(text);                                      // String senden
62
      uart_putc('\n');                                      // Neue Zeile
63
      last_enc_delta = enc_delta;                           // Gesendeten Wert als aktuellen eintragen
64
      }
65
    }
66
return 0;                                                   // Wird nie erreicht
67
}
68
/* ENCODER CODE von Peter Dannegger */
69

70
ISR (TIMER0_OVF_vect)                                       // Timer Interrupt
71
{
72
  static int16_t enc_last = 0x01;
73
  int16_t i = 0;
74

75
  if( PHASE_A )
76
    i = 1;
77

78
  if( PHASE_B )
79
    i ^= 3;                                                 // convert gray to binary
80

81
  i -= enc_last;                                            // difference new - last
82

83
  if( i & 1 )                                               // bit 0 = value (1)
84
   {       
85
    enc_last += i;                                          // store new as next last
86
    enc_delta += (i & 2) - 1;                               // bit 1 = direction (+/-)
87
   }
88
}

@ErgoProxy

War in der Tat n Schreibfehler :)



Bouni

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