1 | /*
|
2 | * Telefon.c
|
3 | *
|
4 | * Created: 05.08.2013 13:44:22
|
5 | */
|
6 |
|
7 | #include <avr/io.h>
|
8 | #include <stdint.h>
|
9 | #include <stdio.h>
|
10 | #include <avr/interrupt.h>
|
11 | #include <inttypes.h>
|
12 |
|
13 | #ifndef F_CPU
|
14 | #define F_CPU 14745600
|
15 | #endif
|
16 | #define UART_BAUD_RATE 115200
|
17 |
|
18 | #include <util/delay.h>
|
19 |
|
20 | uint8_t senden; //wert der an Schieberegister gesendet wird
|
21 | uint8_t empfang;
|
22 | uint8_t tmp_sreg; //SREG zwischenspeicher in interrupts
|
23 | uint8_t status; //status des Programms
|
24 | uint16_t counter; //counter 16bit gross
|
25 | // Hilfsmakro zur UBRR-Berechnung ("Formel" laut Datenblatt)
|
26 | #define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)
|
27 |
|
28 | //*******************************************************Interrupts*********************************************
|
29 | //Interrupt Flanke an INT0 A&B Signal Encoder
|
30 | //lese A/D Wandleraus und speichere in S-ram
|
31 | ISR (INT0_vect)
|
32 | {
|
33 | uint8_t werth; // Speicher für A/D Wert high
|
34 | uint8_t wertl; //Speicher für A/D Wert low
|
35 |
|
36 | tmp_sreg = SREG; //SREG sichern
|
37 | uint8_t temp; // lokale Variable
|
38 |
|
39 | counter++; //counter +1
|
40 |
|
41 | //A/D Wandlung und speichern in S-ram Funktioniert!
|
42 |
|
43 | // PORTD = 0b01000000; //CS SChieberegister auf OFF A/D auf ON
|
44 | PORTB |= (1<<PB4) ; //Setze PB4 auf 1 CONV von A/D Wandler
|
45 | PORTB &= ~ (1<<PB4) ; //Setze PB4 auf 0 CONV von A/D Wandler
|
46 | PORTB |= (1<<PB4) ; //Setze PB4 auf 1 CONV von A/D Wandler
|
47 | _delay_ms(0.005); //CONVERTIERUNG max 5 mikro sekunden
|
48 |
|
49 | SPDR=senden; //Irgendwas senden um übertragung zu starten
|
50 | while (!(SPSR & (1<<SPIF))) // warten bis übertragung fertig
|
51 | ;
|
52 | temp = SPDR; // Wert in temp schreiben
|
53 | werth= temp<<1; //um 1ns nach links verschieben ausgabe an PortA = highbyte
|
54 |
|
55 | SPDR = senden++; // neuen Wert in SPDR schreiben um neue übertragung zu starten
|
56 | while (!(SPSR & (1<<SPIF))) // warten bis übertragung fertig
|
57 | ;
|
58 | temp = SPDR;
|
59 | wertl=temp;
|
60 | if (temp>127) //falls temp kleiner als 127 ist ist das MSB nicht gesetzt
|
61 | {
|
62 | werth = werth | 0b00000001;
|
63 | }
|
64 | wertl=wertl<<1;
|
65 | wertl = wertl & (0b11110111); //4tes bit invertieren auf 0
|
66 | PORTA=werth; //Ausgabe an PortA = Highbyte
|
67 | PORTC=wertl; //Ausgabe an PortC = lowbyte
|
68 |
|
69 | // PORTA=counter;
|
70 | // PORTC=0;
|
71 |
|
72 | //********************************************ADWANDLER AUSGELESEN RESULTAT AN PINS DES MIKROK**************
|
73 | //speichern im S-RAM
|
74 | PORTB &= ~ (1<<PB2); //PB2=WE auf 0 S-ram
|
75 | PORTB |= (1<<PB2); //PB2=WE auf 1 S-ram
|
76 |
|
77 | PORTD &= ~ (1<<PD7); //PD7 auf 0 setzen Zähler +1 = S-ram adresse +1 = SPEICHERN
|
78 | PORTD |= (1<<PD7); //PD7=zähler+1 wieder auf 1 setzen
|
79 |
|
80 | //******************************************SPEICHERN IN S-RAM fertig***************************************
|
81 | SREG = tmp_sreg; //SREG wider herstellen
|
82 |
|
83 | }
|
84 |
|
85 | //Interrupt Funktion Positive Flanke an INT1 Z Signal Encoder
|
86 | ISR (INT1_vect)
|
87 | {
|
88 | tmp_sreg = SREG; //SREG sichern
|
89 | if (status==2) //beginne mit der Messung
|
90 | {
|
91 | GICR = (1<<INT1)|(1<<INT0); // aktivieren von INT0 = AB Impuls
|
92 | }
|
93 | status++;
|
94 |
|
95 | SREG = tmp_sreg; //SREG wider herstellen
|
96 |
|
97 | }
|
98 |
|
99 | //**********************************************Funktionen*******************************************
|
100 | //Motorstart Funktion
|
101 | uint8_t startmotor()
|
102 | {
|
103 | DDRA = 0xff; //Port A = Ausgang
|
104 | DDRC = 0xff; //Port C = Ausgang
|
105 | PORTD |= (1<<PD7); //Counter auf 1 setzen bereit für negative Flanke
|
106 | PORTB |= (1<<PB0)|(1<<PB3)|(1<<PB1)|(1<<PB2); //PB0 starte Motor PB3 clear counter PB1 & PB2 = OE und WE auf 1 S-ram
|
107 | PORTB &= ~(1<<PB3); //clear counter wider weg
|
108 | counter=0; //zähler reseten
|
109 | GICR = (1<<INT1); // aktivieren von INT1 = Z Impuls
|
110 | status++; // sollte jetzt status=2 sein
|
111 | return(0);
|
112 | }
|
113 |
|
114 | //auslesen aus S-Ram und SENDEN FUNKTION... Funktioniert!
|
115 | uint8_t auslesen(void)
|
116 | {
|
117 | uint16_t temp; // lokale Variable
|
118 | cli(); //schalte Interrupts aus
|
119 |
|
120 | GICR &= ~ ((1<<INT1)|(1<<INT0)); //deaktivieren von Interrupts
|
121 | DDRA = 0x00; //PortA als Eingang
|
122 | DDRC = 0x00; //PortC als eingang
|
123 |
|
124 | PORTB |= (1<<PB3)|(1<<PB2); //PB3=CLR counter auf 1 PB2= WE S-ram auf 1
|
125 | PORTB &= ~ ((1<<PB0)|(1<<PB3)|(1<<PB1)); // stoppe Motor, Counter wider auf 0 OE s-ram auf low = ausgabe
|
126 |
|
127 | temp=counter;
|
128 |
|
129 | while(temp>=2)
|
130 | {
|
131 | while(!(UCSRA & (1<<UDRE))) // Warten bis senden bereit
|
132 | ;
|
133 | UDR=PINA; //highbyte wird gesendet
|
134 | while(!(UCSRA & (1<<UDRE))) // Warten bis senden bereit
|
135 | ;
|
136 | UDR=PINC; //lowbyte wird gesendet
|
137 |
|
138 | PORTB |= (1<<PB2); //S-ram WE auf 1
|
139 | PORTD &= ~ (1<<PD7); //PD7 auf 0 setzen Zähler +1 = S-ram adresse +1
|
140 | PORTD |= (1<<PD7); //PD7=zähler+1 wieder auf 1 setzen
|
141 | temp--;
|
142 | }
|
143 | status++; //status=5
|
144 | return(0);
|
145 | }
|
146 | uint8_t statussend(void)
|
147 | {
|
148 | printf("m"); //eigentlich nichts machen aber es funktioniert nur mit printf
|
149 |
|
150 | return(0);
|
151 | }
|
152 |
|
153 | //EMPFANG FUNKTION
|
154 | uint8_t uartempfangen (void)
|
155 | {
|
156 | while(!(UCSRA & (1<<RXC))) // Warten bis empfangen
|
157 | ;
|
158 | empfang = UDR;
|
159 |
|
160 | status=1; //stauts auf 1 setzen
|
161 | counter=0;
|
162 | sei(); //Innterrupts erlauben
|
163 | return (0);
|
164 | }
|
165 |
|
166 | //SPI
|
167 | uint8_t shiftreg (void)
|
168 | {
|
169 |
|
170 | //PORTD = 0b00100000; //CS SChieberegister auf OFF A/D auf ON
|
171 | SPDR = senden;
|
172 | while (!(SPSR & (1<<SPIF))) // warten bis übertragung fertig
|
173 | ;
|
174 | //0-1-0 Puls an STCP von Schieberegister um Werte zu übernehmen
|
175 | PORTB &= ~ (1<<PB4) ;
|
176 | PORTB |= (1<<PB4);
|
177 | PORTB &= ~ (1<<PB4) ;
|
178 |
|
179 | status=0;
|
180 |
|
181 | return(0);
|
182 | }
|
183 |
|
184 | //ENDE FUNKTIONEN
|
185 | int main(void)
|
186 | {
|
187 | while(1)
|
188 | {
|
189 | //Serielle Schnittstelle einrichten
|
190 | UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) >> 8 );
|
191 | UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );
|
192 | // Frameformat = 8 Bit
|
193 | UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
|
194 | //Datenrichtungsregister
|
195 | DDRA = 0x00; //alles eingänge
|
196 | DDRB = 0b10111111; //Alles Ausgänge ausser PB6
|
197 | DDRC = 0x00; //alles Eingänge
|
198 | DDRD = 0b11100010;
|
199 |
|
200 | PORTD = 0b00000000; //schiberegister und CS von A/D Wandler auf ON
|
201 |
|
202 | UCSRB = (1 << TXEN)|(1 << RXEN); // Setzt TXEN und RXEN Bit= Transmitter Enable Reciver enable
|
203 |
|
204 | //SPI EINRICHTEN
|
205 | SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<CPHA); //SPI ENABLE,MASTER, set clock rate fck/16,fallende Taktflanke = einlesen
|
206 | SPSR = (1<<SPI2X); // Douple speed aktivieren
|
207 | PORTB |= (1<<PB4)|(1<<PB1)|(1<<PB2) ; //Setze PB4 auf 1 CONV von A/D Wandler PB1&2 = S-ram disabled
|
208 |
|
209 | SPDR=213; //Dummy Daten senden
|
210 |
|
211 | //Interrupt Eingänge Encoder
|
212 | MCUCR = (1<<ISC00)|(1<<ISC11)|(1<<ISC10); // ISC00 auf 1 = jede änderung an INT 0 lösst einen Interrupt aus
|
213 | // ISC11&10 auf 1 = positivie Flanke INT 1 lösst Interrupts aus
|
214 | status = 0 ;
|
215 | senden = 0b00000110;
|
216 | counter=0;
|
217 | while (1) // unentliche schleife
|
218 | {
|
219 | switch(status)
|
220 | {
|
221 | case 0: uartempfangen();break; // warten bis LABVIEW bereit
|
222 | case 1: startmotor();break; //Motor starten beginne Messung nach Z Impuls
|
223 | case 2: statussend();break; //nichts machen warte auf Z impuls
|
224 | case 3: statussend();break; //nichts machen warte auf Messung= fertig
|
225 | case 4: auslesen();break; //auslesen des s-rams Senden auf schnitstelle
|
226 | case 5: shiftreg();break; //irgendetwas auf den I/O Pins anzeigen
|
227 | default: status=0;break; //default = neustart
|
228 | }
|
229 |
|
230 | }
|
231 | }
|
232 | return 0;
|
233 | }
|