doch, hier ist ein beispiel:
Code:
#include <avr/io.h>
/* Diese ganze "Bibliothek" bezieht sich auf ATmega32. Es dürfte aber nicht schwer sein
sie für andere Atmels umzuschreiben */
/* Erstmal ein paar sehr nützliche #defines die ich zum ersten mal bei www.mc-project sah */
#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT)) // Setzt bit im gewünschten Register
#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT)) // Löscht bit in ADDRESS
#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT)) // Prüfft ob bit gesetzt ist
/*PWM-Teil
Hier kommen meine #defines und Funktionen und zur PWM Ausgabe mit Timer2(16Bit Timer)
Beim ATmega32 geschiet die PWM Ausgabe an PD4(OC1B) und PD5(OC1A). Mit den #defines stellt
man die ganze Voreinstellungen ein. Mit den Funtkionen pwmXbit() kann man dann das PWM
Ausgangssignal steuern. Mit pwm_index setzt man fest an welchen Ausgang. limit_range
unterteil den PWM Bereich in 0.0-100.0 Das ganze sieht dann so aus
z.B pwm9bit(35.0,1) damit ist PWM Ausgabe an Ausgang 2 wobei im OutputCompareRegister
35.0*327.68 = (int) 11468.8 steht
*/
#define PWMchannel_init DDRD= _BV(PD4) | _BV(PD5); // PWM Ports als ausgang deklarieren
#define PWM8bit_init TCCR1A |=_BV(WGM10) // Gewünschte PWM 8,9 oder eben 10Bit
#define PWM9bit_init TCCR1A |=_BV(WGM11)
#define PWM10bit_init TCCR1A = _BV(WGM10) | _BV(WGM11)
#define PWMdisable TCCR1A = ~_BV(WGM10) & ~_BV(WGM11) // Timer2 wieder normaler Timer
#define PWMnoCO1A TCCR1A = ~_BV(COM1A0) & ~_BV(COM1A1) // Kein PWM an Ausgang1
#define PWMnoCO1B TCCR1A = ~_BV(COM1B0) & ~_BV(COM1B1)
#define PWM1upcounting TCCR1A = _BV(COM1A0) | _BV(COM1A1) // invertierende PWM
#define PWM2upcounting TCCR1A = _BV(COM1B0) | _BV(COM1B1)
#define PWM1downcounting TCCR1A |= _BV(COM1A1) // nicht invertierend
#define PWM2downcounting TCCR1A |= _BV(COM1B1)
#define Timer2_prescaler_1 TCCR1B |= _BV(CS10) // verschiedene Prescaler
#define Timer2_prescaler_8 TCCR1B |= _BV(CS11)
#define Timer2_prescaler_64 TCCR1B = _BV(CS11) | _BV(CS10)
#define Timer2_prescaler_256 TCCR1B |= _BV(CS12)
#define Timer2_prescaler_1024 TCCR1B = _BV(CS12) | _BV(CS10)
#define Timer2_stop TCCR1B = ~_BV(CS12) & ~_BV(CS11) & ~_BV(CS10) // stopt Timer2
float limit_range(float val,float low,float high)
{
if(val<low) return low;
else if(val>high) return high;
else return val;
}
void pwm8bit(float vel, unsigned char pwm_index) // pwb_index 0 für Ausgang 1, 1 für Ausgang 2
{ // für 8Bit Pwm
vel = limit_range(vel,0.0,100.0);
if(pwm_index==0)
OCR1A= (int) (163.84*vel);
if(pwm_index==1)
OCR1B= (int) (163.84*vel);
}
void pwm9bit(float vel, unsigned char pwm_index) // pwb_index 0 für Ausgang 1, 1 für Ausgang 2
{
vel = limit_range(vel,0.0,100.0);
if(pwm_index==0)
OCR1A= (int) (327.68*vel);
if(pwm_index==1)
OCR1B= (int) (327.68*vel);
}
void pwm10bit(float vel, unsigned char pwm_index) // pwb_index 0 für Ausgang 1, 1 für Ausgang 2
{
vel = limit_range(vel,0.0,100.0);
if(pwm_index==0)
OCR1A= (int) (655.36*vel);
if(pwm_index==1)
OCR1B= (int) (655.36*vel);
}
/* Analog/Digiatl konverting */
#define ADCchannel_init DDRA=0x00 // ADC Port als Eingang deklarieren
#define ADCinit ADCSRA|=_BV(ADEN) // Teilt dem Board mit das der jeweilige Port für ADC verwendet wird
#define ADCdisable ADCSRA &=~_BV(ADEN) // machs das vorherige wieder rückgänig
#define ADCstart ADCSRA|=_BV(ADSC) // startet eine konvertierung auf dem gewünschten Kannal/Pin
#define ADCfree ADCSRA|=_BV(ADATE) // schaltet den freilaufenden Modus ein
#define ADCvintern ADMUX|=_BV(REFS0) // interne Spannungsversorgung
#define ADCinterrupt_on ADCSRA|=_BV(ADIE) // ADC interrupt wird freigeschalten
#define ADCprescaler_2 ADCSRA |=_BV(ADPS0) // gewünschter Teilungsfaktor/Prescaler
#define ADCprescaler_4 ADCSRA|=_BV(ADPS1)
#define ADCprescaler_8 ADCSRA=_BV(ADPS1) | _BV(ADPS0)
#define ADCprescaler_16 ADCSRA|=_BV(ADPS2)
#define ADCprescaler_32 ADCSRA=_BV(ADPS2) | _BV(ADPS0)
#define ADCprescaler_64 ADCSRA=_BV(ADPS2) | _BV(ADPS1)
#define ADCprescaler_128 ADCSRA=_BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0)
#define ADCprescaler_reset ADCSRA = ~_BV(ADPS2) & ~_BV(ADPS1) & ~_BV(ADPS0)
#define ADCchannel_1 //gewünschter Kannal z.B bei ATmega32 PINA0 - PINA7
#define ADCchannel_2 ADMUX|=_BV(MUX0) // bei nicht freilaufen muss ADCchannel_x vor
#define ADCchannel_3 ADMUX|=_BV(MUX1) // ADCstart kommen dann kann man mit getadc() der
#define ADCchannel_4 ADMUX= _BV(MUX1) | _BV(MUX0) // Adcwert des gewählten Kannals auslesen
#define ADCchannel_5 ADMUX|=_BV(MUX2)
#define ADCchannel_6 ADMUX= _BV(MUX2) | _BV(MUX0)
#define ADCchannel_7 ADMUX= _BV(MUX2) | _BV(MUX1)
#define ADCchannel_8 ADMUX= _BV(MUX2) | _BV(MUX1) | _BV(MUX0)
#define ADCchannel_reset ADMUX= ~_BV(MUX2) & ~_BV(MUX1) & ~_BV(MUX0)
inline unsigned int getadc(void)
{
while (ADCSRA & _BV(ADSC)) {}
return ADC;
}
und weiter:
Code:
#include <adc_pwm.h> (so heisst oben die datei für diese main)
// PWM Beispiel
int main(void)
{
PWMchannel_init;
PWM9bit_init;
PWM1upcounting;
PWM2upcounting;
Timer2_prescaler_256;
pwm9bit(35.0,0);
pwm9bit(45.0,1);
Timer2_stop;
Timer2_prescaler_1024;
pwm9bit(35.0,0);
pwm9bit(45.0,1);
}
habe ich hier vom forum.
weil es so schön war, noch für adc (bibliothek von ganz oben für diese main):
Code:
#include <adc_pwm.h>
// AD beispiel
int main(void)
{
unsigned int x;
ADCinit;
ADCchannel_init;
ADCvintern;
ADCprescaler_16;
ADCchannel_3;
x=getadc();
ADCprescaler_reset;
ADCchannel_reset;
ADCprescaler_128;
ADCchannel_5;
x=getadc();
}
mdf pebisoft
Lesezeichen