2014-12-14 4 views
0

Теперь я работаю над проектом солнечного трекера с ATMEGA1284P, и после настройки PWM настало время обнаружить механические ограничения трекера, чтобы я мог определить границы для сервоприводов.Переместить серво с кнопками | C | Atmel Studio

Для этого я подготовил простой код. Я знаю, что PWM работает правильно (также проверяется с помощью области видимости), но я просто не могу заставить этот код работать. Идея состоит в том, чтобы переместить серво с двумя кнопками (подключенными к gnd), а затем настроить UART, чтобы я мог отправить текущее положение сервопривода на свой компьютер. Я попытался также вызвать функцию pwm_set1 вне циклов if, но он вообще не отвечает.

Переключатели также правильно подключены, и я также проверил с помощью вольтметра на выводах uC, и они оба работают нормально, т. Е. GND при нажатии, подтягивающие резисторы, настроенные так, как вы можете видеть в приведенном ниже коде.

Любые предложения приветствуются. Спасибо! Cheers, Руи Морено.

#ifndef F_CPU 
#define F_CPU 1000000L // 1 Mhz 
#endif 
#include <avr/io.h> 
#include <avr/portpins.h> 
#include <util/delay.h> 

void pwm_init(){ 
    // Configurar o Waveform Generation Mode. 
     // Para modo de fast PWM, WGM11, 12 e 13 têm que estar a 1 
    TCCR1A |= 1<<WGM11 | 1<<COM1A1 | 0<<COM1A0;  // COM1A1 para configurar PWM em modo non- inverted (devido ao BJT) | anterior:COM1A1 e COM1A0 para configurar PWM em inverted mode 
    TCCR1B |= 1<<WGM13 | 1<<WGM12 | 1<<CS10;  // CS10 serve para selecionar o prescaler  (nenhum, neste caso) 

    //Definir o período para PWM 
    ICR1 = 19999; 
    OCR1A = ICR1 - 550; // posição inicial do servo 
}; 

void pwm_set1(uint16_t x){ 
    OCR1A = ICR1-x; 
} 

int main(void) 
{ 
    DDRD |= 0xFF; //Configurar Porta D como saída em todos os pinos 

    pwm_init(); 
    uint16_t posx = 550; 

    //configurar pinos C1 e C2 como entrada para os switches left e right (just in case) 
    DDRC &= ~(1 << PC2); 
    DDRC &= ~(1 << PC3); 
    //pull-up resistors nos pinos C1 e C2 
    PORTC |= (1 << PC2); 
    PORTC |= (1 << PC3); 


    while(1) 
    { 
      if ((PINC & (1<<2)) == 0){ 
       posx+=1; 
       pwm_set1(posx); 
      } 

      if ((PINC & (1<<3)) == 0){ 
       posx-=1; 
       pwm_set1(posx); 
      } 
    }  
} 

ответ

0

мне удалось получить выключатели работают с использованием прерываний:

ISR(INT0_vect) {   
    if (bit_is_set(PIND, PIND2)) { //PD2 
     OCR1A+=20; 
    } 
    else{} 
} 

ISR(INT1_vect) {   
    if (bit_is_set(PIND, PIND3)) { //PD2 
     OCR1A-=20; 
    } 
    else{} 
    } 

void initInterrupts(void) { 
    EIMSK |= ((1 << INT0)|(1 << INT1));  //enable INT0 and INT1 
    //EICRA |= (1 << ISC01);  //trigger on falling edge 
    sei();       // set (global) interrupt enable bit 
    } 

Еще немного сырой, как то, что я хочу для прерывания обновить переменную и затем pwm_set1 функцию в основной с этой обновленной переменной. Также мне придется реализовать какой-то механизм debouncing.

Cheers, Rui Moreno.