C 运行时无法在我的代码中的开关状态之间切换(ATMEGA328p)

C 运行时无法在我的代码中的开关状态之间切换(ATMEGA328p),c,arduino-uno,C,Arduino Uno,当运行代码时,它应该处于待机状态,直到按下按钮,使其进入下一个运行状态,此时所有数码输出(LED)都会工作。但是,只要我上传代码到ATMEGA328p,并在运行模式下启动,不会改变。按钮连接到Arduino上的引脚,该引脚在电路板中嵌入了一个小LED,因此我知道它肯定在切换 任何帮助都将不胜感激,我对另一个代码也有同样的问题,所以我知道这肯定是我做错了 #include <avr/io.h> #include <avr/interrupt.h> #include <

当运行代码时,它应该处于待机状态,直到按下按钮,使其进入下一个运行状态,此时所有数码输出(LED)都会工作。但是,只要我上传代码到ATMEGA328p,并在运行模式下启动,不会改变。按钮连接到Arduino上的引脚,该引脚在电路板中嵌入了一个小LED,因此我知道它肯定在切换

任何帮助都将不胜感激,我对另一个代码也有同样的问题,所以我知道这肯定是我做错了

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

#define SET_BIT(reg, pin)           (reg) |= (1 << (pin))
#define CLEAR_BIT(reg, pin)       (reg) &= ~(1 << (pin))
#define WRITE_BIT(reg, pin, value)   (reg) = (((reg) & ~(1 << (pin))) | ((value) << (pin)))
#define BIT_VALUE(reg, pin)       (((reg) >> (pin)) & 1)
#define BIT_IS_SET(reg, pin)         (BIT_VALUE((reg),(pin))==1)

//uart definitions
#define BAUD (9600)
#define MYUBRR (F_CPU/16/BAUD-1)

// These buffers may be any size from 2 to 256 bytes.
#define  RX_BUFFER_SIZE  64
#define  TX_BUFFER_SIZE  64


//uart definitions
unsigned char rx_buf;

static volatile uint8_t tx_buffer[TX_BUFFER_SIZE];
static volatile uint8_t tx_buffer_head;
static volatile uint8_t tx_buffer_tail;
static volatile uint8_t rx_buffer[RX_BUFFER_SIZE];
static volatile uint8_t rx_buffer_head;
static volatile uint8_t rx_buffer_tail;


// Functions declaration
void setup(void);
void process(void);
void uart_init(unsigned int ubrr);
void valve_pot_init(void);

// Uart functions
void uart_putchar(uint8_t c);
uint8_t uart_getchar(void);
uint8_t uart_available(void);
void uart_putstring(unsigned char* s);
void uart_getLine(unsigned char* buf, uint8_t n);

// ADC functions
uint16_t adc_read(uint8_t channel);
void adc_init();

// Global Variables & Defines for Puush Button Debouncing
#define PButton 0b00010000 // Location of pushbutton input in Port B
volatile uint8_t pushbuttons_db = 0;
volatile uint8_t reg1;
volatile uint8_t reg2;

// Setting up switch statement within process function
enum {
    standby,
    running,
    };
    
void digital_io_init( void ){
    
    // LED Setup    
    SET_BIT(DDRB,PB0); // Red LED, valve is operational, Unsafe to touch
    SET_BIT(DDRB,PB1); // Green LED, valve is non-operational, Safe to touch
    SET_BIT(DDRB,PB2); // Red LED, valve is fully open
    SET_BIT(DDRB,PB3); // Green LED, valve is fully closed
    SET_BIT(DDRD,PD2); // Back Light LED
    
    // Push Button Setup
    CLEAR_BIT(DDRB,PB4);
    
}

void debounce_init(void) {
    cli();
    
    // Setting Clear Time Compare on Timer0
    SET_BIT(TCCR0A,WGM01);
    CLEAR_BIT(TCCR0A,WGM00);
    
    // Setting Prescalar of 256 on Timer0
    SET_BIT(TCCR0B,CS02);
    CLEAR_BIT(TCCR0B,CS01);
    CLEAR_BIT(TCCR0B,CS00);
    
    // Setting 2ms period on Timer0
    CLEAR_BIT(OCR0A,7);
    SET_BIT(OCR0A,6);
    SET_BIT(OCR0A,5);
    SET_BIT(OCR0A,4);
    SET_BIT(OCR0A,3);
    SET_BIT(OCR0A,2);
    CLEAR_BIT(OCR0A,1);
    SET_BIT(OCR0A,0);
    
    // Enabling Interupt on Output Compare Match A 
    CLEAR_BIT(TIMSK0,OCIE0B);
    SET_BIT(TIMSK0,OCIE0A);
    CLEAR_BIT(TIMSK0,TOIE0);

    sei();
}

