I'm trying to realise 2 separate PWMs using a AT89S8253 on the Esay8051b by triggering on overflows of timer 0 and 1 (timer 2 is in use for serial communication).
The oscillator crystal is 8MHz. From what I can make of the datasheet for the microcontroller, 1 machine cycle takes 12 oscillator periods to execute. This would mean that @8MHz: 1 machine cycle = 1/8000000 * 12 = 1,5µs.
If I connect an oscilloscope to the output pin, the signal appears completely wrong (much too long, by a factor 40 or so).
This is the code I use for the interrupt routine:
Code: Select all
void puls_Y() org 0x1B ilevel 2
{
yval = -916 - ((yvalue*166)>>8);
if(t1out)
yval = -4000;
TR1 = 0;
TL1 = yval & 0xFF;
TH1 = yval >> 8;
TR1 = 1;
t1out = ~t1out;
}
The timer is used to drive a servo through the output pin t1out. I (try to) send a pulse between 1375µs (916 machine cycles @ 1,5µs / cycle) and 1625µs by adding a one-byte variable to the 916 value.
This calculation is theoretically sound. The 4000 serves to generate a longer low level.
In practice the timing appears to be a disaster. I've tried counting instructions to realise delays but due to the timing error this appears impossible.
Note1: I haven't tested serial communication yet, but I suspect it will not work, because of the same timing issue (edit: serial doesn't work, probably because of the timing).
Note2: I have a graphical LCD attached, though I can't imagine why this might be a problem
Note3: I tried using the delay_us() function but this seems to suffer from the same timing error; delay_ms() seems to work fine (not verified to the millisecond, but delay_ms(2000) gives what appears to be a 2 second delay)