#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/delay.h>
#include <stdbool.h>
#include "lcdrunn.h"
#define MOSI PB5
#define MISO PB6
#define SCK PB7
#define CS PA0
#define CSS PA1
#define PORT_SPI PORTA
#define CS_HIGH PORTA |= (1 << CS);
#define CS_LOW PORTA &= ~(1 << CS)
#define CS_HIGHH PORTA |= (1 << CSS);
#define CS_LOWW PORTA &= ~(1 << CSS);
#define EEMEM __attribute__((section(".eeprom")))
void InitSpi();
void SendSpi(uint8_t bajt);
uint8_t ReceiveSpi( void );
uint8_t SendAndReceive(uint8_t data);
uint16_t MCP3304(uint8_t channel, uint8_t chooseMCP);
void displayAmperage(uint32_t pomiar);
void displayVoltage(uint32_t pomiar);
int main(void)
{
lcd_init();
InitSpi();
while(1)
{
lcd_cls();
uint32_t pomiarU = MCP3304(0,1);
uint32_t pomiarA = MCP3304(0,2);
uint32_t pomiar2U = MCP3304(2,1);
uint32_t pomiar2A = MCP3304(2,2);
uint32_t pomiar3U = MCP3304(6,1);
uint32_t pomiar3A = MCP3304(4,2);
displayVoltage(pomiarU);
displayAmperage(pomiarA);
displayVoltage(pomiar2U);
displayAmperage(pomiar2A);
displayVoltage(pomiar3U);
displayAmperage(pomiar3A);
_delay_ms(1000);
}
}
void displayAmperage(uint32_t pomiar)
{
if(pomiar > 4096)
{
pomiar = (8192 - pomiar)/2;
lcd_str("-");
}
uint32_t result = (pomiar * 2.56 / 4096) * 1000 * 10 ;// /2 dla drugiego mcp
uint16_t unity = result % 1000;
uint16_t dozens = result / 1000;
lcd_int(dozens);
lcd_str(".");
if(unity < 10)
{
lcd_int(0);
lcd_int(0);
}
else if( unity < 100)
{
lcd_int(0);
}
lcd_int(unity);
lcd_str(" A ");
}
void displayVoltage(uint32_t pomiar)
{
if(pomiar > 4096)
{
pomiar = (8192 - pomiar);
lcd_str("-");
}
uint32_t wyn = (pomiar * 2.56 / 4096) * 32000 ;// /2 dla drugiego mcp
uint16_t unity = wyn % 1000;
uint16_t dozens = wyn / 1000;
lcd_int(dozens);
lcd_str(".");
if(unity < 10)
{
lcd_int(0);
lcd_int(0);
}
else if( unity < 100)
{
lcd_int(0);
}
lcd_int(unity);
lcd_str(" V ");
}
void InitSpi()
{
DDRB |= (1 << MOSI) | (1 << SCK) | (1 << PB4);
PORTB |= (1 << PB4);
DDRA |= (1 << CS) | (1 << CSS);
// Define the following pins as output
//DDRA |= (1 << CS);
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(SPIE);
//SPSR |= (1 << SPI2X);
CS_HIGH;
CS_HIGHH;
}
//wysyłanie do adc
void SendSpi(uint8_t bajt)
{
SPDR = bajt;
while( !(SPSR & (1 << SPIF)) );
}
//odbiór z adc
uint8_t ReceiveSpi( void )
{
CS_HIGH;
_delay_us(5);
CS_LOW;
while( !(SPSR & (1 << SPIF)) );
return SPDR;
}
uint8_t SendAndReceive(uint8_t data)
{
SPDR = data;
while( !(SPSR & (1 << SPIF)) );
return SPDR;
}
uint16_t MCP3304(uint8_t channel, uint8_t chooseMCP)
{
uint8_t send_one = 0x08 | (channel >> 1);
uint8_t send_two = 0x00 | (channel << 7);
uint8_t send_three = 0x00;
uint16_t sum;
uint8_t wyn1;
uint8_t wyn2;
uint32_t fullSum = 0;
for(int i = 0; i < 5; ++i)
{
if(chooseMCP == 1)
{
CS_LOW;
SendAndReceive(send_one);
wyn1 = SendAndReceive(send_two);
wyn2 = SendAndReceive(send_three);
CS_HIGH;
}
else
{
CS_LOWW;
SendAndReceive(send_one);
wyn1 = SendAndReceive(send_two);
wyn2 = SendAndReceive(send_three);
CS_HIGHH;
}
wyn1 = wyn1 & 0b00011111;
sum = wyn1;
sum = sum << 8;
sum |= wyn2;
fullSum += sum;
}
sum = fullSum/5;
return sum;
}