//main loop
int main() {
    
    // Digital I/O initialise
    digital_io_init();
    
    // Pot for valve, ADC initialise
    valve_pot_init();
    
    // Push button & debouncing initialise
    debounce_init();

    for ( ;; ) {
        process();
        // _delay_ms(1);
    }
}

//initialises ADC and UART port
void valve_pot_init(void) {

    //init uart
    uart_init(MYUBRR);

    // Initialise adc
    SET_BIT(ADCSRA,ADEN);
    
    // ADC Enable and pre-scaler of 128: ref table 24-5 in datasheet
    SET_BIT(ADCSRA,ADPS2);
    SET_BIT(ADCSRA,ADPS1);
    SET_BIT(ADCSRA,ADPS0);
    // ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);

   // Selecting channel and ref input voltage
    SET_BIT(ADMUX,REFS0);
    CLEAR_BIT(ADMUX,MUX0);
    CLEAR_BIT(ADMUX,MUX1);
    CLEAR_BIT(ADMUX,MUX2);
    CLEAR_BIT(ADMUX,MUX3);
    CLEAR_BIT(ADMUX,REFS1);

}


void process(void) {

    // For Push Button & Debouncing
    uint8_t pb_now = 0;
    uint8_t pb_prev = 0;
    uint8_t pb_pressed;
    
    // Determining whether push button has been pressed
    pb_now = pushbuttons_db;
    pb_pressed = pb_now & (pb_now ^ pb_prev);
    pb_prev = pb_now;

    char temp_buf[64];

   // Start single conversion by setting ADSC bit in ADCSRA
    ADCSRA |= (1 << ADSC);

    // Wait for ADSC bit to clear, signalling conversion complete.
     while ( ADCSRA & (1 << ADSC) ) {}

    // Result now available in ADC
    uint16_t pot = ADC;
    uint16_t valve_position = pot / 10.23; // This will give an output range of 0 to 100%
    
    // convert uint16_t to string
    itoa(valve_position, (char *)temp_buf,10);
    
    // Send serial data
   uart_putstring((unsigned char *) temp_buf);
   uart_putchar('\t');

    static uint8_t state = standby ;
        
        switch (state){
            
            // This state is for no one is in the sauna, system on standby
            case standby:   // Clearing Light Outputs
                            CLEAR_BIT(PORTB,PB0); // Red LED, valve is operational, Unsafe to touch
                            CLEAR_BIT(PORTB,PB1); // Green LED, valve is non-operational, Safe to touch
                            CLEAR_BIT(PORTB,PB2); // Red LED, valve is fully open
                            CLEAR_BIT(PORTB,PB3); // Green LED, valve is fully closed
                            CLEAR_BIT(PORTD,PD2); // Back Light LED
                    
                            // Turning On Green LED on to say sauna is safe
                            SET_BIT(PORTB,1); // Green LED, valve is non-operational, Safe to touch
                    
                            // Button pressed means someone has entered sauna, go to running state
                            if ( pb_pressed & PButton ) {
                                state = running;
                            }
            
            // This state is for when someone is using the sauna, system is on
            case running:   // Cleaing Light Outputs
                            CLEAR_BIT(PORTB,PB0); // Red LED, valve is operational, Unsafe to touch
                            CLEAR_BIT(PORTB,PB1); // Green LED, valve is non-operational, Safe to touch
                            CLEAR_BIT(PORTB,PB2); // Red LED, valve is fully open
                            CLEAR_BIT(PORTB,PB3); // Green LED, valve is fully closed
                            CLEAR_BIT(PORTD,PD2); // Back Light LED
                    
                            // Turning On Red LED & LCD Back Light
                            SET_BIT(PORTD,PD2); // Back Light LED, turn on
                            SET_BIT(PORTB,PB0); // Red LED, valve is operational, Unsafe to touch
                            
                            // Physical indication of valve being fully open
                            if ( valve_position == 100 ){
                                SET_BIT(PORTB,2); // Red LED, valve is fully open
                            }
                            
                            // Physical indication of valve being fully closed
                            if ( valve_position == 0 ){
                                SET_BIT(PORTB,3); // Green LED, valve is fully closed
                            }
                            
                            // Button pressed means someone is going into sauna, go to next state
                            if ( pb_pressed & PButton ){
                                state = standby;
                            }
                            
            default: state = standby;
        } // Switch Statement
}




