-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathin_out.cpp
240 lines (206 loc) · 6.32 KB
/
in_out.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
// Technische Richtlinie FA205
// Bibliothek: in_out.c
// Controller: Atmel ATmega8/ATmega328p
// Version: 2.0
// erstellt am: 30.9.2015
// letzte Änderung: 9.4.2018
// Autor: Rahm
#include "in_out.h"
// Definition der Funktionen
//***************************************************************
// ab hier Funktionen für Port-Ein-/Ausgabe
//***************************************************************
void bit_init(volatile uint8_t *byte_adr, uint8_t bit_nr, uint8_t direction)
{
if (direction == OUT)
{
if (byte_adr == &PORTD) DDRD |= (0x01<<bit_nr);
else if (byte_adr == &PORTB) DDRB |= (0x01<<bit_nr);
else if (byte_adr == &PORTC) DDRC |= (0x01<<bit_nr);
}
else
{
if (byte_adr == &PORTD) DDRD &= ~(0x01<<bit_nr);
else if (byte_adr == &PORTB) DDRB &= ~(0x01<<bit_nr);
else if (byte_adr == &PORTC) DDRC &= ~(0x01<<bit_nr);
}
#ifndef NOPULLUPS
if (direction == IN) *byte_adr |= (0x01<<bit_nr); // internen Pullup aktivieren
#endif
}
void byte_init(volatile uint8_t *byte_adr, uint8_t direction)
{
uint8_t reg_config;
if (direction == OUT)
{
reg_config = 0xff; // als Ausgang
}
else
{
reg_config = 0x00; // als Eingang
}
if (byte_adr == &PORTD) DDRD = reg_config;
else if (byte_adr == &PORTB) DDRB = reg_config;
else if (byte_adr == &PORTC) DDRC = reg_config;
#ifndef NOPULLUPS
if (direction == IN) *byte_adr = 0xff; // interne Pullups aktivieren
#endif
}
uint8_t bit_read(volatile uint8_t *byte_adr, uint8_t bit_nr)
{
if (byte_adr == &PORTD) return ((PIND>>bit_nr) & 0x01);
else if (byte_adr == &PORTB) return ((PINB>>bit_nr) & 0x01);
else if (byte_adr == &PORTC) return ((PINC>>bit_nr) & 0x01);
else return 0;
}
void bit_write(volatile uint8_t *byte_adr, uint8_t bit_nr, uint8_t val)
{
val &= 0x01;
if (val == 1)
*byte_adr |= (0x01<<bit_nr);
else
*byte_adr &= ~(0x01<<bit_nr);
}
uint8_t byte_read(volatile uint8_t *byte_adr)
{
if (byte_adr == &PORTD) return PIND;
else if (byte_adr == &PORTB) return PINB;
else if (byte_adr == &PORTC) return PINC;
else return 0;
}
//PORT als Ausgabe
void byte_write(volatile uint8_t *byte_adr, uint8_t byte_wert)
{
*byte_adr = byte_wert;
}
void bit_toggle(volatile uint8_t *byte_adr, uint8_t bit_nr, volatile uint8_t *_bit_status_)
{
if( !bit_read(byte_adr,bit_nr) )
{
delay_ms(20); // Entprellzeit
while( !bit_read(byte_adr,bit_nr));
delay_ms(20);
*_bit_status_ = ~*_bit_status_;
*_bit_status_ &= 0x01; // Bit 0 ausmaskieren!
}
}
//***************************************************************
// ab hier PWM-Funktionen
//***************************************************************
#ifdef _ATMEGA328_
#define _TIMER_CONT_A_ TCCR2A
#define _TIMER_CONT_B_ TCCR2B
#define _PWM_PRESCALER_BIT_ CS22 // Prescaler 64 => fpwm ca. 1kHz @ 16MHz
#define _TIMER_COMPARE_REG_2 OCR2B
#define _OUT_MODE_BIT_2 COM2B1
#define _TIMER_COMPARE_REG_ OCR2A
#define _OUT_MODE_BIT_ COM2A1
#endif
#ifdef _ATMEGA8_
#define _TIMER_CONT_A_ TCCR2
#define _TIMER_CONT_B_ TCCR2
#define _PWM_PRESCALER_BIT_ CS21 // Prescaler 8 => fpwm ca. 1,6kHz @ 3,6864MHz
#define _TIMER_COMPARE_REG_ OCR2
#define _OUT_MODE_BIT_ COM21
#endif
void pwm_init(void)
{
bit_init(&PORTB,3,OUT);
_TIMER_CONT_B_ |= (1<<_PWM_PRESCALER_BIT_); // Prescaler initialisieren
_TIMER_CONT_A_ |= (1<<WGM21) | (1<<WGM20); // FastPWM Mode
_TIMER_COMPARE_REG_ = 127;
}
void pwm_start()
{
_TIMER_CONT_A_ |= (1<<_OUT_MODE_BIT_);
}
void pwm_stop()
{
_TIMER_CONT_A_ &= ~(1<<_OUT_MODE_BIT_);
}
void pwm_duty_cycle ( uint8_t value )
{
_TIMER_COMPARE_REG_ = value;//255-value;
}
void pwm2_init(void)
{
bit_init(&PORTD,3,OUT);
_TIMER_CONT_B_ |= (1<<_PWM_PRESCALER_BIT_); // Prescaler initialisieren
_TIMER_CONT_A_ |= (1<<WGM21) | (1<<WGM20); // FastPWM Mode
_TIMER_COMPARE_REG_2 = 127;
}
void pwm2_start()
{
_TIMER_CONT_A_ |= (1<<_OUT_MODE_BIT_2);
}
void pwm2_stop()
{
_TIMER_CONT_A_ &= ~(1<<_OUT_MODE_BIT_2);
}
void pwm2_duty_cycle ( uint8_t value )
{
_TIMER_COMPARE_REG_2 = value;//255-value;
}
//////// PWM3 ///////
void pwm3_init(void)
{
bit_init(&PORTB,1,OUT);
TCCR1A |= (1<<WGM10) | (1<<WGM11); // FastPWM Mode (8-Bit)
TCCR1B |= (1<<WGM12) | (1<<CS11); // Prescaler initialisieren
OCR1A = 127 * 4;
}
void pwm3_start()
{
TCCR1A |= (1<<COM1A1); // FastPWM Mode (8-Bit)
//_TIMER_CONT_A_ |= (1<<_OUT_MODE_BIT_2);
}
void pwm3_stop()
{
TCCR1A &= ~(1<<COM1A1);
//_TIMER_CONT_A_ &= ~(1<<_OUT_MODE_BIT_2);
}
void pwm3_duty_cycle ( uint8_t value )
{
OCR1A = value*4;
//_TIMER_COMPARE_REG_2 = value;//255-value;
}
//***************************************************************
// ab hier ADC-Funktionen
//***************************************************************
//***** Konstanten
#define AD_START 6 // Bit ADCSRA.6 startet die Wandlung
//uint16_t adc_in(uint8_t ch); // Prototyp! Lokale Funktion mit Kanalwahl
// Initialisierung des ADU.
void adc_init(void)
{
ADMUX = 0x60; // interne Referenz / Rechtsbündig
ADCSRA = 0x85; // Enable, Stop, Prescaler=32
}
// Einlesen des ADC-Kanals 1
uint8_t adc_in1( void )
{
return (adc_in(CH1));
}
// Einlesen des ADC-Kanals 2
uint8_t adc_in2( void )
{
return (adc_in(CH2));
}
// Funktion mit Kanal-Parameter
uint8_t adc_in(uint8_t ch)
{
ADMUX &=0xf0;
ADMUX |= ch; // Kanal Nr.
ADCSRA |= (1<<AD_START); // Wandlung starten
while( ADCSRA & (1<<AD_START) ); // Warten bis Wandlung beendet
return ADCH;
}
// Gibt den 10 Bit-Wert des ADC zurück. Funktion mit Kanal-Parameter
uint16_t adc_in10(uint8_t ch)
{
ADMUX &=0xf0;
ADMUX |= ch; // Kanal Nr.
ADCSRA |= (1<<AD_START); // Wandlung starten
while( ADCSRA & (1<<AD_START) ); // Warten bis Wandlung beendet
return (ADC>>6); //Bit nach links schieben (alternativ Flag ADLS = 1 setzen)
}