在纯C中设置atmega328上的中断

在纯C中设置atmega328上的中断,c,avr,atmega,C,Avr,Atmega,我目前正在一个Arduino Uno板上工作,我正试图用纯C编写它,而不使用Arduino的库 我正在工作的项目应该是这样的: 将LEDPB0设置为BP7打开和关闭 在连接到按钮的PD2上设置中断 按下按钮时,LED应停止(暂停) 再次按下按钮时,LED应再次打开 从最后一个关闭的LED开始 更准确地说: 调用函数play() LED开始一个接一个地闪烁 如果我按下按钮,play()功能应该停止 这意味着,如果连接到PB3的LED最后一次点亮,当我再次按下按钮时,play()功能应该从P

我目前正在一个Arduino Uno板上工作,我正试图用纯
C
编写它,而不使用Arduino的库

我正在工作的项目应该是这样的:

  • 将LED
    PB0
    设置为
    BP7
    打开
    关闭

  • 在连接到按钮的PD2上设置中断

  • 按下按钮时,LED应停止(暂停)

  • 再次按下按钮时,LED应再次打开

    从最后一个关闭的LED开始

更准确地说:

  • 调用函数
    play()
  • LED开始一个接一个地闪烁
  • 如果我按下按钮,
    play()
    功能应该停止
这意味着,如果连接到
PB3
的LED最后一次点亮,当我再次按下按钮时,
play()
功能应该从
PB4
继续

以下是我到目前为止的情况:

#ifndef F_CPU
#define F_CPU 16000000UL
#endif

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

void play( void );

volatile uint8_t buttonWasPressed = 0;
const unsigned char LEDS[] = { PB0, PB1, PB2, PB3, PB4, PB5 };

int main(void)
{
    DDRB = 0xFF;  /// Set PORTB as OUTPUT

    DDRD  |=  ( 1 << PD7 );     /// Set PIN7 IN DDRD as INPUT
    PORTD &= ~( 1 << PD7 );     /// Set PIN7 on PORTD to LOW
    DDRD  &= ~( 1 << PD2 );     // Clear the PD2 pin and set PD2 (PCINT0 pin) now as input
    PORTD |= (1 << PD2);        // Set PIN PD2 as INPUT with pull-up enabled

    EICRA |= (1 << ISC00);      // set INT0 to trigger on ANY logic change
    EIMSK |= (1 << INT0);       // Turns on INT0
    sei();                      // turn on interrupts

    while(1)
    {
        play();
    }
}

ISR (INT0_vect)
{

    uint8_t buttonState = PIND & ( 1 << PD2 );
    if ( buttonState )
    {
        if ( buttonWasPressed == 0 )
        {
            PORTD ^= ( 1 << PD7 );  /// SET PIN 4 IN PORT B TO LOW
            _delay_ms( 200 );
            buttonWasPressed = 1;   /// update button state
        }
    }
    else                            /// The button is not pressed
    {
        buttonWasPressed = 0;       /// Update the button state
    }
}

