20 Pin AVR Relay Development Board Firmware
From Catholicpenguin
[edit]
Overview
Sparkfun makes a development board with 4 relays. The only practical chip is the ATTiny2313, which has so little ram that about all you can really do is turn the board into an a dumb I/O module over serial.
This firmware does this. This was last compiled with WinAVR-20081205 on Windows Vista.
Protocol:
- 9600 baud serial.
- 'in:[0-3]<SP>\n' - Reads the digital input 0-3, which correspond to the input pins 1-4. Note you need a space after the command, before the newline, because of a bug.
- 'out:[0-3][0-1]<SP>\n' - Switches one of the relays on/off. Nothing is echoed back in confirmation of this command.
[edit]
Source
#include <avr/io.h>
#include <stdio.h>
#include <string.h>
#define Rx PD0
#define Tx PD1
#define STATUS PB4
unsigned char inputs[] = {PD2,PD3,PD5,PD6};
unsigned char outputs[] = {PB3,PB2,PB1,PB0};
unsigned char IO_get(unsigned char input)
{
return PIND & (1<<input);
}
void IO_set(unsigned char output, unsigned char val)
{
if (val)
PORTB |= (1<<output);
else
PORTB &= ~(1<<output);
}
void IO_Init(void)
{
for (unsigned char i=0;i<4;i++) {
DDRD &= ~(1<<inputs[i]); // Input
PORTD &= ~(1<<inputs[i]); // Tri-state
}
for (unsigned char i=0;i<4;i++) {
DDRB |= (1<<outputs[i]); // Outputs
PORTB &= ~(1<<outputs[i]); // Off
}
DDRB |= (1<<STATUS); // Outputs
PORTB &= ~(1<<STATUS); // Off
}
void USART_Init( unsigned int baud )
{
/* Set baud rate */
UBRRH = (unsigned char)(baud>>8);
UBRRL = (unsigned char)baud;
/* Enable receiver and transmitter */
UCSRB = (1<<RXEN)|(1<<TXEN);
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<USBS)|(3<<UCSZ0);
}
static int USART_Transmit( unsigned char data , FILE *stream)
{
/* Wait for empty transmit buffer */
while ( !( UCSRA & (1<<UDRE)) )
;
/* Put data into buffer, sends the data */
UDR = data;
return 0;
}
static int USART_Receive( FILE *stream )
{
/* Wait for data to be received */
while ( !(UCSRA & (1<<RXC)) )
;
/* Get and return received data from buffer */
if (UDR == '\r') return '\n';
return UDR;
}
static FILE mystdout = FDEV_SETUP_STREAM(USART_Transmit, USART_Receive, _FDEV_SETUP_RW);
void init(void)
{
// Set USART Tx as output, Rx as input
DDRD &= ~(1<<Rx); // Input
PORTD &= ~(1<<Rx); // Tri-state
DDRB |= (1<<Tx); // Output
USART_Init(64); // 9600, 10MHz clock == 64
stdout = &mystdout;
stdin = &mystdout;
IO_Init();
}
int main(void)
{
char strbuf[16];
init();
printf("in:[0-3] \nor out:[0-3][0-1] \n");
while (1)
{
fgets(strbuf,16,stdin);
char * pos;
if ((pos = strstr(strbuf,"in:")))
{
unsigned char input = *(pos+3)-'0';
putchar(input+'0');
putchar(IO_get(input)+'0');
}
else if ((pos = strstr(strbuf,"out:")))
{
unsigned char output = *(pos+4)-'0';
unsigned char val = *(pos+5)-'0';
IO_set(output,val);
}
else
putchar('?');
}
return 0;
}
