Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
// ------------- READS51 generated header --------------
// module : serial.c
// created : 19:51:27, Monday, October 09, 2000
// Example routines for the textbook
// Programming and Interfacing the 8051 in C and Assembly
// by S. Yeralan and H. Emery
// (C) 2000, Rigel Press, www.rigelcorp.com
// -----------------------------------------------------
// build the library using the "Compile | Make Library" command.
// include <sio51.h> to projects, which are to be linked with
// this library
#include <sio51.h>
// -------------------------------------------------------------------
void InitSerialPort0(int nMode){
switch(nMode)
{
case _9600_11_059_TIMER1 : // 9600 Baud, 11.0592MHz, Timer 1
#asm
mov tmod, #20h ; set counter 1 for auto reload - mode 2
mov tcon, #41h ; run coutnter 1 and set edge trig ints
mov th1, #0fdh ; set counter 1 for 4800 baud with xtal=11.0592mhz
mov scon, #50h ; set serial control reg for 8 bit data and mode 1
#endasm
break;
case _9600_24_TIMER1 : // 9600 Baud, 24.0MHz, Timer 1
#asm
mov tmod, #20h ; set counter 1 for auto reload - mode 2
mov tcon, #41h ; run coutnter 1 and set edge trig ints
mov th1, #0f3h ; set counter 1 for 4800 baud with xtal=11.0592mhz
mov scon, #50h ; set serial control reg for 8 bit data and mode 1
mov pcon, #80h ; set the double baud ratebit
#endasm
break;
case _9600_12_80535BRG : // 9600 Baud, 12.0MHz, 80535 internal BRG
#asm
setb 0DFh ; (0xDF=bd) enable internal baud rate generator
mov scon, #50h ; set serial control reg for 8 bit data and mode 1
mov 87h, #80h ; set double baud rate bit
#endasm
break;
case _9600_10_C515BRG : // 9600 Baud, 10.0MHz, C515C internal BRG
#asm
#define SRELL 0x0AA
#define SRELH 0x0BA
#define BD 0x0DF ; internal baud rate enable
setb BD ; enable internal baud rate generator
mov SRELL, #0BFh
mov SRELH, #3
mov scon, #50h ; set serial control reg for 8 bit data and mode 1
mov 87h, #80h ; set double baud rate bit
#endasm
break;
}
}
// -------------------------------------------------------------------
void putc(char c){
#asm
mov a, BPL
add a, #0xFA
mov dpl, a
mov a, BPH
addc a, #0xFF
mov dph, a
movx a, @dptr
clr ti
mov sbuf, a
jnb ti, $
clr ti
#endasm
}
void puts(char *sz){
while(*sz) putc(*sz++);
}
// -------------------------------------------------------------------
void PrtHexDigit(unsigned int uNum){
uNum &= 0xF;
if(uNum<10) putc('0'+uNum);
else putc('A'+uNum-10);
}
void PrtHex(unsigned int uNum){
PrtHexDigit((uNum&0xF000)>>12);
PrtHexDigit((uNum&0x0F00)>>8);
PrtHexDigit((uNum&0x00F0)>>4);
PrtHexDigit(uNum);
}
// -------------------------------------------------------------------
void PrtDec(int n){
int nDigit;
if(n<0)
{
putc('-');
n=-n;
}
nDigit=n/10000;
putc(nDigit+'0');
n-=nDigit*10000;
nDigit=n/1000;
putc(nDigit+'0');
n-=nDigit*1000;
nDigit=n/100;
putc(nDigit+'0');
n-=nDigit*100;
nDigit=n/10;
putc(nDigit+'0');
n-=nDigit*10;
putc(n+'0');
}
// -------------------------------------------------------------------
void printf(char *sz){
int n, *pnArg;
char c;
pnArg=(&sz)-2; // note : C argument ordering
c=*sz;
sz++;
while(c)
{
if(c=='%')
{
c=*sz;
sz++;
switch(c)
{
case 'c': putc(*pnArg);
pnArg--;
break;
case 's': puts(*pnArg);
pnArg--;
break;
case 'd': n=*pnArg;
pnArg--;
PrtDec;
break;
// case 'b': break; // binary
// case 'o': break; // octal
// case 'u': break; // unsigned decimal
case 'x': n=*pnArg;
pnArg--;
PrtHex;
break;
}
}
else putc(c);
c=*sz++;
}
}
// -------------------------------------------------------------------
char getc(void){
#asm
jnb ri, $
clr ri
mov PRL, sbuf
mov PRH, #0
#endasm
}
// -------------------------------------------------------------------
;#INCLUDE "8051EQU.INC"
; RESET ;reset routine
.ORG 0H ;locate routine at 00H
AJMP START ;jump to START
;
;**************************************************************************
;
; INTERRUPTS (not used) ;place interrupt routines at appropriate
;memory locations
.ORG 03H ;external interrupt 0
RETI
.ORG 0BH ;timer 0 interrupt
RETI
.ORG 13H ;external interrupt 1
RETI
.ORG 1BH ;timer 1 interrupt
RETI
.ORG 23H ;serial port interrupt
RETI
.ORG 25H ;locate beginning of rest of program
;
;**************************************************************************
;
INITIALIZE: ;set up control registers
;
MOV TCON,#00H
MOV TMOD,#00H
MOV PSW,#00H
MOV IE,#00H ;disable interrupts
RET
;
;**************************************************************************
;
; Real code starts below. The first two routines are for delays so we
; can slow down the blinking so we can see it. (Without a delay, it
; would blink so fast it would look like it was always on.
;
;**************************************************************************
;
DELAYMS: ;millisecond delay routine
; ;
MOV R7,#00H ;put value of 0 in register R7
LOOPA:
INC R7 ;increase R7 by one (R7 = R7 +1)
MOV A,R7 ;move value in R7 to Accumlator (also known as A)
CJNE A,#0FFH,LOOPA ;compare A to FF hex (256). If not equal go to LOOPA
RET ;return to the point that this routine was called from
;
;**************************************************************************
;
DELAYHS: ;half second delay above millisecond delay
; ;
MOV R6,#00H ;put 0 in register R6 (R6 = 0)
MOV R5,#002H ;put 2 in register R5 (R5 = 2)
LOOPB:
INC R6 ;increase R6 by one (R6 = R6 +1)
ACALL DELAYMS ;call the routine above. It will run and return to here.
MOV A,R6 ;move value in R6 to A
JNZ LOOPB ;if A is not 0, go to LOOPB
DEC R5 ;decrease R5 by one. (R5 = R5 -1)
MOV A,R5 ;move value in R5 to A
JNZ LOOPB ;if A is not 0 then go to LOOPB.
RET
;
;**************************************************************************
;
START: ;main program (on power up, program starts at this point)
ACALL INITIALIZE ;set up control registers
LOOP:
CPL P1.0 ;ComPLement (invert) P1.0 (this makes LED change)
ACALL DELAYHS ;go to above routine that causes a delay
AJMP LOOP ;go to LOOP(always jump back to point labeled LOOP)
.END ;end program