Projekte
BirgerT
nibo2_fork#01
nibo2_pwm_leds.c
Projekte
Forum
Doku
Öffentliche Projekte
Startseite
Beispielprogramme
Projekte von anderen
Welcome
Username
Passwort
Eingeloggt bleiben
Zugangsdaten vergessen?
Registrieren
Projektverwaltung
⇨ Please choose! ⇦
——————————————————
✎ Create new project...
★ Browse existing projects...
——————————————————
⚬ MotorTest#1
⚬ C Tutorial 8#1
⚬ NIBO2 C Project#1
⚙ C Tutorial 15#1
⚬ 2010_11_18_el_test001#1
nibo2_fork#01
BSD_license.h
bt_lib_debugutil.c
bt_lib_debugutil.h
bt_lib_glcd.c
bt_lib_glcd.h
bt_lib_grafix.c
bt_lib_grafix.h
bt_lib_terminal.c
bt_lib_terminal.h
bt_lib_uart.c
bt_lib_uart.h
bt_lib_utils.h
lumpylumpy.h
main.c
nibo2_audio.c
nibo2_audio.h
nibo2_copro.c
nibo2_copro.h
nibo2_copro_cmd.h
nibo2_font.h
nibo2_global.h
nibo2_main_menu.h
nibo2_pwm_leds.c
nibo2_pwm_leds.h
nibo2_register.c
nibo2_register.h
nibo2_sensors.c
nibo2_sensors.h
test_debugutil.h
test_gfx_draw.h
xmas1.h
Project details
Compiler settings
Nachrichten
Sie sind nicht eingeloggt.
Neuigkeiten
★
NiboRoboLib 3.6
2017-01-17: Neue Version 3.6
★
NiboRoboLib 3.4.1
2016-04-16: Neue Version 3.4.1
★
Coding Tutorial
2015-11-22: Jetzt auch für den NIBO burger!
Site-Statistic
7426 private projects
385 public projects
16180353 lines compiled
58212 builds
NIBO
@
nibo2_fork_01/nibo2_pwm_leds.c [read only]
////////////////////////////////////////////////////////////////////////// // // NIBO2 PWM LEDS // // Beschreibung siehe nibo2_pwm_leds.h // ////////////////////////////////////////////////////////////////////////// // // BSD License see "license.h" // #include "BSD_license.h" // // Einbinden aller erforderlichen Makros und Bibliotheksheader // #include "nibo2_pwm_leds.h" // ////////////////////////////////////////////////////////////////////////// // volatile pwm_t pwm = {0,0,0,0,0,0}; // // ====================================================== INIT // void pwmleds_init() { // PORT B = // PB7 /OC1C/OC2=OUT = LED_PWM (PWM Out Timer 1C oder 2) // PB6 /OC1B = OUT = LED_LCD (PWM Ausgang Timer 1B) // PB5 /OC1A = OUT = LED_HEAD (PWM Ausgang Timer 1A) // PB4 /OC0 = OUT = AUDIO (PWM Ausgang Timer 0) // PB3 /MISO = OUT = ISP_MISO (Signal an Copro) // PB2 /MOSI = INP = ISP_MOSI (Signal vom Copro) // PB1 /SCK = OUT = ISP_SCK // PB0 /SS = OUT = LCD_RESET und ISP_SS DDRB = 0b1111011; PORTB |= (1<<ISP_MOSI); // INPUT Pullup ein // PORT C = Grüne LEDs PC0..PC7 alles Ausgänge DDRC = 0xff; // PORT D = Erweiterungsanschluss (EXT / NDS3) // PD7 /T2 = OUT = CO_RESET (Copro Reset) // PD6 /T1 = frei = EXT_A // PD5 /XCK1 = frei = EXT_B // PD4 = PIND4 = SW3 // PD3 /TXD1/INT3 = frei = EXT_C // PD2 /RXD1/INT2 = frei = EXT_D // PD1 /SDA/INT1 = frei = I2C_SDA // PD0 /SCL/INT0 = frei = I2C_SCL DDRD = 0b1000000; // PORT E = Rote LEDs PE0..PE7 alles Ausgänge DDRE = 0xff; ////////////////////////////////////////////////////////////////////////// // // PWM TIMER 1 // ////////////////////////////////////////////////////////////////////////// // // Der Timer 1 wird im Mode 10 betrieben: // - der Timer läuft mit Prescaler F_CPU/8; // - TCNT1 wird zwischen 0 und dem Wert im ICR hochgezählt; // erreicht TCNT1 den Wert im ICR wird wieder runtergezählt; // - ist TCNT1 wieder 0, wird die Overflow ISR aufgerufen: // F_CPU /8 /(2*(ICR) mal pro Sekunde // 16000000Hz /8 /(2*1000) = 1000-mal / Sekunde // oder alle 0,001 Sekunden bzw. jede milli Sekunde. // - ist TCNT1 < OCRx, dann wird der jew. PWM Ausgang OCx eingeschaltet; // // Controlregister (ATmega128 Datenblatt Seite 132 ff.) // // WGM13/WGM12/WGM11/WGM10 = Waveform Generation Mode // 0 0 0 0 = Mode 0: Normalmode // 1 0 0 0 = Mode 8: PWM, Phase + Freq. Correct, // x 1 0 1 0 = Mode 10: PWM, Phase Correct // TOP steht im ICR // // COM1n1/COM1n0 = OC1n Pin Verhalten bei Compare Match // 0 0 = Normales Verhalten als In- oder Output // 0 1 = Beim Compare Match wird getoggelt (nur OC1A) // x 1 0 = if(TCNT < OCR1n) OC1n =1; else OC1n = 0; // 1 1 = if(TCNT < OCR1n) OC1n =0; else OC1n = 1; // // CS12/CS11/CS10 = Clock Select (Taktquelle und Vorteiler) // 0 0 0 = Timer Stopp // 0 0 1 = Zähltakt F_CPU /1 16Mhz // x 0 1 0 = Zähltakt F_CPU /8 2MHz // 0 1 1 = Zähltakt F_CPU /64 250kHz // 1 0 0 = Zähltakt F_CPU /256 62,5kHz // // TimerCounter Register TCNT1 = 0; // Output Compare Register OCR1A = 0; OCR1B = 0; OCR1C = 0; // Input Compare Register == TOP Level für Mode 8 o. 10 ICR1 = 1000; // // TCCR = TimerCounterControlRegister // siehe ATmega128 Datenblatt Seite 132 ff. // // TCCR1A = WGM10, WGM11, COM1A1, COM1A0..COM1C1,COM1C0 // TimerMode "Teil 1" und Verhalten der PWM Pins TCCR1A = (1<<WGM11) | (1<<COM1A1) | (1<<COM1B1) | (1<<COM1C1); // z.Bsp. keine PWM für die DuoLEDs, dann // TCCR1A = (1<<WGM11) | (1<<COM1A1) | (1<<COM1B1); PORTB |= (1<<LED_PWM); // // TCCR1B = CS10..CS12, WGM12, WGM13 // Clockselect und Timermode "Teil 2" TCCR1B = (1<<CS11) | (1<<WGM13); // TIMSK = Timer Interrupt Mask siehe Datenblatt Seite 138, 139 // Enable Overflow Interrupt TIMSK |= (1<<TOIE1); } // nibo2_init_pwm_leds ////////////////////////////////////////////////////////////////////////// /* TIMER TASK TABELLE */ ////////////////////////////////////////////////////////////////////////// // für 10 Funktionen, die nacheinander alle 10ms aufgerufen werden. #define PWM_TASKS_MAX 10 fn_Pointer_t pwm_tasktable[PWM_TASKS_MAX]; static uint8_t pwm_task_index = 0; // ISR Index counter static uint8_t pwm_task_count = 0; // Anzahl vorhandener Tasks /* ================================= TIMER TASK in Tabelle eintragen -> Adresse der aufzurufenden Funktion <- Index des Eintrags in Task Tabelle oder 0xff, wenn Eintrag nicht möglich. */ uint8_t pwm_add_fn(fn_Pointer_t task){ if (pwm_task_count < PWM_TASKS_MAX) { uint8_t index = 0; do { fn_Pointer_t temp_task = pwm_tasktable[index]; if (temp_task == 0) { uint8_t temp_sreg = SREG; cli(); pwm_tasktable[index] = task; SREG = temp_sreg; pwm_task_count++; return index; } } while (index++ < PWM_TASKS_MAX); } return 0xff; // Fehler Tabelle voll } /* ================================== TIMER TASK aus Tabelle austragen -> Index des Eintrags in der Task Tabelle */ void pwm_del_fn(uint8_t tasknr){ if (pwm_task_count > 0) { if (tasknr < PWM_TASKS_MAX) { uint8_t temp_sreg = SREG; cli(); pwm_tasktable[tasknr] = 0; SREG = temp_sreg; pwm_task_count--; } } } // ------------------------------ TIMER TASK in ISR aufrufen // // Inline Funktion wird in die Timer1 OVF ISR eingefügt, steht nur hier // damit die Funktionen für den TIMER TASK im CODE beieinander stehen. // static inline void task_call(){ if (++pwm_task_index > (PWM_TASKS_MAX-1)) { pwm_task_index = 0; } fn_Pointer_t time_task = pwm_tasktable[pwm_task_index]; if (time_task != 0) { time_task(); } } ////////////////////////////////////////////////////////////////////////// /* PWM WERTE SETZEN */ ////////////////////////////////////////////////////////////////////////// /* Intensität der LEDs setzen oder abfragen -> uint8_t val = 0..100% oder > 100 für Abfrage <- uint8_t aktueller PWM Wert 0..100% */ // HEADLIGHT uint8_t pwm_head(uint8_t val) { if (val <= 100) { pwm.pwmA = val; OCR1A = val *10; } return pwm.pwmA; } // LCD BACKLIGHT uint8_t pwm_lcd(uint8_t val) { if (val <= 100){ pwm.pwmB = val; #if 0==1 if(val == 0) OCR1B = 0; else OCR1B = val *10 -1; #else OCR1B = val *10; #endif } return pwm.pwmB; } // DUO LEDS uint8_t pwm_leds(uint8_t val) { if (val <= 100){ pwm.pwmC = val; OCR1C = val *10; } return pwm.pwmC; } ////////////////////////////////////////////////////////////////////////// /* AKTUELLE ZEITWERTE LESEN */ ////////////////////////////////////////////////////////////////////////// //void delay_ms(uint8_t ms) __attribute__((always_inline)); void delay_ms(uint8_t ms) { while(ms--) _delay_ms(1); // aus util/delay.h } // Lese Millisekunden uint16_t pwm_get_ms() { cli(); uint16_t tmp = pwm.ms; sei(); return tmp; } // Lese Sekunden uint16_t pwm_get_sec() { cli(); uint16_t tmp = pwm.ms; sei(); return tmp; } ////////////////////////////////////////////////////////////////////////// /* TIMER 1 OVERFLOW INTERRUPT */ ////////////////////////////////////////////////////////////////////////// ISR (TIMER1_OVF_vect) { // Struct in lokale Variablen umschaufeln uint16_t time_ms = pwm.ms; uint16_t time_sec = pwm.sec; uint8_t time_cyc = pwm.cycle; time_cyc++; time_ms++; // 0..1000ms if(time_ms >= 1000){ time_ms -=1000; time_sec++; if (time_sec >= 60) { time_sec -= 60; pwm.min++; } } pwm.ms = time_ms; pwm.sec = time_sec; pwm.cycle = time_cyc; task_call(); // inline Funktion s.o. }
Compiler results:
Werbung
Online
leonelb389687792836
ruebenmendes25697
warrenhinder6456
wilfredocastillo