1 | #include <avr/io.h>
|
2 | #include <util/delay.h>
|
3 | #include <stdlib.h>
|
4 | #include <avr/interrupt.h>
|
5 | #define F_CPU 4000000UL // Systemtakt in Hz - Definition als unsigned long beachten
|
6 | #define BAUD 9600UL // Baudrate
|
7 |
|
8 | // Berechnungen
|
9 | #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
|
10 | #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
|
11 | #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
|
12 |
|
13 | #if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
|
14 | #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
|
15 | #endif
|
16 |
|
17 |
|
18 | #define CR "\r\nS
|
19 |
|
20 |
|
21 | #define UART_MAXSTRLEN 10
|
22 |
|
23 | volatile char uart_string[UART_MAXSTRLEN + 1] = "";
|
24 | char textx[32];
|
25 |
|
26 | int channel=1;
|
27 | int channels=2;
|
28 | int adcKanal = 0;
|
29 | int plex = 0;
|
30 | int uart_str_count=0;
|
31 |
|
32 |
|
33 |
|
34 | //Interrupt zur Kanalansteuerung
|
35 | //*******************************
|
36 | ISR(USART_RXC_vect)
|
37 | {
|
38 | unsigned char nextChar;
|
39 | // Daten aus dem Puffer lesen
|
40 | nextChar = UDR;
|
41 | uart_string[uart_str_count] = nextChar;
|
42 | uart_str_count++;
|
43 | send_string("ooo");//100
|
44 |
|
45 | //Interrupt wirs so lange gelesen, bis ein "Z" kommt, dann wird er verarbeitet
|
46 | if( nextChar =='Z')
|
47 | {
|
48 | channels = 0;
|
49 | send_string("dddd");//100
|
50 | //send_string(uart_string);
|
51 | //annel= atoi(uart_string[1]);
|
52 | channels= atoi(&uart_string[1]);
|
53 | send_char(uart_string[1]);
|
54 | sprintf (textx, "%u", channels);
|
55 | send_string(textx);
|
56 | uart_str_count=0;
|
57 |
|
58 | }
|
59 |
|
60 |
|
61 | }
|
62 |
|
63 |
|
64 |
|
65 | //****************************
|
66 | //---------------------------------
|
67 | void init_uart(unsigned int ubrr)
|
68 | //---------------------------------
|
69 | {
|
70 | UBRRH = (unsigned char)(ubrr>>8);
|
71 | UBRRL = (unsigned char)(ubrr);
|
72 | //UCSRB |= (1<<RXEN);
|
73 | //UCSRB |= (1<<TXEN);
|
74 | //UCSRB |= (1<<RXCIE);
|
75 | //UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
|
76 |
|
77 |
|
78 |
|
79 | UBRRH = UBRR_VAL >> 8;
|
80 | UBRRL = UBRR_VAL & 0xFF;
|
81 | UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // Asynchron 8N1
|
82 | UCSRB |= (1<<RXEN)|(1<<TXEN)|(1<<RXCIE); // UART RX, TX und RX Interrupt einschalten
|
83 |
|
84 | sei();
|
85 |
|
86 |
|
87 | }
|
88 |
|
89 | //---------------------------------
|
90 | void init_adc(void)
|
91 | //---------------------------------
|
92 | {
|
93 |
|
94 | uint16_t result;
|
95 |
|
96 | ADMUX = (0<<REFS1) | (1<<REFS0); // AVcc als Referenz benutzen
|
97 | // ADMUX = (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen
|
98 | // Bit ADFR ("free running") in ADCSRA steht beim Einschalten
|
99 | // schon auf 0, also single conversion
|
100 | ADCSRA = (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler
|
101 | ADCSRA |= (1<<ADEN); // ADC aktivieren
|
102 |
|
103 | /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
|
104 | also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
|
105 |
|
106 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
|
107 | while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten
|
108 | /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
|
109 | Wandlung nicht übernommen. */
|
110 | result = ADCW;
|
111 | }
|
112 |
|
113 | //---------------------------------
|
114 | uint16_t ADC_Read( int channel )/* ADC Einzelmessung */
|
115 | //---------------------------------
|
116 |
|
117 | {
|
118 | // Kanal waehlen, ohne andere Bits zu beeinflußen
|
119 | ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
|
120 | ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
|
121 | while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten
|
122 | return ADCW; // ADC auslesen und zurückgeben
|
123 | }
|
124 |
|
125 | //---------------------------------
|
126 | void send_char(unsigned char data)
|
127 | //---------------------------------
|
128 | {
|
129 | while (!(UCSRA & (1<<UDRE)));
|
130 | UDR = data;
|
131 | }
|
132 |
|
133 | //---------------------------------
|
134 | void send_string(char *data)
|
135 | //---------------------------------
|
136 | {
|
137 | while (*data) {
|
138 | send_char(*data);
|
139 | data++;
|
140 | }
|
141 | }
|
142 |
|
143 |
|
144 |
|
145 | //************
|
146 | int main(void)
|
147 | //************
|
148 | {
|
149 |
|
150 |
|
151 | init_uart(UBRR_VAL);
|
152 | init_adc();
|
153 | uint16_t adcval;
|
154 | while (1) {
|
155 | int x = 0;
|
156 | //Kanal 1
|
157 | cli();//interrupts ausschalten
|
158 | //hiereine Schleife, in der die ADCs aufgerufen werden
|
159 | //for(int x = 0;x<sizeArray;x++)
|
160 | for(int x = 0;x<channels;x++)
|
161 | {
|
162 | char text[32];
|
163 | char kanal[100];
|
164 |
|
165 |
|
166 |
|
167 | channel = x%6;
|
168 |
|
169 | //Schalten Multiplexer abhängig vom channel
|
170 | plex = x/6;//d.h. 0-5 sind Plex 0;6-11 sind Plex 1.........
|
171 | //Kanal ist dann der Rest der Rechnung
|
172 | channel = x%6;
|
173 |
|
174 | DDRB = 0xFF; // (3)
|
175 | PORTB = plex; // (4)
|
176 |
|
177 | adcval = ADC_Read(channel);
|
178 | sprintf(kanal, "%d" ,channel);
|
179 | send_string("c");//99
|
180 | send_string("X");//88
|
181 | send_string(kanal);//0=48 1=49
|
182 | send_string("Y");//89
|
183 | sprintf (text, "%u", adcval);
|
184 | send_string(text);
|
185 | send_string("Z");//90
|
186 | send_string("E");//69
|
187 | //send_string(CR);
|
188 | //--> ende while......
|
189 | }
|
190 |
|
191 |
|
192 |
|
193 | sei();//interrupts einschalten
|
194 |
|
195 |
|
196 |
|
197 | _delay_ms(2000);
|
198 |
|
199 | }
|
200 | return 1;
|
201 | }
|