1 | #ifndef F_CPU
|
2 | #warning "F_CPU wurde nicht extern in der Makefile definiert, es werden 16 Mhz angenommen."
|
3 | #define F_CPU 16000000UL /* Quarz mit 16 Mhz */
|
4 | #endif
|
5 | #define UBBRR_VAL 8 /* initialize USART for 115200 Baud */
|
6 |
|
7 |
|
8 | ///////////////////////////////////////
|
9 | // Main mit Hauptschleife
|
10 | ///////////////////////////////////////
|
11 |
|
12 |
|
13 | int main (void) {
|
14 |
|
15 | // Initialisierungen
|
16 | InitTimer();
|
17 | InitUsart();
|
18 |
|
19 | // Globale Interrupts aktivieren
|
20 | sei();
|
21 |
|
22 | while (1)
|
23 | {
|
24 | Timeraufgaben_Abarbeiten();
|
25 | }
|
26 | return 0;
|
27 | }
|
28 |
|
29 |
|
30 |
|
31 | ///////////////////////////////////////
|
32 | // Timer
|
33 | ///////////////////////////////////////
|
34 |
|
35 | // Zählvariable für den Timer - ISR
|
36 | uint16_t gHeartbeat;
|
37 | uint8_t gfAufgabenLiegenVor = 0;
|
38 |
|
39 |
|
40 | void InitTimer(){
|
41 |
|
42 | // Schrittweite des Zählers in Millisekunden
|
43 | uint16_t Schrittweite_ms = 32;
|
44 |
|
45 | // Aktivierung des CTC Modes des Timer (Clear Timer on Compare Match)
|
46 | // Bewirkt ein Zurücksetzen des Timers nach Erreichen des Schwellwertes im OCR0 Register.
|
47 | TCCR0 |= (0<<WGM00)|(1<<WGM01);
|
48 |
|
49 | // Konfiguration des Timer - Prescalers: CPU - Takt / 1024.
|
50 | // Somit wird der eigentliche Timer mit 15,625 kHz angesteuert.
|
51 | TCCR0 &= ~(1<<CS01);
|
52 | TCCR0 |= (1<<CS00)|(1<<CS02);
|
53 |
|
54 | // Berechnung des Output Compare Registers
|
55 | uint16_t PrescalerFaktor = 1024;
|
56 | OCR0 = (F_CPU * Schrittweite_ms / 1000 / (2 * PrescalerFaktor)) -1;
|
57 |
|
58 | // Compare Interrupt aktivieren
|
59 | TIMSK |= (1<<OCIE0);
|
60 |
|
61 | }
|
62 |
|
63 | // ISR vom TimerCompare Int.
|
64 |
|
65 | ISR(TIMER0_COMP_vect){
|
66 |
|
67 | // Marke, ab der die globale Zählvariable zurückgesetzt wird.
|
68 | // Zeitdauer entspricht somit der Periodendauer der gesamten Timerroutine.
|
69 | // Zu errechnen ist sie mittels MaxMark * Schrittweite_ms.
|
70 | uint8_t MaxMark = 64;
|
71 |
|
72 | uint8_t Mark1 = 32; // Marke für Timerereignis 1
|
73 | uint8_t Mark2 = 16; // Marke für Timerereignis 2
|
74 | //uint8_t Mark3 = 1; // Marke für Timerereignis 3
|
75 |
|
76 |
|
77 | if (gHeartbeat == MaxMark){
|
78 | gHeartbeat = 0;
|
79 | }
|
80 | if (gHeartbeat == Mark1){
|
81 | gfAufgabenLiegenVor = 1;
|
82 | }
|
83 | if (gHeartbeat == Mark2){
|
84 |
|
85 | //!!!!!!
|
86 | // HIER KLAPPT DIE ÜBERTRAGUNG EINWANDFREI
|
87 | //!!!!!!
|
88 | char text[] = "TEST \n";
|
89 | SendeTextUART(text,sizeof(text));
|
90 | }
|
91 |
|
92 | // Die globale Zählvariable zum Realisieren größerer Periodendauern wird hier hochgezählt
|
93 | gHeartbeat++;
|
94 |
|
95 | }
|
96 |
|
97 | void Timeraufgaben_Abarbeiten(){
|
98 |
|
99 | if(gfAufgabenLiegenVor == 1){
|
100 |
|
101 | //!!!!!!
|
102 | // HIER IST DAS EIGENTLICHE PROBLEM:
|
103 | // HIER GEHT ES NICHT SAUBER: DIE TEXTE WERDEN NUR TEILWEISE ÜBERTRAGENG
|
104 | //!!!!!!
|
105 |
|
106 | char text[] = "test \n";
|
107 | SendeTextUART(text,sizeof(text));
|
108 | gfAufgabenLiegenVor = 0;
|
109 | }
|
110 |
|
111 | }
|
112 |
|
113 |
|
114 |
|
115 |
|
116 | ///////////////////////////////////////
|
117 | // UART Teil
|
118 | ///////////////////////////////////////
|
119 |
|
120 | // Globaler Eingangspuffer und Arrayindex
|
121 | char gStrUebertrage[21];
|
122 | uint8_t gI = 0;
|
123 |
|
124 | void InitUsart(void)
|
125 | {
|
126 | /* set the baudrate */
|
127 | UBRRH = (UBBRR_VAL >> 8) & 0x7F; /* ensure URSEL to be zero when wrinting */
|
128 | UBRRL = UBBRR_VAL & 0xFF;
|
129 |
|
130 | // Aktivieren des Senden und Empfangsmodus
|
131 | UCSRB = (1<<RXEN)|(1<<TXEN);
|
132 |
|
133 | // Aktivierung des "Zeichen Empfangen" - Interrupts
|
134 | UCSRB |= (1<<RXCIE);
|
135 |
|
136 | }
|
137 |
|
138 |
|
139 | void SendeTextUART(char StrUebertrage[],uint8_t size){
|
140 |
|
141 | // Aktivierung des "Data Register Empty" - Interrupts
|
142 | UCSRB |= (1<<UDRIE);
|
143 |
|
144 | // Kopieren des lokalen Arrays auf einen globalen Puffer ohne Nutzung von malloc.
|
145 | strncpy(gStrUebertrage,StrUebertrage,size);
|
146 |
|
147 | //Inkrement für das Arrayindex
|
148 | gI = 0;
|
149 |
|
150 | // Nach Übertragung des ersten Zeichen wird der "UDRE" Interrupt ausgelöst
|
151 | UDR = gStrUebertrage[0];
|
152 |
|
153 | }
|
154 |
|
155 | // ISR vom Data Register Empty Interrupt
|
156 | ISR(USART_UDRE_vect){
|
157 |
|
158 | gI++; // Zuerst, da ansonsten der Interrupt "reinfunkt". Daher mit 0 initialisiert.
|
159 | if (gStrUebertrage[gI] != 0){ // solange Nullterminierung noch nicht erreicht
|
160 | UDR = gStrUebertrage[gI];
|
161 | }else{
|
162 | // Deaktivierung des "Data Register Empty" - Interrupts. Die Übertragung ist beendet.
|
163 | UCSRB &= ~(1<<UDRIE);
|
164 | gI = 0;
|
165 | }
|
166 |
|
167 | }
|