//PLEASE NOTE THIS VERSION OF UART USES INTERRUPTS

/*  ****** serial uart definitions ************ */
/******************  interrupt based  ********/

// Initialize the UART
void uart_init(unsigned int ubrr) {

    cli();

    UBRR0H = (unsigned char)(ubrr>>8);
    UBRR0L = (unsigned char)(ubrr);
    UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
    UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
    tx_buffer_head = tx_buffer_tail = 0;
    rx_buffer_head = rx_buffer_tail = 0;

    sei();

}



// Transmit a byte
void uart_putchar(uint8_t c) {
    uint8_t i;

    i = tx_buffer_head + 1;
    if ( i >= TX_BUFFER_SIZE ) i = 0;
    while ( tx_buffer_tail == i ); // wait until space in buffer
    //cli();
    tx_buffer[i] = c;
    tx_buffer_head = i;
    UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0) | (1 << UDRIE0);
    //sei();
}

// Receive a byte
uint8_t uart_getchar(void) {
    uint8_t c, i;

    while ( rx_buffer_head == rx_buffer_tail ); // wait for character
    i = rx_buffer_tail + 1;
    if ( i >= RX_BUFFER_SIZE ) i = 0;
    c = rx_buffer[i];
    rx_buffer_tail = i;
    return c;
}


// Transmit a string
void uart_putstring(unsigned char* s)
{
    // transmit character until NULL is reached
    while(*s > 0) uart_putchar(*s++);
}


// Receive a string
void uart_getLine(unsigned char* buf, uint8_t n)
{
    uint8_t bufIdx = 0;
    unsigned char c;

    // while received character is not carriage return
    // and end of buffer has not been reached
    do
    {
        // receive character
        c = uart_getchar();

        // store character in buffer
        buf[bufIdx++] = c;
    }
    while((bufIdx < n) && (c != '\n'));

    // ensure buffer is null terminated
    buf[bufIdx] = 0;
}



uint8_t uart_available(void) {
    uint8_t head, tail;

    head = rx_buffer_head;
    tail = rx_buffer_tail;
    if ( head >= tail ) return head - tail;
    return RX_BUFFER_SIZE + head - tail;
}


// Transmit Interrupt
ISR(USART_UDRE_vect) {
    uint8_t i;

    if ( tx_buffer_head == tx_buffer_tail ) {
        // buffer is empty, disable transmit interrupt
        UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
    }
    else {
        i = tx_buffer_tail + 1;
        if ( i >= TX_BUFFER_SIZE ) i = 0;
        UDR0 = tx_buffer[i];
        tx_buffer_tail = i;
    }
}

// Receive Interrupt
ISR(USART_RX_vect) {
    uint8_t c, i;

    c = UDR0;
    i = rx_buffer_head + 1;
    if ( i >= RX_BUFFER_SIZE ) i = 0;
    if ( i != rx_buffer_tail ) {
        rx_buffer[i] = c;
        rx_buffer_head = i;
    }
}

ISR(TIMER0_COMPA_vect){

    uint8_t pb0;
    uint8_t delta;

    pb0 = ~PINB;
    
    delta = pb0 ^ pushbuttons_db;

    pushbuttons_db ^= (reg2 & delta);

    reg2 = (reg1 & delta);
    reg1 = delta;

}
#包括
#包括
#包括
#包括

#定义设置位(reg,引脚)(reg)|=(1)提示:
break
否则你会失败。@塔德曼我确实像以前一样在那里有中断,在这两种情况下都没有操作,还有什么我可以尝试的吗?它们非常重要,或者你让所有代码在特定条件下按顺序运行。你需要修复它。删除它们不是一个好计划。你可能会我希望延迟也能恢复,否则你会锁定运行该循环的CPU。我不知道,伙计,这段代码非常糟糕。例如,你没有调用setup()和adc_init()…您是否尝试在切换前设置断点,检查寄存器/变量是否与您期望的一样。否则,注释掉所有非关键代码,即仅评估按钮。尝试为状态提供一些虚拟值,看看会发生什么。