PWM_ADC_UART_11.c


1
#include <avr/io.h>
2
#include <stdlib.h>
3
4
5
/* USART-Init beim ATmega16 */
6
#ifndef F_CPU
7
#define F_CPU 16000000           /* Oszillator-Frequenz in Hz */
8
#endif
9
 
10
// Hilfsmakro zur UBRR-Berechnung ("Formel" laut Datenblatt)
11
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)
12
#define UART_BAUD_RATE 9600
13
14
15
/*** Funktionen ***/
16
17
void uart_puts (char *s)
18
{
19
    while (*s)
20
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
21
        uart_putc(*s);
22
        s++;
23
    }
24
}
25
26
void uart_putc(unsigned char c)
27
{
28
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
29
    {
30
    }                             
31
 
32
    UDR = c;                      /* sende Zeichen */
33
    return 0;
34
}
35
36
void Init_USART()
37
38
{
39
  UCSRB |= (1<<TXEN);                // UART TX einschalten
40
    UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1 
41
  UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) >> 8 );
42
    UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );
43
44
}
45
46
47
void Init_ADC()
48
  
49
  {
50
   ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen
51
  // Activate ADC with Prescaler 16 --> 16Mhz/128 = 125kHz
52
    ADCSRA = _BV(ADEN) | _BV(ADPS2)|(1<<ADPS1)|(1<<ADPS0); 
53
   // Select pin ADC0 using MUX
54
     ADMUX = 0;
55
  }
56
57
void ADC_Messung_starten()
58
  
59
  {
60
    //Start conversion
61
    ADCSRA |= _BV(ADSC);
62
    // wait until converstion completed
63
    while (ADCSRA & _BV(ADSC) ) {}
64
  } 
65
66
void time (a)
67
68
{
69
  char s[7];
70
  int ADC_Wert;
71
  // Timer 1 einstellen
72
    //  
73
    // Modus 14:
74
    //    Fast PWM, Top von ICR1
75
    //
76
    //     WGM13    WGM12   WGM11    WGM10
77
    //      1        1       1        0
78
    //
79
   //    Timer Vorteiler: 1
80
    //     CS12     CS11    CS10
81
    //       0        0       1
82
    //
83
    //  Steuerung des Ausgangsport: Set at BOTTOM, Clear at match
84
    //     COM1A1   COM1A0
85
    //       1        0
86
 
87
    TCCR1A = (1<<COM1A1) | (1<<WGM11);
88
    TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS10);
89
 
90
    //
91
    //  den Endwert (TOP) für den Zähler setzen
92
    //  der Zähler zählt bis zu diesem Wert
93
 
94
    ICR1 = 0x6FFF;
95
 
96
  //
97
  // der Compare Wert
98
  // Wenn der Zähler diesen Wert erreicht, wird mit
99
  // obiger Konfiguration der OC1A Ausgang abgeschaltet
100
  // Sobald der Zähler wieder bei 0 startet, wird der
101
  // Ausgang wieder auf 1 gesetzt
102
  //
103
  // Durch Verändern dieses Wertes, werden die unterschiedlichen
104
  // PWM Werte eingestellt.
105
  //                             Pulsweite ändern 0x0F = 1,6mV bei f = 556 Hz
106
                //           0xBB8 = 0,555V      
107
                //          0x1770 = 1,111V
108
              //           0x36B0 = 2,5V
109
              //          0x5208 = 3,68V
110
              //          0x6D60 = 
111
                //          0x6FFF = 4,95V
112
  //_delay_us(500);
113
  OCR1A = a; // Zählerstand übernehmen
114
115
//  OCR1A = 0x6FFF;  //Fester Zählerstand (Spannung)
116
117
118
   ADC_Messung_starten();
119
120
   
121
    // get converted value
122
    ADC_Wert = ADCW; 
123
  
124
  
125
  PORTB = ~ADC_Wert>>2; // Ausgabe an PORT X mit LED's
126
    
127
   itoa( ADC_Wert, s, 10 ); // 10 fuer radix -> Dezimalsystem
128
   
129
   uart_puts( s );
130
   uart_putc('\r');
131
   uart_putc('\n');    
132
}
133
134
135
136
137
int main()
138
{
139
 
140
int16_t i = -12345;
141
142
//  int ADC_Wert;      // Werteinhalt für die Ausgabe
143
144
  DDRB = 0xFF;      // port B output
145
  // OC1A auf Ausgang
146
  
147
  DDRD = (1 << PD5 ); //ATMega16 Augabe PIN D 05
148
  //
149
   
150
 Init_USART();
151
152
Init_ADC();
153
154
   for(;;) // Dauerschleife
155
   {
156
      
157
    for (int a=0; a <=28671; a+=200) //Zähler von 0 bis Maximum
158
        {
159
         time (a);
160
      
161
       } 
162
        
163
    for (int a=28671; a >=0; a-=200) //Zähler von Maximum bis 0
164
        {
165
         time (a);
166
                 
167
      }
168
       
169
  }
170
171
  
172
}