The last week has been very busy with non-project stuff, but I have managed to make progress on constructing some simple external hardware for the 68hc11 EVB to interface to. For most starter “microcontroller mucking about” projects, playing with a few LEDs is de riguer, and Evie Beer is no exception:
You can ignore the funny connector on the other end of the board, that is a topic for another time. Although, if you recognise the connector, you just might have a clue as to what else I will be getting up to this month.
Those pin-headers on the board are chopped-up IDE male-male gender-changers… which seemed like a good idea at the time, but when soldering to the underside pin, the plastic on the top of the board would melt and the pins fall out! Lacking any alternative, I had to resort to very-quick-and-hasty soldering. Talk about pressure!
I also spent rather too much time calculating resistor values, for sure, but needed to make sure that the loads on the 68hc11 MCU pins could never exceed 25mA, which is the Motorola documented “safe limit” for continuous operation – the pins, input-buffers and CMOS drivers will happily source or sink over 100mA per pin, but are heavily margined to allow for eg: automotive EMI, unintentional inductive coupling to vacuum-cleaner motors, and so on. At 25ma nominal, it is extremely unlikely that permanent damage to pins/drivers/buffers will occur.
A Shortcut that Went On Too Long
A while back, I saw an advert for some “LED with built-in series resistor”, and though that that would be a great way to save time, effort and brainpower. The LEDs sure work, tested with a 250mA 5V wall-wart power-supply (and no external resistors, you catch my drift?). Unfortunately, when designing a circuit-segment to limit the power-draw, you need to know the rated resistance of that hidden internal resistor, and the only specifications for these LEDs are:
- Maximum Forward Voltage: +7.5V
- Reverse Breakdown Voltage: -5V
- Forward Current at +5V: 10-15 mA
From Ohms laws, that means the resistance is anywhere between 500-333 Ohms; and the “illuminated” power-draw is 50-75mW per LED on my 5V circuit, crikey! Ouch!!! There is a 50% uncertainty on the current drawn (and therefore logically on the effective internal series resistance too). So the calculations had to be done using interval-arithmetic, to get the outer maximum/minimum results. Yep, results plural.
Why is power-draw so important anyway? Well, Motorola have never specified the maximum power that any of the 68hc11 MCUs can dissipate – they have formally specified the maximum that some models of the MCU chip itself is responsible for, in both single-chip (68HC11E1 = 139mW, 68HC11F1=150mW) and expended-mode operation, but have left designers and users to make a “wild finger in the air” guess as to how much externally-sourced/sunk peripheral power the MCU can dissipate. Apart from commercial embedded-systems manufacturers that were able to bulk-test 10s of thousands of units and apply statistical methods to the results, no-one actually knows.
Thus, allowing for 15mA for each of potentially 8 LEDs, together with all the other circuitry on my external board, seemed a little bit uncomfortable. So interval-arithmetic and testing was needed, to try and get the LED power-draw down without making the LEDs too dim. OK, so the results are in:
An additional 220 Ohm resistor drops the drawn current down to 7-9mA, whilst still keeping the LEDs reasonably bright. They are still really bright enough even with a 470 Ohm external resistor at 5-6mA – they are pretty darned good LEDs, but I have decided not to use these beasties again – fully separate resistors and plain-old LEDs actually is easier in the end!
Brute Force Animation
Next job was to get the LEDs driven from the 68hc11, controlled by a program. I had intended to use jumper-leads to connect the LED positive terminals to four of the 68hc11 Port B pins, and the common ground to the EVBU ground. Unfortunately, I needed female-to-female leads and I only have female-to-male. Darn! So the first piece of brute-forcing: use an old 50-pin SCSI cable as a gender-changer!
On the 68hc11, direct control of the on/off digital state of pins is easy: the 8 “Port B” pins are set/reset by writing an 8-bit mask to the on-board memory-mapped port B data register, ie: writing 0xff to address 0x1004 (the port B data register) would turn on all 8 port B pins, and so on, and so on. So a program to display a counter pattern would be something like:
ldab #0 # initialise counter (accumulator B) loop stab $1004 # store counter to port B data-register incb # increment counter <delay for a noticeable fraction of a second, somehow> jmp loop # go round again
Given that I only have 4 LEDs currently, I figured that connecting them to the high-order pins of port B would have them change only every 16 times round the loop, so could avoid the need to come up with a timed delay mechanism. However, with the 68hc11 running at 2MHz clock, even an “update only once-out-of-every-16” was still waaaaaaay to fast – the LEDs all just appear to be constantly on.
The BUFFALO ROM provides a user-callable routine to wait for an incoming character from the console terminal (at 1200 baud), store the ASCII code in accumulator A, then echo it back. I rather liked the idea of being able to step the program by typing on the keyboard, as that would allow me to check that the LEDs were really turning on and off, and in the expected sequence. Which gives the following program:
ldab #0 # initialise counter (accumulator B) loop stab $1004 # store counter to port B data-register incb # increment counter jsr $ffcd # call BUFFALO to wait for console keypress jmp loop # go round again
Well, this worked and proved the counter was incrementing and the writes to the port data register were really controlling the LEDs, but required a keypress for every change of LED state.
The lightbulb moment: the console terminal has an auto-repeat for keyboard keys, so I could convert that call to BUFFALO into a noticable delay instead – by using the utter brute force approach: wedge the console RETURN key down with a folded piece of paper…
And it worked beatifully. OK, so it’s not the “proper” way to do it, which would be to use the very flexible built-in timer system on the 68hc11, but I quite liked this solution – a quick, dirty, indirect hardware solution to a software problem.