void play( void )
{
    for ( uint8_t i = 0 ; i < 6 ; i++ )
    {
        PORTB |= ( 1 << LEDS[i] );  ///Turn LED ON
        _delay_ms( 250 );
        PORTB &= ~( 1 << LEDS[i] ); ///Turn LED OFF
        _delay_ms( 250 );
    }
}
\ifndef F\u CPU
#定义F_CPU 1600000UL
#恩迪夫
#包括
#包括
#包括
虚空游戏(void);
易失性uint8_t按钮加压=0;
常量无符号字符LED[]={PB0,PB1,PB2,PB3,PB4,PB5};
内部主(空)
{
DDRB=0xFF;///将端口B设置为输出

DDRD |=(1试试这样的方法

#ifndef F_CPU
#define F_CPU 16000000UL
#endif

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

void play( unsigned int a );
ISR (INT0_vect);

volatile uint8_t buttonWasPressed = 0;
const unsigned char LEDS[] = { PB0, PB1, PB2, PB3, PB4, PB5 };
unsigned int ledNum = 0;

int main(void)
{
    DDRB = 0xFF;  /// Set PORTD as OUTPUT

    DDRD  |=  ( 1 << PD7 );     /// Set PIN7 IN DDRD as INPUT
    PORTD &= ~( 1 << PD7 );     /// Set PIN7 on PORTD to LOW
    DDRD  &= ~( 1 << PD2 );     // Clear the PD2 pin and set PD2 (PCINT0 pin) now as input
    PORTD |= (1 << PD2);        // Set PIN PD2 as INPUT with pull-up enabled

    EICRA |= (1 << ISC00);      // set INT0 to trigger on ANY logic change
    EIMSK |= (1 << INT0);       // Turns on INT0
    sei();                      // turn on interrupts

    while(1)
    {
        if(buttonWasPressed == 1)
            play(ledNum);

    }
}

ISR (INT0_vect)
{

    uint8_t buttonState = PIND & ( 1 << PD2 );
    if ( buttonState )
    {
        if ( buttonWasPressed == 0 )
        {
            PORTD ^= ( 1 << PD7 );  /// SET PIN 4 IN PORT B TO LOW
            _delay_ms( 200 );
            buttonWasPressed = 1;   /// update button state
        }
    }
    else                            /// The button is not pressed
    {
        buttonWasPressed = 0;       /// Update the button state
    }
}

void play( unsigned int a )
{
    for ( uint8_t i = a ; i < 6 ; i++ )
    {
        PORTB |= ( 1 << LEDS[i] );  ///Turn LED ON
        _delay_ms( 250 );
        PORTB &= ~( 1 << LEDS[i] ); ///Turn LED OFF
        _delay_ms( 250 );
        ledNum=i;
    }
}
\ifndef F\u CPU
#定义F_CPU 1600000UL
#恩迪夫
#包括
#包括
#包括
无效播放(未签名整数a);
行业特殊风险(国际向量);
易失性uint8_t按钮加压=0;
常量无符号字符LED[]={PB0,PB1,PB2,PB3,PB4,PB5};
无符号整数ledNum=0;
内部主(空)
{
DDRB=0xFF;///将端口D设置为输出

DDRD |=(1我在@Althaf1467的帮助下成功修复了它

工作守则是:

#ifndef F_CPU
#define F_CPU 16000000UL
#endif

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define LEDS_LENGTH 6

void play( void );

volatile uint8_t state = 0 ;
const unsigned char LEDS[] = { PB0, PB1, PB2, PB3, PB4, PB5 };

int main( void )
{
    DDRB = 0xFF;                    /// Set PORTD as OUTPUT

    DDRD  |=  ( 1UL << PD7   );     /// Set PIN7 IN DDRD as INPUT
    PORTD &= ~( 1UL << PD7   );     /// Set PIN7 on PORTD to LOW
    DDRD  &= ~( 1UL << PD2   );     /// Clear the PD2 pin and set PD2 (PCINT0 pin) now as input
    PORTD |=  ( 1UL << PD2   );     /// Set PIN PD2 as INPUT with pull-up enabled

    EICRA |=  ( 1UL << ISC00 );     /// set INT0 to trigger on ANY logic change
    EIMSK |=  ( 1UL << INT0  );     /// Turns on INT0
    sei();                          /// turn on interrupts

    while(1)
    {
        play();
    }
}

ISR ( INT0_vect )
{
    if ( PIND & ( 1UL << PD2 ) )
    {
        PORTD ^= ( 1UL << PD7 );    /// SET PIN 4 IN PORT B TO LOW
        state ^= ( 1 << 0 );        /// Swap the Buton State from 0 to 1 and back to 0 ...
        _delay_ms( 500 );
    }
}

void play( void )
{
    static uint8_t step = 0;
    while( step < LEDS_LENGTH )
    {
        if ( state == 1 )
        {
            break;
        }
        PORTB |=  ( 1UL << LEDS[ step ] );  /// Turn LED ON
        _delay_ms( 250 );

        PORTB &= ~( 1UL << LEDS[ step ] );  /// Turn LED OFF
        _delay_ms( 250 );

        step++;
    }

    if ( step == LEDS_LENGTH )
    {
        step = 0;
    }
}
\ifndef F\u CPU
#定义F_CPU 1600000UL
#恩迪夫
#包括
#包括
#包括
#定义LED_长度6
虚空游戏(void);
易失性uint8_t状态=0;
常量无符号字符LED[]={PB0,PB1,PB2,PB3,PB4,PB5};
内部主(空)
{
DDRB=0xFF;///将端口D设置为输出

DDRD |=(可能会有人问我是否肯定ommit ISR“原型”@KIIV我不知道。我会删除它。@AlexK。这不是关于
arduino
,而是关于我需要继续的C代码。这更多的是关于
AVR
我想
按钮的按下对你的主代码有什么影响?几乎可以工作了,但一旦我按下按钮,函数
play()
停止,如果我再次按下按钮,则只有
PD7
LED闪烁。