All, I'm a newbie to SDCC.  So, I'm not sure if I'm asking for help in the proper way.  If I am, sorry.

Thanks for any suggestions you may have!!






I've been working on converting a simple C program and compiling it using SDCC instead of Keil C. The program uses the AT89C51 watchdog timer, the serial port, and blinks an LED. When compiled using Keil, the program works perfectly. The program simply outputs 21 exes ('X') in response to receiving a 'D' from a notebook PC. To compile the program using SDCC, I first converted the AT89C51xDS header file from Atmel so that sfr and sbit lines had the correct syntax. I also toggled the the LED bit using ! rather than ~. Finally, I used packihx to create the hex file. 
 
The program responds to receiving a 'D' from the notebook PC, but it only transmits 8 characters instead of 21. 
 
Any suggestions? Thanks for your help in advance!! 
 
With apologies for the clutter, I've attached the code below: 
 
 
#define UART_TXD_DELAY_COUNT 10 // transmit delay cnt => 40*6/30MHz = 8mics/cnt for 115200 bps 
#define UNIT_TIMER_RELOAD 0x06 //250 mac. cycles/super timer cnt or 50mics res. at 30MHz 
 
#define MAX_WAIT 4400 //4400*50mics=220ms conversion time at 30 mHz 
 
#define LED0_PORT_BIT P2_0 // setup/power and while(1) loop cycle flip-flop LED 
 
 
#define WATCHDOG_ON // comment this line out to turn off watchdog timer for debugging 
 
 
#include "AT89C51xD2SDCC.h" // From Atmel: definition for the register names of the AT89C51xD2 chips 
 
 
 
 
 
unsigned long data g_ul_clock_count=0; 
 
unsigned long data main_clock_count=0; 
 
 
// Interrupt Vectors and Interrupt Support Functions 
 
// timer 0 super clock count interrupt routine 
void timer_0_interrupt(void) interrupt 1 using 3 

TF0=0; // reset interrupt flag 
if(!(~(((unsigned char data *)(&g_ul_clock_count))[3]))) 
if(!(~(((unsigned char data *)(&g_ul_clock_count))[2]))) 
if(!(~(((unsigned char data *)(&g_ul_clock_count))[1]))) 
if(!(~(((unsigned char data *)(&g_ul_clock_count))[0]))) g_ul_clock_count=0; 
g_ul_clock_count++; 

 
// UART Serial Port Interrupt 4 Function (input: RxD)(output: TxD) 
// with SBUF (serial port) array output (256 bytes max) for interrupt 4 
void UART_interrupt(void) interrupt 4 using 2 

unsigned char UART_data=0; 
unsigned char array_index=0; 
unsigned long delay_index=0; 
 
if(RI==1) // if reception occurs 

RI=0; // clear reception flag for next reception 
UART_data=SBUF; // read receive data 
if(UART_data=='D') 

for(array_index=0; array_index<=20; array_index++) 

SBUF='X'; // send each byte to UART 
delay_index=0; 
while(delay_index<UART_TXD_DELAY_COUNT) delay_index++; 


 
} else TI=0; // if emission occurs, clear emission flag for next emission 
#ifdef WATCHDOG_ON 
WDTRST=0x1E; // reset watchdog sequence 
WDTRST=0xE1; // reset watchdog sequence 
#endif 

 
 
// Initialize relevant system devices and defaults 
void setup_ThermoMIC(void) 

// CPU Clock in X2 mode (peripherals are also at X2 or 6 clocks per mac. cyc.) 
CKCON0|=0x01; 
 
// UART settings using the internal baud rate generator 
PCON|=0x80; // SMOD1=1, selects double baud rate mode for UART in mode 1,2,3 
SCON=0x50; // UART in mode 1 (8-bit), REN=1 
BDRCON&=0xEC; // BRR=0, SRC=0 
BDRCON|=0x0E; // TBCK=1, RBCK=1, SPD=1 
BRL=0xF0; // 115200 bps at 30MHz in X2 mode 
 
// Watchdog time-out setup 
// For mode X1: 12 clock periods per machine cycle 
// For mode X2: 6 clock periods per machine cycle 
WDTPRG|=0x07; // (2^(14+0x07)-1) machine cycles [0x07=MAX] or 0.419s @ Fosc=30MHz & X2 
 
// setup timer 0 in mode 2 with auto-reload & software gate 
// to create a 100 microsec unit time count 
TMOD&=0xF0; // timer 0 mode 2 with software gate 
TMOD|=0x02; // GATE0=0, C/T0#=0, M10=1, M00=0 
TH0=UNIT_TIMER_RELOAD; // reload value 
TL0=UNIT_TIMER_RELOAD; // init value 
IPL0|=0x02; // set timer 0 interrupt priority to 3 (highest) 
IPH0|=0x02; // set timer 0 interrupt priority to 3 (highest) 
 
 
// after setups are done then enable interrupts and start peripherals 
ES=1; // enable UART serial port interrupt 
ET0=1; // enable timer 0 interrupt 
EA=1; // enable all interrupts (global mask) 
TR0=1; // run timer 0 
SPCON|=0x40; // run SPI 
BDRCON|=0x10; // run internal baud rate generator 

 
// watchdog restart sequence 
void restart_watchdog(void) 

#ifdef WATCHDOG_ON 
WDTRST=0x1E; 
WDTRST=0xE1; 
#endif 

 
// superclock count reset 
void reset_superclock(void) 

ET0=0; // disable timer 0 interrupt 
g_ul_clock_count=0; 
ET0=1; // enable timer 0 interrupt 

 
 
 
// reset program clock count vars 
void reset_clock_counts(void) 

main_clock_count=0; 

 
 
 
 
/////////////////////////////////////////////////////////////////////////////// 
// Main entry point of looping controller program 
 
void main(void) 

unsigned char indexer=0; 
unsigned char check_flag=0; 
 
// setup functions 
setup_ThermoMIC(); 
reset_superclock(); 
restart_watchdog(); 
LED0_PORT_BIT=~1; 
 
 
// primary loop 
while(g_ul_clock_count<main_clock_count) { restart_watchdog(); } // wait if early 
main_clock_count=g_ul_clock_count+MAX_WAIT; 
while(1) 

LED0_PORT_BIT=!LED0_PORT_BIT; 
 
 
if(g_ul_clock_count>0x7FFFFFFF) 

reset_superclock(); 
reset_clock_counts(); 

 
while(g_ul_clock_count<main_clock_count) { restart_watchdog(); } // wait if early 
main_clock_count=g_ul_clock_count+MAX_WAIT; 


 




























Gary D. Sides, Ph.D.
Phone:  205-307-6695          Cell:  205-222-2757
gary.sides@gastechnology.org