我正在使用树莓派和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;