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  | }
  |