0

私は現在、ATMEGA1284P を使用したソーラー トラッカー プロジェクトに取り組んでおり、PWM を構成した後、トラッカーの機械的な制限を発見して、サーボの境界を定義できるようにします。

このために、簡単なコードを用意しました。PWM が正常に動作していることはわかっていますが (スコープでもチェックされています)、このコードを動作させることができません。アイデアは、2 つのプッシュボタン (gnd に接続) でサーボを動かし、後で UART を構成して、現在のサーボ位置をコンピューターに送信できるようにすることです。if ループの外で pwm_set1 関数を呼び出してみましたが、まったく応答しません。

スイッチも正しく配線されており、uCピンの電圧計でもチェックしましたが、両方とも正常に動作しています。つまり、押されたときにGND、以下のコードでわかるように構成されたプルアップ抵抗です。

どんな提案でも大歓迎です。ありがとうございました!乾杯、ルイ・モレノ。

#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);
            }
    }    
}
4

1 に答える 1

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
   }

私が望むのは、割り込みが変数を更新し、その更新された変数で main の下の pwm_set1 関数が欲しいので、まだ少し生です。また、ある種のデバウンス メカニズムを実装する必要があります。

乾杯、ルイ・モレノ。

于 2014-12-14T20:35:26.513 に答える