September 01, 2011
by missle3944
|
Hi guys I'm just fooling around with spi between my 2 mcus and I was able to get them to work fine through spi. Now I made a spi temp sensor but for some reason my slave only sends one byte to the master or something like that. My slave has the temp sensor and all of the ADC code on it. But for some reason I cant tell if the master is only reading one byte or the slave is only sending one byte. |
September 01, 2011
by Ralphxyz
|
Dan, you can hard code a message string for the slave to send.
That way you take the temp sensor out of the equation.
Ralph |
September 01, 2011
by missle3944
|
Ralph, how would I do this. Would I use an array? Heres my code for the slave if anyone has a suggestion ,too.
//
// slave_SPI.c
//
#define F_CPU 14745600
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>
#include <inttypes.h>
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/io_328p.h"
#include <stdio.h>
#include <math.h>>
#include "../libnerdkits/delay.h"
#include "../libnerdkits/uart.h"
// preprocessor macros for port/pin manulipulation
//
#define INPUT2(port,pin) DDR ## port &= ~_BV(pin)
#define OUTPUT2(port,pin) DDR ## port |= _BV(pin)
#define CLEAR2(port,pin) PORT ## port &= ~_BV(pin)
#define SET2(port,pin) PORT ## port |= _BV(pin)
#define TOGGLE2(port,pin) PORT ## port ^= _BV(pin)
#define READ2(port,pin) ((PIN ## port & _BV(pin))?1:0)
//------------------------------------------------------------
#define INPUT(x) INPUT2(x)
#define OUTPUT(x) OUTPUT2(x)
#define CLEAR(x) CLEAR2(x)
#define SET(x) SET2(x)
#define TOGGLE(x) TOGGLE2(x)
#define READ(x) READ2(x)
#define PULLUP_ON(x) INPUT2(x); SET2(x)
#define PULLUP_OFF(x) INPUT2(x); CLEAR2(x)
void adc_init() {
// set analog to digital converter
// for external reference (5v), single ended input ADC0
ADMUX = 0;
// set analog to digital converter
// to be enabled, with a clock prescale of 1/128
// so that the ADC clock runs at 115.2kHz.
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
// fire a conversion just to get the ADC warmed up
ADCSRA |= (1<<ADSC);
}
uint16_t adc_read() {
// read from ADC, waiting for conversion to finish
// (assumes someone else asked for a conversion.)
// wait for it to be cleared
while(ADCSRA & (1<<ADSC)) {
// do nothing... just hold your breath.
}
// bit is cleared, so we have a result.
// read from the ADCL/ADCH registers, and combine the result
// Note: ADCL must be read first (datasheet pp. 259)
uint16_t result = ADCL;
uint16_t temp = ADCH;
result = result + (temp<<8);
// set ADSC bit to get the *next* conversion started
ADCSRA |= (1<<ADSC);
return result;
}
double sampleToFahrenheit(uint16_t sample) {
// conversion ratio in DEGREES/STEP:
// (5000 mV / 1024 steps) * (1 degree / 10mV)
// ^^^^^^^^^^^ ^^^^^^^^^^
// from ADC from LM34
return sample * (5000.0 / 1024.0 / 10.0);
}
// local functions
void spi_slave_init(void);
uint8_t spi_recv_char(uint8_t send);
// define ports, pins
//
#define DD_MISO B,4
#define DD_MOSI B,3
#define DD_SCK B,5
#define DD_SS B,2
// --------------------------------------------------------------------------------------------------------
int main() {
// start up the Analog to Digital Converter
adc_init();
// start up the serial port
uart_init();
FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
stdin = stdout = &uart_stream;
// holder variables for temperature data
uint16_t last_sample = 0;
double this_temp;
double temp_avg;
uint8_t i;
// initialize SPI
spi_slave_init();
uint8_t byte_received;
uint8_t byte_to_send;
DDRD |= (1<<PD7);
DDRD |= (1<<PD6);
// get a byte, increment it, and send back
while(1){
temp_avg = 0.0;
for(i=0; i<100; i++) {
last_sample = adc_read();
this_temp = sampleToFahrenheit(last_sample);
// add this contribution to the average
temp_avg = temp_avg + this_temp/100.0;
}
if (byte_received == 2){
byte_received = spi_recv_char(temp_avg);
printf_P(PSTR("%.2f degrees F\r\n"), temp_avg);
}
}
}
// --------------------------------------------------------------------------------------------------------
//
void spi_slave_init(void){
// setup slave SPI pins
OUTPUT(DD_MISO);
INPUT(DD_MOSI);
INPUT(DD_SCK);
INPUT(DD_SS);
// enable SPI
SPCR = _BV(SPE);
}
uint8_t spi_recv_char(uint8_t send){
// character to send
SPDR = send;
// wait for received character
while(!(SPSR & _BV(SPIF)));
// return recieved character
return(SPDR);
}
|