Oha, das kenn ich wenn man bis 4 oder 5 Uhr bastelt und sucht...
Also ich hatte auch Probleme mit einem PWM für ne Displaybeleuchtung neulich. Das war so, dass es in einem bestimmten Modus nicht ging, in anderem Schon. folgendes allerdings geht super:
(achtung, es ist C und ein AT90CAN12 Aber mit was anderem kann ich dir nicht helfen. Ich denke in der Sache ist es egal
Aufruf:
Code:
// Init PWM interface
if(initPWM(fast,non_inv,div8));
else return false;
Funktion:
Code:
/*****************************************************************************
*
* Temperature Unit Firmware
* - PWM functions for display-background-LED
*
* Compiler : avr-gcc 4.3.0 / avr-libc 1.6.2 / AVR Studio 4.14
* size : 2,70KB
* by : Thomas Fuchs, Wolfsburg, Germany
* thomas.fuchs@cc-robotics.de
*
* License : Copyright (c) 2009 Thomas Fuchs
*
* Tested with AT90CAN128
****************************************************************************/
#include <stdbool.h>
#include "utils.h"
#include "pwm.h"
uint8_t PWM_Timer_temp = 0; // save the operation during hard on/off
// Init PWM
/* defines
#define normal 0
#define phase_correct 1
#define fast 2
#define non_inv 0
#define inv 1
#define off 2
#define no_div 0
#define div8 1
#define div64 2
#define div256 3
#define div1024 4
*/
bool initPWM(uint8_t mode, uint8_t operation, uint8_t clk_div)
{
PWM_Value = 0;
PWM_Timer = 0;
PWM_DDR |= _BV(PWM_Pin);
switch (mode)
{
case 0:
break;
case 1:
PWM_Timer |= (1<<WGM00);
break;
case 2:
PWM_Timer |= (1<<WGM00);
PWM_Timer |= (1<<WGM01);
break;
default:
return false;
}
switch (operation)
{
case 0:
PWM_Timer |= (1<<COM0A1);
break;
case 1:
PWM_Timer |= (1<<COM0A0);
PWM_Timer |= (1<<COM0A1);
break;
case 2:
break;
default:
return false;
}
switch (clk_div)
{
case 0:
PWM_Timer |= (1<<CS00);
break;
case 1:
PWM_Timer |= (1<<CS01);
break;
case 2:
PWM_Timer |= (1<<CS00);
PWM_Timer |= (1<<CS01);
break;
case 3:
PWM_Timer |= (1<<CS02);
break;
case 4:
PWM_Timer |= (1<<CS00);
PWM_Timer |= (1<<CS02);
break;
default:
return false;
}
return true;
}
// PWM dimm
/* defines
#define soft_off 0
#define soft_on 1
#define hard_off 2
#define hard_on 3
*/
void dimmPWM(uint8_t function)
{
uint8_t i;
switch (function)
{
case 0:
for (i=255; i>0; i--) // 255 must be configurated value from EEPROM
{
PWM_Value = i;
delay_ms(8); // delay 10 ms
}
break;
case 1:
for (i=0; i<255; i++) // 255 must be configurated value from EEPROM
{
PWM_Value = i;
delay_ms(8); // delay 10 ms
}
break;
case 2:
PWM_Timer_temp = (PWM_Timer&0x30);
PWM_Timer &= 0xCF;
break;
case 3:
PWM_Timer |= PWM_Timer_temp;
break;
default:
return;
}
}
header zu pwm.c:
Code:
/*****************************************************************************
*
* Temperature Unit Firmware
* - header file of pwm.c
*
* Compiler : avr-gcc 4.3.0 / avr-libc 1.6.2 / AVR Studio 4.14
* size : 953Bytes
* by : Thomas Fuchs, Wolfsburg, Germany
* thomas.fuchs@cc-robotics.de
*
* License : Copyright (c) 2009 Thomas Fuchs
*
* Tested with AT90CAN128
****************************************************************************/
#define PWM_DDR DDRB
#define PWM_Pin 7
#define PWM_Timer TCCR0A
#define PWM_Value OCR0A
// Init PWM
#define normal 0
#define phase_correct 1
#define fast 2
#define non_inv 0
#define inv 1
#define off 2
#define no_div 0
#define div8 1
#define div64 2
#define div256 3
#define div1024 4
// PWM dimm
#define soft_off 0
#define soft_on 1
#define hard_off 2
#define hard_on 3
extern void delay_ms(uint16_t period); //delay routine (milliseconds)
Ich hoffe das hilft dir!
Lesezeichen