This week: I started putting together a test program to read from the power chip. So far it is just a skeleton and I need to fill in the details on the SPI communication. The test program will in essence transfer data from the ADE7763 to a computer terminal. Because we already have experience with RS232 communication, I will use SecureCRT as my terminal. When the user presses "p" on the computer, the microcontroller will contact the ADE7763, read the power and print it to the terminal. This way we can make sure the microcontroller is able to read data and determine whether the values make sense. I also began searching the internet for information regarding the Ethernet communication. It also uses SPI bus so the basic concepts will be the same, just a difference in addresses and commands. Because both devices use the same bus, they will share some communication lines. Their individual addresses will let its device know that it is being communicated with. Here is a basic wiring diagram of the microcontroller with two SPI devices.
**Click to Enlarge**
---------------------------------------------------------------------------------------------
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdio.h>
#include "uart.h"
#include "spi.h"
#define F_CPU 8000000UL // This should match the processor speed
#define BAUD_RATE 9600 // Baud rate. The usart_int routine
// Variables and #define for rge RX ring buffer.
#define RX_BUFFER_SIZE 64
unsigned char rx_buffer[RX_BUFFER_SIZE];
volatile unsigned char rx_buffer_head;
volatile unsigned char rx_buffer_tail;
//USART Function Prototypes
unsigned char uart_buffer_empty(void);
void usart_prints(const char *ptr);
void usart_printf(const char *ptr);
void usart_init(void);
void usart_putc(const char c);
unsigned char usart_getc(void);
int getPower(int command);
void setRegister(int value, int command);
void startReading(int command);
int main(void)
{
//pull CS low?
int pow = 0;
int valP = 0;
usart_init();
//Initialize Power Chip settings
setRegister(valP, pow);
startReading(pow);
sei();
while(1)
{
char str[25];
uint8_t power = getPower(pow);
while(!uart_buffer_empty()){
char c = usart_getc();
if(c == 'p'){
usart_prints("\r");
usart_prints("The power is: ");
sprintf(str,"%d\n",power);
usart_prints(str);
}
}
_delay_ms(10000);
}
}
int getPower(int command)
{
int value = 1; //read power from chip
return value;
}
void setRegister(int value, int command)
{
//set bits of specified register
}
void startReading(int command)
{
}
//USART FUNCTIONS BELOW
ISR(USART_RX_vect)
{
// UART receive interrupt handler.
// To do: check and warn if buffer overflows.
char c = UDR0;
rx_buffer[rx_buffer_head] = c;
if (rx_buffer_head == RX_BUFFER_SIZE - 1)
rx_buffer_head = 0;
else
rx_buffer_head++;
}
void usart_init(void)
{
// Configures the USART for serial 8N1 with
// the Baud rate controlled by a #define.
unsigned short s;
// Set Baud rate, controlled with #define above.
s = (double)F_CPU / (BAUD_RATE*16.0) - 1.0;
UBRR0H = (s & 0xFF00);
UBRR0L = (s & 0x00FF);
// Receive complete interrupt enable: RXCIE0
// Receiver & Transmitter enable: RXEN0,TXEN0
UCSR0B = (1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
// Along with UCSZ02 bit in UCSR0B, set 8 bits
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
DDRD |= (1<< 1); // PD0 is output (TX)
DDRD &= ~(1<< 0); // PD1 is input (Rx)
// Empty buffers
rx_buffer_head = 0;
rx_buffer_tail = 0;
}
void usart_printf(const char *ptr){
// Send NULL-terminated data from FLASH.
// Uses polling (and it blocks).
char c;
while(pgm_read_byte_near(ptr)) {
c = pgm_read_byte_near(ptr++);
usart_putc(c);
}
}
void usart_putc(const char c){
// Send "c" via the USART. Uses poling
// (and it blocks). Wait for UDRE0 to become
// set (=1), which indicates the UDR0 is empty
// and can accept the next character.
while (!(UCSR0A & (1<<UDRE0)))
;
UDR0 = c;
}
void usart_prints(const char *ptr){
// Send NULL-terminated data from SRAM.
// Uses polling (and it blocks).
while(*ptr) {
while (!( UCSR0A & (1<<UDRE0)))
;
UDR0 = *(ptr++);
}
}
unsigned char usart_getc(void)
{
// Get char from the receiver buffer. This
// function blocks until a character arrives.
unsigned char c;
// Wait for a character in the buffer.
while (rx_buffer_tail == rx_buffer_head)
;
c = rx_buffer[rx_buffer_tail];
if (rx_buffer_tail == RX_BUFFER_SIZE-1)
rx_buffer_tail = 0;
else
rx_buffer_tail++;
return c;
}
unsigned char uart_buffer_empty(void)
{
// Returns TRUE if receive buffer is empty.
return (rx_buffer_tail == rx_buffer_head);
}
----------------------------------------------------------------------------------------
Next week: I'll continue to work on my ADE7763 test program and Ethernet specific SPI programming. I may also start my test program for the Ethernet communication to the computer.