@ffredrik:Har trott något sånt också men då blink-programmet fungerade så klockrent och delay(adc-värde) stämde så precis så uteslöt jag det.
Efter blod, svett och tårar (mest tårar) har jag fått igång det nu. Tyvärr har jag inte en aning om varför det blir så här.
Tyckte mig komma fram till det verkligen är något tok med analogRead() i mitt program så sökte runt på nätet efter kod som kunde hjälpa mig att konfigurera ADC:n manuellt och göra en manuell utläsning (eller vad man ska kalla det).
Hittade lite kod och testade och visst, fungerade hur bra som helst på första försöket.
Det jag alltså inte har en aning om är varför analogRead() inte fungerar i mitt program. Är det för att man stället om timers och annat?
Koden nedan fungerar alltså precis som tänkt. Obs. Här läser jag bara ut 8-bitar så skiftar enbart bort 4 LSBs.
EDIT: Hehe, du tänkte precis rätt
Glattnos Ska jämföra programmen lite och se skillnaderna. Ditt program är mycket renare än mitt ihopklistrade klabb.
Kod: Markera allt
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define F_CPU 8000000UL
#define SERVO_PORT PORTB
#define SERVO_CMD_PIN PB0
#define SERVO_CLOSE_PIN PB3
#define SERVO_OPEN_PIN PB4
#define RADIO_OPEN_PIN PB1
#define RADIO_CLOSE_PIN PB2
#define SERVO_FREQ 11 //Högre siffra ger lägre frekvens
volatile uint8_t freqCounter = 0;
volatile uint16_t calCounter = 0;
volatile uint8_t calState = 1;
static uint8_t ServoPositionClose = 150;
volatile uint16_t ServoPositionCloseCal = 0;
static uint8_t ServoPositionOpen = 146;
volatile uint16_t ServoPositionOpenCal = 0;
volatile uint8_t ActiveServoPositionPulse = 148; // 161 = 1500us, 135 = 1900us
static inline void initTimer1(void)
{
TCCR1 |= (1 << CTC1); // clear timer on compare match
TCCR1 |= (1 << CS13); // | (1 << CS11) | (1 << CS10); //clock prescaler
OCR1C = 255; // compare match value
TIMSK |= (1 << OCIE1A); // enable compare match interrupt
}
ISR(TIMER1_COMPA_vect)
{
freqCounter++;
if(calState){
calCounter++;
if(calCounter >= 0xFFFF){
calState = 0;
}
}
if(freqCounter == SERVO_FREQ){
SERVO_PORT |= (1<<SERVO_CMD_PIN);
OCR1C = 255 - ActiveServoPositionPulse;
}
if(freqCounter > SERVO_FREQ){
SERVO_PORT &= ~(1<<SERVO_CMD_PIN);
freqCounter = 0;
OCR1C = 105;
}
}
int main(void)
{
// initializations
pinMode(SERVO_CMD_PIN, OUTPUT);
pinMode(SERVO_CLOSE_PIN, INPUT);
pinMode(SERVO_OPEN_PIN, INPUT);
pinMode(RADIO_OPEN_PIN, INPUT);
pinMode(RADIO_CLOSE_PIN, INPUT);
initTimer1(); // initialize timer registers
sei(); // enable interrupts
initADC();
while(1)
{
if(calState){
ADCSRA |= (1 << ADSC); // start ADC measurement
while (ADCSRA & (1 << ADSC) ); // wait till conversion complete
ServoPositionOpenCal = ADCH >> 4;
}
_delay_ms (1000);
ActiveServoPositionPulse = ServoPositionOpen + ServoPositionOpenCal;
}
return 0;
}
void initADC()
{
ADMUX =
(1 << ADLAR) | // left shift result
(0 << REFS1) | // Sets ref. voltage to VCC, bit 1
(0 << REFS0) | // Sets ref. voltage to VCC, bit 0
(0 << MUX3) | // use ADC2 for input (PB4), MUX bit 3
(0 << MUX2) | // use ADC2 for input (PB4), MUX bit 2
(1 << MUX1) | // use ADC2 for input (PB4), MUX bit 1
(0 << MUX0); // use ADC2 for input (PB4), MUX bit 0
ADCSRA =
(1 << ADEN) | // Enable ADC
(1 << ADPS2) | // set prescaler to 64, bit 2
(1 << ADPS1) | // set prescaler to 64, bit 1
(0 << ADPS0); // set prescaler to 64, bit 0
}