AVR Debugger
History
The fact is, 10 years ago this
project could have been completed. It will be a useful tool to help
you debug code. The challenge was to make a debugger that does not
require any MCU resources to be used from the MCU, allowing the
debugger to run integrated with the code being debugged. The
Debugger only use 1 I/O pin, and is connected to a serial port from
the host PC. Using a VT100 terminal to capture the output from the
Debug tool, all of the debug information can be captured. By adding
a simple command along with the debug firmware, you can send out
debug statements like debugXY(x,y, "test"). The Debugger will adapt
to any speed from 1Mhz to 20Mhz without configuration from the user.
Features Ver : 1.0
|
|
No resource need in the MCU you are debugging |
|
|
No configuration to do |
|
|
Run with MCU from 1Mhz to 20Mhz |
|
|
Use VT100 terminal emulator as debugging window |
|
|
Self powered by the serial port of your PC |
|
|
Simple to build |
|
|
Convert any I/O in a verbose debugger |
|
|
Reset button |
System Requirements
|
|
Terminal software |
|
|
Debugging circuit with the HEX file of the debugger |
|
|
PC free serial port |
History
| V1.0 | First Release! |
Picture

Schematic, PCB, Code, Hex File
\Code in the debugger ATMega162
//*****************************************************************************
// AVR Debuger
// Version 1.0 Fev 2007
//
// Sylvain Bissonnette
//*****************************************************************************
// Editor : UltraEdit32
//*****************************************************************************
//
// R E T U R N S T A C K 1 6
//
//*****************************************************************************
// I N C L U D E
//*****************************************************************************
#include <iom162v.h>
#include <macros.h>
#include <shortnametype.h>
//*****************************************************************************
// D E F I N E
//*****************************************************************************
#define XTAL 8000000
#define FALSE 0
#define TRUE 1
#define DEBUG_DDR DDRD
#define DEBUG_PORT PORTD
#define DEBUG_BIT 0x08
#define DEBUG_UCSRA UCSR0A
#define DEBUG_UCSRB UCSR0B
#define DEBUG_UCSRC UCSR0C
#define DEBUG_UDR UDR0
#define DEBUG_UBRRH UBRR0H
#define DEBUG_UBRRL UBRR0L
#define TERM_UCSRA UCSR1A
#define TERM_UCSRB UCSR1B
#define TERM_UCSRC UCSR1C
#define TERM_UDR UDR1
#define TERM_UBRRH UBRR1H
#define TERM_UBRRL UBRR1L
#define TERM_SPEED 19200
#define TERM_TXBUFFER 80
#define LED_OK 0x01
#define LED_ERROR 0x02
#define LED_GOOD 0x04
#define LED_DDR DDRA
#define LED_PORT PORTA
//*****************************************************************************
// P R O T O T Y P E
//*****************************************************************************
void main(void);
void Delay(void);
// Term
void TermInit(void);
void TermTxChar(char ch);
void TermTxFlush(void);
void TermTxInt(void);
void TermConstXY(ushort x, ushort y, const char *Ptr);
void TermXY(ushort x, ushort y, char *Ptr);
void TermConstString(const char *ptr);
void TermString(char *ptr);
// Debuger
void DebugInit(void);
void Debuger_RxInt(void);
//*****************************************************************************
// G L O B A L V A R I A B L E
//*****************************************************************************
// Term
char TermTxBuffer[TERM_TXBUFFER];
char *TermTxFill;
char *TermTxFree;
uint TermTxBufferChar;
char Text[512];
//*****************************************************************************
// M A I N
//*****************************************************************************
void main()
{
ushort i;
SEI();
TermInit();
TermConstXY(24,03," A V V R R R \0");
TermConstXY(24,04," A A V V R R \0");
TermConstXY(24,05," A A V V R R R \0");
TermConstXY(24,06," A A A A V V R R \0");
TermConstXY(24,07,"A A V R R \0");
TermConstXY(6,10,"D D D E E E E B B B U U G G G G G G E E E E R R R \0");
TermConstXY(6,11,"D D E B B U U G G E R R \0");
TermConstXY(6,12,"D D E E E B B U U G G G G G G E E E R R R \0");
TermConstXY(6,13,"D D E B B U U G G G G E R R \0");
TermConstXY(6,14,"D D D E E E E B B B U U U G G G G G G E E E E R R\0");
TermConstXY(35,20,"V : 1 . 0\0");
TermConstXY(23,21,"S y l v a i n B i s s o n n e t t e\0");
for (i=0;i<68;i++)
{
TermConstXY(6+i,17,"*\0");
Delay();
TermConstXY(6+i-1,17," \0");
Delay();
}
TermConstXY(0,0," \0");
DebugInit();
while(1);
}
/******************************************************************************
Name: void Delay(void)
Description: Delay
Input: none
Output: none
Misc:
******************************************************************************/
void Delay(void)
{
uint i,j;
for (i=0;i<30000;i++);
}
/******************************************************************************
Name: void DebugInit(void)
Description: Setup the serial port
Input: none
Output: none
Misc:
******************************************************************************/
void DebugInit(void)
{
DEBUG_UCSRB = (1<<RXEN0) + (1<<TXEN0) + (1<<RXCIE0);
DEBUG_UCSRC = (1<<URSEL0) + (1<<UCSZ01) + (1<<UCSZ00) + (1<<UPM01);
DEBUG_UBRRH = 0;
DEBUG_UBRRL = 0;
}
/******************************************************************************
Name: void Debuger_RxInt(void)
Description: Interrupt from RX of the Debuger Port
Input: none
Output: none
Misc:
******************************************************************************/
#pragma interrupt_handler Debuger_RxInt:iv_USART0_RXC
void Debuger_RxInt(void)
{
char Ch;
static ushort Lock = TRUE;
static ushort LockCounter;
if ((DEBUG_UCSRA & (1<<FE0)) || (DEBUG_UCSRA & (1<<DOR0)) || (DEBUG_UCSRA & (1<<UPE0)))
{
Ch = DEBUG_UDR;
DEBUG_UBRRL++;
}
else
{
Ch = DEBUG_UDR;
if (Ch < 0x7f) TermTxChar(Ch);
}
}
/******************************************************************************
Name: void TermInit(void)
Description: Setup the serial port
Input: none
Output: none
Misc:
******************************************************************************/
void TermInit(void)
{
char Buffer[10];
TermTxFlush();
TERM_UBRRH = ((XTAL / (16 * TERM_SPEED)) - 1)>>8;
TERM_UBRRL = (XTAL / (16 * TERM_SPEED)) - 1;
TERM_UCSRA = 0x00;
TERM_UCSRB = (1<<TXEN0) + (1<<UDRIE0);
TERM_UCSRC = (1<<URSEL0) + (1<<UCSZ11) + (1<<UCSZ10);
TermConstXY(0,0,"\0");
}
/******************************************************************************
Name: void TermConstXY(ushort x, ushort y, const char *Ptr)
Description:
Input: ushort x -> X position to print on the termnal
ushort y -> Y position to print on the termnal
const char *Ptr-> Pointer of string to be print on the terminal
Output: none
Misc:
******************************************************************************/
void TermConstXY(ushort x, ushort y, const char *Ptr)
{
char Buffer[10];
if ((x == 0) && (y == 0))
{
Buffer[0] = 0x1b;
Buffer[1] = '[';
Buffer[2] = '2';
Buffer[3] = 'J';
Buffer[4] = 0x00;
TermString(&Buffer[0]);
Buffer[0] = 0x1b;
Buffer[1] = '[';
Buffer[2] = '1';
Buffer[3] = ';';
Buffer[4] = '1';
Buffer[5] = 'H';
Buffer[6] = 0x00;
TermString(&Buffer[0]);
}
else
{
Buffer[0] = 0x1b;
Buffer[1] = '[';
Buffer[2] = (y/10)+48;
Buffer[3] = (y%10)+48;
Buffer[4] = ';';
Buffer[5] = (x/10)+48;
Buffer[6] = (x%10)+48;
Buffer[7] = 'f';
Buffer[8] = 0x00;
TermString(&Buffer[0]);
TermConstString(Ptr);
}
}
/******************************************************************************
Name: void TermXY(ushort x, ushort y, char *Ptr)
Description:
Input: ushort x -> X position to print on the termnal
ushort y -> Y position to print on the termnal
char *Ptr-> Pointer of string to be print on the terminal
Output: none
Misc:
******************************************************************************/
void TermXY(ushort x, ushort y, char *Ptr)
{
char Buffer[10];
if ((x == 0) && (y == 0))
{
Buffer[0] = 0x1b;
Buffer[1] = '[';
Buffer[2] = '2';
Buffer[3] = 'J';
Buffer[4] = 0x00;
TermString(&Buffer[0]);
Buffer[0] = 0x1b;
Buffer[1] = '[';
Buffer[2] = '1';
Buffer[3] = ';';
Buffer[4] = '1';
Buffer[5] = 'H';
Buffer[6] = 0x00;
TermString(&Buffer[0]);
}
else
{
Buffer[0] = 0x1b;
Buffer[1] = '[';
Buffer[2] = (y/10)+48;
Buffer[3] = (y%10)+48;
Buffer[4] = ';';
Buffer[5] = (x/10)+48;
Buffer[6] = (x%10)+48;
Buffer[7] = 'f';
Buffer[8] = 0x00;
TermString(&Buffer[0]);
TermString(Ptr);
}
}
/******************************************************************************
Name: void TermConstString(const char *ptr)
Description: Send a constant string the serial port
Input: String Pointer
Output: none
Misc:
******************************************************************************/
void TermConstString(const char *ptr)
{
while(*ptr != 0x00)
{
TermTxChar(*ptr++);
}
}
/******************************************************************************
Name: void TermString(char *ptr)
Description: Send a string the serial port
Input: String Pointer
Output: none
Misc:
******************************************************************************/
void TermString(char *ptr)
{
while(*ptr != 0x00)
{
TermTxChar(*ptr++);
}
}
/******************************************************************************
Name: void Term_TxChar(ushort)
Description: Send a char on the serial port
Input: char
Output: none
Misc:
******************************************************************************/
void TermTxChar(char ch)
{
while(TermTxBufferChar > TERM_TXBUFFER - 2) WDR();
*TermTxFill++ = ch;
if (TermTxFill == &TermTxBuffer[TERM_TXBUFFER]) TermTxFill = &TermTxBuffer[0];
TermTxBufferChar++;
TERM_UCSRB |= (1<<UDRIE0);
}
/******************************************************************************
Name: int Term_TxFlush
Description: This function flush all the Tx buffer
Input: none
Output: none
Misc:
******************************************************************************/
void TermTxFlush()
{
TermTxFill = &TermTxBuffer[0];
TermTxFree = &TermTxBuffer[0];
TermTxBufferChar = 0;
}
/******************************************************************************
Name: void Term_TxInt(void)
Description: This function is automaticaly when the UDR buffer is empty
Input: none
Output:
Misc:
******************************************************************************/
#pragma interrupt_handler Term_TxInt:iv_USART1_UDRE
void Term_TxInt(void)
{
if (TermTxBufferChar)
{
TERM_UDR = *TermTxFree++;
if (TermTxFree == &TermTxBuffer[TERM_TXBUFFER]) TermTxFree = &TermTxBuffer[0];
TermTxBufferChar--;
}
else TERM_UCSRB &= ~(1<<UDRIE0); /* TX int empty disable */
}
\Code in the target to debug
//*****************************************************************************
// AVR Debuger
// Version 1.0 Fev 2007
//
// Sylvain Bissonnette
//*****************************************************************************
// Editor : UltraEdit32
//*****************************************************************************
//
//
R E T U R N S T A C K 1 6
//
//*****************************************************************************
//
I N C L U D E
//*****************************************************************************
#include <io2313v.h>
#include <macros.h>
#include <shortnametype.h>
//*****************************************************************************
//
D E F I N E
//*****************************************************************************
#define DEBUG_XTAL
16000000
#define DEBUG_DDR
DDRD
#define DEBUG_PORT
PORTD
#define DEBUG_BIT
0x01
//*****************************************************************************
//
P R O T O T Y P E
//*****************************************************************************
void main(void);
void DebugXY(ushort
x, ushort y,
char *Ptr);
void Debug(char
*Ptr);
void DebugInit();
//*****************************************************************************
//
G L O B A L V A R I A B L E
//*****************************************************************************
char Text[30];
//*****************************************************************************
//
M A I N
//*****************************************************************************
void main()
{
uint i;
Text[0]
= 'x';
Text[1]
= 'X';
Text[2]
= 'x';
Text[3]
= 'X';
Text[4]
= 'x';
Text[5]
= 'x';
Text[6]
= 'X';
Text[7]
= 'x';
Text[8]
= 'X';
Text[9]
= 'x';
Text[10]
= 0x00;
DebugInit();
while(1)
{
DebugXY(19,19,&Text[0]);
for (i=0;i<60000;i++)
WDR();
DebugXY(0,0,&Text[0]);
}
}
/******************************************************************************
Name:
void DebugXY(ushort x, ushort y, char *Ptr)
Description:
Input:
ushort x -> X position to print on the termnal
ushort y -> Y position to print on the termnal
char *Ptr-> Pointer of string to be print on the terminal
Output:
none
Misc:
168 Byte
******************************************************************************/
void DebugXY(ushort
x, ushort y,
char *Ptr)
{
char Buffer[10];
if ((x ==
0) && (y
== 0))
{
Buffer[0]
= 0x1b;
Buffer[1]
= '[';
Buffer[2]
= '2';
Buffer[3]
= 'J';
Buffer[4]
= 0x00;
Debug(&Buffer[0]);
Buffer[0]
= 0x1b;
Buffer[1]
= '[';
Buffer[2]
= '1';
Buffer[3]
= ';';
Buffer[4]
= '1';
Buffer[5]
= 'H';
Buffer[6]
= 0x00;
Debug(&Buffer[0]);
}
else
{
Buffer[0]
= 0x1b;
Buffer[1]
= '[';
Buffer[2]
= (y/10)+48;
Buffer[3]
= (y%10)+48;
Buffer[4]
= ';';
Buffer[5]
= (x/10)+48;
Buffer[6]
= (x%10)+48;
Buffer[7]
= 'f';
Buffer[8]
= 0x00;
Debug(&Buffer[0]);
Debug(Ptr);
}
}
/******************************************************************************
Name:
void Debug(char *Ptr)
Description: *char Char to be
print
Input:
char *Ptr
Output:
none
Misc:
150 Byte
******************************************************************************/
void Debug(char
*Ptr)
{
#define MINDELAY 75
int i,j,Parity;
while(*Ptr
!= 0)
{
CLI();
DEBUG_PORT &= ~DEBUG_BIT;
for (j=0;j<MINDELAY;j++);
// Start Bit
Parity =
0;
for (i=0;i<8;i++)
// All 8 Bits
{
if
(*Ptr & (0x01<<i))
{
Parity++;
DEBUG_PORT
|= DEBUG_BIT;
for (j=0;j<MINDELAY;j++);
}
else
{
DEBUG_PORT
&= ~DEBUG_BIT;
for (j=0;j<MINDELAY;j++);
}
}
if (Parity%2)
{
DEBUG_PORT
|= DEBUG_BIT;
for (j=0;j<MINDELAY;j++);
}
else
{
DEBUG_PORT
&= ~DEBUG_BIT;
for (j=0;j<MINDELAY;j++);
}
DEBUG_PORT |=
DEBUG_BIT;
for (j=0;j<MINDELAY*200;j++);
// Stop Bit
SEI();
Ptr++;
}
}
/******************************************************************************
Name:
void DebugInit()
Description:
Input:
Output:
none
Misc:
******************************************************************************/
void DebugInit()
{
uint i;
char Buffer[2];
DEBUG_DDR |= DEBUG_BIT;
DEBUG_PORT |= DEBUG_BIT;
Buffer[0]
= 0x55;
Buffer[1]
= 0x00;
for (i=0;i<255;i++)
Debug(&Buffer[0]);
DebugXY(0,0,&Text[0]);
}