1 | /*
|
2 | *
|
3 | * USARTC0, Tx Pin -> PC3.
|
4 | * 9600 baud mit 2 MHz clock. BSCALE = 0
|
5 | * BSEL = ( 32000000 / (2^0 * 16*19200)) -1 = 12
|
6 | * Fbaud = 32000000 / (2^0 * 16 * (12+1)) = 9615 bits/sec
|
7 | */
|
8 |
|
9 |
|
10 | #define PHASE_A (PORTD_IN & 0x01)
|
11 | #define PHASE_B (PORTD_IN & 0x02)
|
12 |
|
13 |
|
14 | #include <avr/io.h>
|
15 | #include <avr/interrupt.h>
|
16 | #include <string.h>
|
17 | #include <asf.h>
|
18 | #include <stdio.h>
|
19 |
|
20 | void Clock_init(void);
|
21 | void Int_init(void);
|
22 | void UART_init(void);
|
23 |
|
24 | void TimerC0_init(void);
|
25 | void TimerE0_init(void);
|
26 |
|
27 | void Send_UART(unsigned int data);
|
28 | void impulsgeber_init (void);
|
29 | int8_t encode_read1(void);
|
30 |
|
31 | //Variablen
|
32 | char lenght = 0x00;
|
33 | char Counter = 0x00;
|
34 |
|
35 | unsigned int TCTW=0x85ED; // TimerXTopWert
|
36 | unsigned int TETW=0x7D00;
|
37 |
|
38 | unsigned int new = 0;
|
39 | volatile int8_t enc_delta; // -128 ... 127
|
40 | static int8_t last;
|
41 | int8_t encval = 0;
|
42 |
|
43 |
|
44 | int main(void)
|
45 | {
|
46 | Clock_init();
|
47 | Int_init();
|
48 | UART_init();
|
49 |
|
50 | TimerC0_init();
|
51 | TimerE0_init();
|
52 |
|
53 |
|
54 |
|
55 | PORTB.DIR = 0x00; //Datenrichtung auf Eingang
|
56 | PORTD.DIR = 0x00;
|
57 | TCC0.PER = TCTW;
|
58 | TCE0.PER = TETW;
|
59 |
|
60 | while(1)
|
61 | {
|
62 |
|
63 | encval=encode_read1();
|
64 |
|
65 | }
|
66 | }
|
67 |
|
68 |
|
69 | //____________INITFunktionen_______________
|
70 |
|
71 | void Clock_init(void)
|
72 | {
|
73 | OSC.CTRL |= OSC_RC32MEN_bm; // Oszillator auf 32Mhz stellen
|
74 | while(!(OSC.STATUS & OSC_RC32MEN_bm)); // Warten bis der Oszillator bereit ist
|
75 | CCP = CCP_IOREG_gc;
|
76 | CLK.CTRL = CLK_SCLKSEL_RC32M_gc; // Clock auf 32MHz stellen
|
77 | }
|
78 |
|
79 | void Int_init(void)
|
80 | {
|
81 | PMIC.CTRL |= PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; // Interrupts (Highlevel, Mediumlevel und Lowlevel freigeben)
|
82 | sei(); // Globale Interruptfreigabe
|
83 | }
|
84 |
|
85 | void UART_init(void)
|
86 | {
|
87 | PORTC.DIR = 0xEF;
|
88 |
|
89 | USARTC0.BAUDCTRLB = 0; // BSCALE = 0
|
90 | USARTC0.BAUDCTRLA = 0x67; // Baudrate 19200 @ 41MHz
|
91 | USARTC0.CTRLB = USART_TXEN_bm | USART_RXEN_bm; // RX+TX Enable CLK
|
92 | USARTC0.CTRLC = 0x03; // Async, no parity, 8 bit data, 1 stop bit
|
93 | USARTC0.CTRLA = 0;
|
94 | }
|
95 |
|
96 | void impulsgeber_init (void)
|
97 | {
|
98 | if( PHASE_A )
|
99 | new = 3;
|
100 | if( PHASE_B )
|
101 | new ^= 1; // new = new^1 ---- convert gray to binary
|
102 | last = new; // power on state
|
103 | enc_delta = 0;
|
104 | }
|
105 |
|
106 |
|
107 | //_______________________TIMER________________________
|
108 |
|
109 | void TimerC0_init()
|
110 | {
|
111 | TCC0.CTRLA = TC_CLKSEL_DIV1024_gc; // Vorteiler einstellen
|
112 | TCC0.CTRLB = 0x00; // Timer in Normalmodus stellen
|
113 | TCC0.INTCTRLA = 0x03; // Interrupt konfigurieren
|
114 | }
|
115 |
|
116 | void TimerE0_init(void)
|
117 | {
|
118 | TCE0.CTRLA = TC_CLKSEL_DIV2_gc; // Vorteiler einstellen
|
119 | TCE0.CTRLB = 0x00; // Timer in Normalmodus stellen
|
120 | TCE0.INTCTRLA = 0x02;
|
121 | }
|
122 |
|
123 |
|
124 | //______________________TimerISR_______________________
|
125 |
|
126 | ISR(TCC0_OVF_vect)
|
127 | {
|
128 |
|
129 | Send_UART(encval);
|
130 |
|
131 | TCC0.PER = TCTW;
|
132 |
|
133 | }
|
134 |
|
135 | ISR(TCE0_OVF_vect)
|
136 | {
|
137 | int8_t new, diff;
|
138 | new = 0;
|
139 | if( PHASE_A )
|
140 | new = 3;
|
141 | if( PHASE_B )
|
142 | new ^= 1; // convert gray to binary
|
143 | diff = last - new; // difference last - new
|
144 | if( diff & 1 ){ // bit 0 = value (1)
|
145 | last = new; // store new as next last
|
146 | enc_delta += (diff & 2) - 1; // bit 1 = direction (+/-)
|
147 | }
|
148 |
|
149 | TCE0.PER=TETW;
|
150 |
|
151 | }
|
152 |
|
153 |
|
154 | //_______________Sonstige Funktionen__________________
|
155 |
|
156 | void Send_UART(unsigned int data)
|
157 | {
|
158 | while (!(USARTC0.STATUS & USART_DREIF_bm));
|
159 | USARTC0.DATA = data;
|
160 | }
|
161 |
|
162 |
|
163 | int8_t encode_read1( void ) // read single step encoders
|
164 | {
|
165 | int8_t val;
|
166 |
|
167 | cli();
|
168 | val = enc_delta;
|
169 | enc_delta = 0;
|
170 | sei();
|
171 | return val; // counts since last call
|
172 | }
|