我正在使用树莓派和atmega 32来使用和学习SPI。它应该遵循过渡图,但是在atmega的某个地方出错了,我不知道它哪里出错了。
这是覆盆子代码

    #include <wiringPi.h>
#include <stdio.h>
#include <wiringPiSPI.h>

#define SELECTADC 6
#define READY 8
#define GIVEADC 32
#define NOTREADY 0x10
#define DUMMY 0x55
#define ACK 10
#define IDLE 1
#define POLL 2
#define ADCSTART 3
#define ADCSTATE 4
#define ADCRESULT 5
main() {
    int tellerPoll=0;
    int teller=0;
    int adcStatusTeller=0;
    int status=0;
    unsigned char data[4];
    wiringPiSetup();
    int kanaal = 0;
    int adc;
    int adcHigh=0;
    int error=0;
    if( wiringPiSPISetup (0, 500000)==-1)
    {
        printf("Could not initialise SPI\n");
        status=0;
        return;
    } else {
        status = IDLE;
        printf("succesful initialised\n");
    }

    for(;;)
    {
        delay(20);
        //wiringPiSPIDataRW(0,data,1);
        switch(status){
        case 0 :
                exit(0);
        case IDLE :
            teller +=1;
            if((teller % 2 == 1)&&1){
                data[0] = POLL;
                wiringPiSPIDataRW(0,data,1);
                status = POLL;
                //teller=0;
                printf("Poll\n");
            }
            else if ((teller % 2 == 0)&&1){
                status = ADCSTART;
            }
            break;
        case  POLL :
            data[0] = DUMMY;
            wiringPiSPIDataRW(0,data,1);
                        printf("Poll result: %x\n", data[0]);
            if(data[0]==ACK){
                status=IDLE;
                printf("Poll succesfull\n");
                tellerPoll=0;
            }
            else{
                tellerPoll+=1;
                if(tellerPoll>20){
                    status=0;
                    printf("No device found\n");
                    tellerPoll=0;
                }
            }

            break;

        case ADCSTART :
            data[0]=ADCSTART;
            wiringPiSPIDataRW(0,data,1);
            status = ADCSTATE;
            printf("ADCSTART\n");
            break;

        case ADCSTATE :
//          printf("ADCSTATE\n");
            data[0]=ADCSTATE;
                        wiringPiSPIDataRW(0,data,1);
            //printf("%x\n",data[0]);
            if(data[0]==READY){
                status=ADCRESULT;
                printf("Ready\n");
                break;
            }
            else if(data[0]==NOTREADY){
                    printf("NOTREADY\n");
                    status=ADCSTATE;
                    adcStatusTeller+=1;
                    if(adcStatusTeller==100){
                        status=IDLE;
                        adcStatusTeller=0;
                        printf("no ADC result\n");
                    }
            }
            else{
                adcStatusTeller+=1;
                status =ADCSTATE;
                                printf("Weird result: %x\n", data[0]);
                if (adcStatusTeller==100){
                    status=IDLE;
                    adcStatusTeller=0;
                    printf("no Results: %x \n", data[0]);
                }
            }
            break;

        case ADCRESULT :

            data[0]=GIVEADC;
            wiringPiSPIDataRW(0,data,1);

            data[0]=DUMMY;
            wiringPiSPIDataRW(0,data,1);
            adc = data[0];

            delay(10);

            data[0]=DUMMY;
            wiringPiSPIDataRW(0,data,1);
            adcHigh=data[0];

            //adcHigh &= 0b11000000;
            //adcHigh <<=2;
            //adc += adcHigh;
            printf("ADC %d  heeft waarde %x %x \n",kanaal, adcHigh, adc);
            status=IDLE;
            break;
        case SELECTADC :

            data[0]=SELECTADC;
            wiringPiSPIDataRW(0,data,1);
            data[0]=DUMMY;
            wiringPiSPIDataRW(0,data,1);
            if(data[0]==ACK){
                delay(10);
                data[0]=kanaal;
                wiringPiSPIDataRW(0,data,1);
                printf("ADC %s is succesfully selected",kanaal);
                status=POLL;
            }
            else{
                printf("There was an error selecting the ADC");
                status=SELECTADC;
                error+=1;
                if(error==20){
                    status=POLL;
                    error=0;
                    printf("No ADC selected");
                    break;
                }
            }
            break;
        default :
            printf("default\n");
            break;
        }
        kanaal=0;


    }
}


还有Atmega32

#include <stdlib.h>
#include <avr/io.h>
void adc_init(void);
void SPI_SlaveInit(void);
unsigned char SPI_SlaveReceive(unsigned char);
void leesADC(char);

#define IDLE 1
#define POLL 2
#define ADCSTART 3
#define ADCSTATE 4
#define SELECTADC 6
#define READY 8
#define ACK 10
#define GIVEADC 32
#define NOTREADY 0x10
#define DUMMY 0x55

void SPI_SlaveInit(void)
{
 /* Set MISO output, all others input */
 DDRB = (1<<PB6);
 /* Enable SPI */
 SPCR = (1<<SPE);
}
unsigned char SPI_SlaveReceive(unsigned char data)
{
 SPDR = data;
 /* Wait for reception complete */
 while(!(SPSR & (1<<SPIF) ));
 /* Return data register */
 return SPDR;
}
//starADC
void leesADC(char kanaal)
{

 ADMUX &= 0b11100000;
 ADMUX |= kanaal & 7;
 ADCSRA |= (1<<ADSC);
}
void adc_init(void)
{
 ADMUX=(1<<REFS0)|(1<<ADLAR); //voedings U als referentie, links uitlijnen in de 10bit
 ADCSRA=(1<<ADEN); // adc enablen, start conversion, auto trigger enable
}

int main(void)
{
 DDRC= 0b11111111;
 DDRD= 0b11111111;
 SPI_SlaveInit();
 adc_init();
 int kanaal=0;
 leesADC(kanaal);

 char stap;
 char status;

 while(1)
 {
    switch(stap){
        case IDLE :
            stap = SPI_SlaveReceive(status);
            break;

        case POLL :
            status = ACK;
            stap=IDLE;
            PORTD=15;
            break;

        case ADCSTART :

            status = ADCSTART;
            leesADC(kanaal);
            PORTD=255;
            break;

        case ADCSTATE :

            if ((ADCSRA & (1<<ADIF)) == 0){
                status = NOTREADY;

            } else{
                status = READY;
            }
            stap=IDLE;
            break;

        case GIVEADC :
            stap= ADCH;
            break;

        case SELECTADC :
            kanaal = SPI_SlaveReceive(DUMMY);
            stap=DUMMY;
            break;

        default :   ;
    }



 }
}


提前致谢。

最佳答案

您无需初始化stap变量,这意味着其值将是不确定的。尝试在switch语句中使用它会导致未定义的行为。

我想您应该将其初始化为IDLE

int stap = IDLE;

09-20 07:16