Maker Pro
Maker Pro

Suggestions to tighten novice 8051 code

J

Jacob Burnetski

Jan 1, 1970
0
I recently got involved with the 8051 and a devlopment board and have
been writing some simple programs to get used to the code and
hardware. The last one that I wrote was a practice problem in the
manual that came with the board. The task was to use an on-board
potentiometer to increase/decrease the speed of an LED array, as well
as make the 2 PWMs complement each other.

My code is at the end. It works, but I'd like to know what the
veterans might have done to tighten it up and make it better? Right
now it takes a second or so to update, and I'd like it to be more
realtime. Any suggestions/tips/comments would be appreciated.

Thanks.

----- start code -----

mov pwmp, #20 ; set frequency of pwm
mov p1, #1 ; turn LED 0 on at the start

START:
acall delay ; call the delay loop straight away
mov a, p1 ; move the current LED status into the
; accumulator

rl a ; rotate the LED position one place to
; the left.

mov p1, a ; light the new LED position
sjmp start ; restart the program

DELAY:
mov adcon, #08h ; turn on the a/d converter
adc: mov b, adcon ; put the a/d status in the b register
jnb b.4, adc ; check to see when the adc has been
; read

mov pwm0, adch ; move the adc value into the pwm0 to control
; duty cycle

mov a, adch ; move the adc value into the
; accumulator

cpl a ; complement the accumulator
mov pwm1, a ; move the complemented adc value into
; the pwm1 register

mov r0, #10 ; set 10 in the register for delay

loop: mov th0, adch ; set the high time of the timer to
; the adc value

mov tl0, adch ; set the low time of the timer to the
; adc value

setb tr0 ; start the timer
time: jnb tf0, time ; wait for the timer to expire
clr tr0 ; clear the timer register
clr tf0 ; clear the timer flag
djnz r0, loop ; loop 10 times for visible rate
ret ; return to the main program
 
R

Robert Baer

Jan 1, 1970
0
Jacob said:
I recently got involved with the 8051 and a devlopment board and have
been writing some simple programs to get used to the code and
hardware. The last one that I wrote was a practice problem in the
manual that came with the board. The task was to use an on-board
potentiometer to increase/decrease the speed of an LED array, as well
as make the 2 PWMs complement each other.

My code is at the end. It works, but I'd like to know what the
veterans might have done to tighten it up and make it better? Right
now it takes a second or so to update, and I'd like it to be more
realtime. Any suggestions/tips/comments would be appreciated.

Thanks.

----- start code -----

mov pwmp, #20 ; set frequency of pwm
mov p1, #1 ; turn LED 0 on at the start

START:
acall delay ; call the delay loop straight away
mov a, p1 ; move the current LED status into the
; accumulator

rl a ; rotate the LED position one place to
; the left.

mov p1, a ; light the new LED position
sjmp start ; restart the program

DELAY:
mov adcon, #08h ; turn on the a/d converter
adc: mov b, adcon ; put the a/d status in the b register
jnb b.4, adc ; check to see when the adc has been
; read

mov pwm0, adch ; move the adc value into the pwm0 to control
; duty cycle

mov a, adch ; move the adc value into the
; accumulator

cpl a ; complement the accumulator
mov pwm1, a ; move the complemented adc value into
; the pwm1 register

mov r0, #10 ; set 10 in the register for delay

loop: mov th0, adch ; set the high time of the timer to
; the adc value

mov tl0, adch ; set the low time of the timer to the
; adc value

setb tr0 ; start the timer
time: jnb tf0, time ; wait for the timer to expire
clr tr0 ; clear the timer register
clr tf0 ; clear the timer flag
djnz r0, loop ; loop 10 times for visible rate
ret ; return to the main program

Why sit around in that count loop, doing almost nothing?
Look into interrupts: start a timer that kicks an interrupt - that
way, you can have the micro doing other work while the timer runs down.
 
G

gary drummond

Jan 1, 1970
0
Robert said:
Why sit around in that count loop, doing almost nothing?
Look into interrupts: start a timer that kicks an interrupt - that
way, you can have the micro doing other work while the timer runs down.

I have some sample (quick-and-dirty) timer/int code here (Assembler)
http://www.gbronline.com/gdrumm/8051downloads.htm/plac.asm
which resolves to 1ms idle (sleep) times. The rest of the timer code
just keeps a "clock" and was part of a realtime clock routine I had in a
terminal
program, but it does show how to get different scales of delay times,
with software, and spends most of its time in idle mode-when not doing
anything. (The 9V battery in the plac lasts about 1-1.5 years, depending
on how often it's used. :<)

It would be easy to add a timer int to replace (some of) your code,
and then play with adding a second calculated timer (software, as in
the 1/4 second or second counters in my plac.asm) to handle other
delays...

In my terminal program, I had a timer keeping a clock in 20ms resolution.
all the int routine did was update the time-tick count and a flag bit. The
main
routine kept checking for the flags set by the timer, comm, and other
routines,
to perform the highest priority task on the list of flagged tasks.

Some things I timed were:
Update LCD display if data available, and not locked~50 char/sec
Scan keyboard keys-
debounce time
pressed time
release time
rollover time
Repeat keystroke timer
"Beep" timer (Bel character)

Some routines needed to be single thread (don't call by software AND
and int routines at the same time), so I made a software queue for the
hardware and software to store requests in, and called the processing
routine from both, after checking for it being used by another "thread".

Some things were timed with software, like yours.
The 'Break" key was done in software (1.5 bits@19200baud=7.8us).
LCD control signals that were fast response type were loops.
Longer times were handled by "saving" a counter (ms|100ms|1/4sec|...)
and flagging something to be done. Each time it was "called" by main,
I compared the saved (well, computed...) count I was waiting for, from
the current count, and then finished what I was waiting for...

As was stated in the post I responded to, interrupts are a big key in
keeping things going, without spinning your wheels in processor loops,
or if nothing is happening-go to sleep and save battery power...

If you are going to use ASM for things, you might want to look at
my macro.src on the same page. It adds a few handy "instructions"
and "case" staements to ASM (ML-ASM).


Gary
 
G

gary drummond

Jan 1, 1970
0
Sorry about that, I should have just pointed to the page.
If you don't have .asm or .src set up as types for an editor, you will need to

download it to look at it in notepad or wordpad.

I'll change the types to .txt my next update of the web pages.

The page is:
http://www.gbronline.com/gdrumm/8051downloads.htm

Gary

PS-I'll be on another ISP starting Sat. I'll still have this group, but my
email
will be changed to gbronline.com (1.4GB of spam and virus messages is
too much each month...)
 
Top