
Playing around with interrupt driven USART code, and reading/writing to EEPROM.
Made a little bit of code for the AVR, and VB6 app that allows you to store a string of text to the AVR over RS232, and retrieve it. As it the string is stored in the EEPROM, it won't be lost when the power is removed. Probably not the best code ever, just a really quick thing I was working on which I thought I would share.![]() Tested on ATMega8515 on STK500. Compiled in AVR Studio 4 (WinAVR) {You can download the sources for both the AVR and VB6 programs, including the compiled binaries from here: EEPROMWriter} Note: The code can only handle up to address 255 of the EEPROM, even though there is 512 bytes of EEPROM on the ATMega8515. May work around this later. Strings are stored from address 1, with address 0 being a byte indicating how long the string is. The string is stored much like a byte array // Include library files
#include <avr/io.h>
#include <stdlib.h>
#define F_CPU 3680000UL //Define crystal/RC osc frequency
#include <util/delay.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
//Definitions
#define CMD_PING 3
#define CMD_READ_EEPROM 4
#define CMD_WRITE_EEPROM 5
#define ACK_OK 100
#define ACK_ERROR 99
// Prototypes
void init_usart(unsigned int baud);
void init_io(void);
void txbyte(unsigned char data);
unsigned char rxbyte(void);
void startup_tasks(void);
void out_debug(unsigned char output);
void out(unsigned char output);
unsigned char out_state(void);
// Let's go
int main(void)
{
startup_tasks(); //Boot procedure for microcontroller
while(1)
{ //Infinite loop, let ISRs do all the hard work from now on
}
}
void startup_tasks(void)
{
init_usart(23); //Init the USART (Serial) for 3.68Mhz clock at 9600 Baud
init_io();
sei(); //Enable interrupts
}
void out_debug(unsigned char output)
{
//Procedure to output byte to 'debug' port
PORTA = output;
}
void out(unsigned char output)
{
//Procedure to output byte to output port
PORTB = output;
}
unsigned char out_state(void)
{
//Procedure to get the current output state
return PORTB;
}
void init_usart(unsigned int baud)
{
// Setup serial I/O for communication
UBRRH = (unsigned char)(baud>>8);
UBRRL = (unsigned char)baud;
UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
UCSRC = (1 << URSEL) | (3 << UCSZ0);
}
SIGNAL (SIG_UART_RECV)
{
//USART RX interrupt service routine
switch(UDR)
{
case(CMD_PING):
txbyte(ACK_OK);
break;
case CMD_READ_EEPROM:
txbyte((unsigned char)eeprom_read_byte((uint8_t*)rxbyte()));
break;
case CMD_WRITE_EEPROM:
eeprom_write_byte ((uint8_t*)rxbyte(), (uint8_t)rxbyte());
txbyte(ACK_OK);
break;
default:
txbyte(ACK_ERROR);
break;
}
}
void init_io(void)
{
DDRB = 255; //Set PORTB for output (Relay Outputs)
DDRA = 255; //Set PORTA for output (Debug Output)
}
void txbyte(unsigned char data)
{
while ( !( UCSRA & (1<<UDRE)) ); //Wait for empty slot to send data
UDR = data; //Send it
}
unsigned char rxbyte (void)
{
while ( !(UCSRA & (1<<RXC)) ); //Wait until there is a byte to be read from RX buffer
return UDR; //Get it
}
And here's the VB6 app. Just make a textbox with the name txtMem, and the MSComm object with the name serial. Make two buttons, btnRead and btnWrite. Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Private Sub btnRead_Click() txtMem.Text = "" Dim i As Byte For i = 1 To getMem(0) txtMem.Text = txtMem.Text & Chr$(getMem(i)) Next End Sub Private Sub btnWrite_Click() writeMem 0, Chr$(Len(txtMem.Text)) delay Dim i As Byte For i = 1 To Len(txtMem.Text) writeMem i, Mid(txtMem.Text, i, 1) delay Next End Sub Sub Form_Load() serial.CommPort = 2 serial.InBufferSize = 1 serial.InputMode = comInputModeBinary serial.PortOpen = True End Sub Sub writeMem(ByVal byLoc As Byte, ByVal szData As String) serial.Output = Chr$(5) serial.Output = Chr$(byLoc) serial.Output = szData End Sub Function getMem(ByVal byLoc As Byte) As Byte serial.Output = Chr$(4) serial.Output = Chr$(byLoc) getMem = getByte End Function Private Function getByte() As Byte Sleep (10) 'Wait a bit for the microcontroller to get into the swing of things Dim byInData() As Byte Dim i As Byte byInData = serial.Input 'Get the COM port buffer into byte array If UBound(byInData) > -1 Then 'Check we actually have something in the buffer For i = 0 To UBound(byInData) getByte = byInData(i) Next Else getByte = 0 End If End Function Sub delay() Sleep (10) End Sub ![]() |
Online SoundCloud Downloader, NEW!Download tracks posted on SoundCloud for free in high-quality MP3! SoundScrape.netUseful eBay Links |