Hi all,
Glad to have found this forum a little over a week ago. I've been referring to it frequently to help with writing my program, and found a lot of useful information in here. Thank you, contributing posters, for all the help you've already given me.
However, right now I'm stuck with another problem with my program, for which I've poured over the AT89S52 datasheet, Atmel 8051 Microcontrollers Hardware Manual, and Google results but so far to no avail.
I'm writing what should be a simple program. The program lights 30 LEDs with PWMs that updates each LED 30 times per second. Because each LED consists of a R, G, and B component, a total of 90 PWM output pins are necessary. I'm therefore using four AT89S52, with Port 0 being used with pull-ups/downs to distinguish among tasks assigned to the specific IC.
The basic algorithm is this:
(1) calculate (with the aid of a large look-up table) the amount of time that each color of each LED is to be lit during the next lighting; (2) turn on all colors of all LEDs (they're driven by a P-channel transistor); (3) start Timer 0 as 16-bit timer, to time 55,000 counts; (4) manually go through and check each LED's timing requirement against TH0 and TL0, and turn each one off as the Timer counts past it; (5) once all LEDs are turned off, jump back to (1).
The problem I'm running into is that during step (2), the ports do not turn on, and therefore the LEDs do not turn on. Just as a sanity check, I've put in a while(1){...} loop at the start of the program that turns on the LEDs on Port 1 and then switch them off one by one. This sanity checker uses the same syntax as that used by the later part of the program.
The sanity checker runs just fine when viewed under the oscilloscope. The real program, however, does not run properly, albeit compiling and logically functioning perfectly in the debugger.
Some things I've considered and tried but did not help:
(a) Program might be too large; however, I did not get the "auto segment too large" or any other similar-sounding errors; (b) Using Boolean to set the bits as well as directly assigning the desired value; (c) Setting the Code Optimization to 0: Constant folding; (d) Disabling the ALE (AUXR - 8Eh to 0x01); (e) Setting the ports using HEX values instead of #defined values; (f) Changing to a new AT89S52; (g) Checking for excessive noise on the connections; (h) Writing to the port twice in a row (different values, returning to 0x00), just to be sure;
... and a few other equally silly things that I nevertheless thought could've caused trouble.
The hardware is also excessively simple:
-> VCC and nEA/VPP to 5V (DC Source) -> GND to DC Source's GND -> ALE and nPSEN are NC -> XTAL1 & 2 are connected to a 24 MHz crystal with a pair of 30pF capacitors -> RST is connected to a floating wire that I use to touch 5V at the start for reset -> Port 1, bit 0 is connected to a P-channel transistor which is in turn connected to another voltage source and the Red component of an LED. -> Port 0 has 10K-Ohm pull-up resistors for chip identification. -> All remaining pins are port pins and have been left floating. They should be outputting, but are not.
Ports 0 and 2 have been observed under the oscilloscope to be actively switching, though judging by the pulse widths the activity has nothing to do with what the program intended.
I'm sure the solution is simple and obvious, but it is one that has so far eluded me. I was wondering if you gurus could please give me a hand here?
Because of the length of the code, I'm presenting a shortened version which I've compiled and run, with the exact same results. I've also marked out the sanity checker code that runs properly, as well as the tiny code block that doesn't seem to be doing what it's supposed to do.
Thanks in advance for any help you might have for me. The code will be included in the following post in response to this (since I've exceeded the message size limit).