Hi,
@Krapao: Danke, kenn ich aber schon.
ich habe jetzt versucht, mich nach dem Code von Thomas Pfeiffer zu
richeten.
http://thomaspfeifer.net/ppm2usb_adapter.htm
Das Problem ist, dass bei start ein paar Messungen durchgeführt werden
(die Anzahln varriiert, mal 6, mal 30 usw.) Die Werte sind da auch
richtig. Doch dann gehts nich mehr weiter, der Mega hängt sich irgentwie
auf oder so. Die Led, auf dem Board ist dann auch an, obwohl sie nur
beim Initialiesieren an sein sollte, aber sie ist dunkler, also ob sie
schnell ann und aus gemacht wird, oder weniger Spannung bekommt.
Hier der Code:
Main.c
1 | #define BAUD 115200UL
|
2 | #define F_CPU 18432000UL
|
3 | #include <util/delay.h>
|
4 | #include <avr/io.h>
|
5 | #include <avr/interrupt.h>
|
6 | #include <stdio.h>
|
7 | #include <stdlib.h>
|
8 |
|
9 | #include "ppm.h"
|
10 |
|
11 | #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
|
12 | #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
|
13 | #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
|
14 |
|
15 | #if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
|
16 | #warning Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
|
17 | #endif
|
18 |
|
19 | volatile unsigned long long time;
|
20 |
|
21 | void delay_ms(double t)
|
22 | {
|
23 | for(int i=0;i<t;i++)
|
24 | {
|
25 | _delay_ms(1);
|
26 | }
|
27 | }
|
28 |
|
29 | void uart_init(void)
|
30 | {
|
31 | //UART0 GPS
|
32 | UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);
|
33 | UCSR0C |= (1<<UCSZ01)|(1<<UCSZ00);
|
34 |
|
35 | UBRR0H = UBRR_VAL >> 8;
|
36 | UBRR0L = UBRR_VAL & 0xFF;
|
37 |
|
38 | //UART1 XBee
|
39 | UCSR1B |= (1<<RXEN1)|(1<<TXEN1);//|(1<<RXCIE1);
|
40 | UCSR1C |= (1<<UCSZ11)|(1<<UCSZ10);
|
41 |
|
42 | UBRR1H = UBRR_VAL >> 8;
|
43 | UBRR1L = UBRR_VAL & 0xFF;
|
44 | }
|
45 |
|
46 | int uart_putc(unsigned char c)
|
47 | {
|
48 | while (!(UCSR1A & (1<<UDRE1)))
|
49 | ;
|
50 | UDR1 = c;
|
51 | return 0;
|
52 | }
|
53 |
|
54 | void uart_puts (char *s)
|
55 | {
|
56 | while (*s)
|
57 | {
|
58 | uart_putc(*s);
|
59 | s++;
|
60 | }
|
61 | }
|
62 |
|
63 | int main(void)
|
64 | {
|
65 | DDRB = (1<<0);
|
66 | PORTB = (1<<0);
|
67 | uart_init();
|
68 | ppmInit();
|
69 | sei();
|
70 | PORTB &= ~(1<<0);
|
71 |
|
72 | while(1)
|
73 | {
|
74 | if(ppmNewData==1)
|
75 | {
|
76 | ppmNewData = 0;
|
77 | unsigned char p[6];
|
78 | for(int i=0;i<6;i++)
|
79 | {
|
80 | p[i] = ppmGet(i);
|
81 | }
|
82 | char out[255];
|
83 | int n = sprintf(out,"%d, %d, %d, %d, %d, %d\n",p[0],p[1],p[2],p[3],p[4],p[5]);
|
84 | for(int i=0;i<n;i++)
|
85 | uart_putc(out[i]);
|
86 | }
|
87 | }
|
88 | }
|
ppm.h
Den code habe ich fast komplett übernommen, nur ein paar Anpassungen
gemacht, z.b. den Prescaler auf 64 gesetzt und die Register angepasst.
1 | #include <avr/io.h>
|
2 | #include <avr/interrupt.h>
|
3 |
|
4 | #ifndef PPM_H_
|
5 | #define PPM_H_
|
6 |
|
7 | extern volatile char ppmNewData;
|
8 | void ppmInit();
|
9 | unsigned char ppmGet(int n);
|
10 |
|
11 | #endif /* PPM_H_ */
|
ppm.c
1 | #include "ppm.h"
|
2 |
|
3 | #define PPM_CHANNELS (6)
|
4 | volatile unsigned int ppm[PPM_CHANNELS];
|
5 | volatile int chan = -1;
|
6 |
|
7 | #define T_MIN ((1*F_CPU)/64/1000)
|
8 | #define T_MAX ((2*F_CPU)/64/1000)
|
9 | #define T_OUT ((3*F_CPU)/64/1000)
|
10 |
|
11 | volatile char ppmNewData;
|
12 | volatile unsigned int timeOld;
|
13 |
|
14 |
|
15 | void ppmInit()
|
16 | {
|
17 | TCCR1B = (1<<CS11)|(1<<CS10); //Prescaler 8
|
18 | TCCR1B |= (1<<ICNC1); //Noise canceler
|
19 | TCCR1B |= (1<<ICES1);
|
20 | TIMSK1 = (1<<ICIE1) | (1<<OCIE1A);
|
21 |
|
22 | ppmNewData=0;
|
23 | chan=-1;
|
24 | }
|
25 |
|
26 | ISR(TIMER1_COMPA_vect)
|
27 | {
|
28 | if(chan!=-1)
|
29 | {
|
30 | ppmNewData = 1;
|
31 | }
|
32 | chan=-1;
|
33 | }
|
34 |
|
35 | ISR(TIMER1_CAPT_vect)
|
36 | {
|
37 | unsigned int time=ICR1;
|
38 | OCR1A=time+T_OUT;
|
39 | if (time>timeOld)
|
40 | {
|
41 | time=time-timeOld;
|
42 | }
|
43 | else
|
44 | {
|
45 | time=time+(0xffff-timeOld)+1;
|
46 | }
|
47 | timeOld=ICR1;
|
48 | if (chan>=0 && chan<PPM_CHANNELS)
|
49 | {
|
50 | ppm[chan]=time;
|
51 | }
|
52 | chan++;
|
53 | }
|
54 |
|
55 | unsigned char ppmGet(int n) {
|
56 | unsigned int t=ppm[n];
|
57 |
|
58 | // conversion T_MIN...T_MAX -> 0...255
|
59 | if (t<T_MIN) t=T_MIN;
|
60 | t-=T_MIN;
|
61 | t=t/((T_MAX-T_MIN)/255);
|
62 | if (t>255) t=255;
|
63 |
|
64 | return ((unsigned char)t);
|
65 | }
|
Die Verkabelung scheint richtig zu sein, weil die paar Messungen bis zum
Ausfhängen richtig sind, außerdem überprüfe ich das Signal laufend
mitnem Oszi.
Was könnte sein?
Manchmal habe ich probleme mit der sei() Funktion, habe auch schon
mehrere Positionen im code getestet, geht aber alles nicht.
MfG
Philipp