assemblymicroprocessors8051proteus

How to create 2 square waveforms of 50% duty cycle in 8051 with Assembly


I'm trying to create two square waveforms of 230 and 460Hz through p2.6 and p2.7 ports of 8051 in Proteus Simulation environment. It will also change its behavior with a switch input from p2.0. When switch is low, the behavior does not change. When it is toggled, frequencies interchange and duty cycle drops to 25%. I'm having trouble in the first part where switch is 0. Although my calculations are correct for the time delay and TH/TL values, the waveforms are not even closed to intended simulations. Also, the code should be strictly Assembly so C is not allowed.

I tried to recalculate but didn't work. I tried my approach with only one counter and it did work, so it has to do with timer triggering. In the code below, I check for timer flags and when a timer reaches its end, I complement the output for the 50% duty cycle. When I introduce the second one, the waveform changes and the expected period of 4 microseconds become few hundred miliseconds in the digital oscilloscope of Proteus.

Here is my code snippet:

ORG 0

    SETUP:
        ;both timers set as mode 1 (16-bit counter)
        MOV TMOD, #11H
    
    MAIN:
        MOV C, P2.0 ;switch signal moved to carry bit
        JC MODE1
    
    MODE0:
        ; This part corresponds to switch = 0. F2 gets timer 1, F1 gets timer 0
    
        ;initialize timer 0
        MOV TL0, #0FAH
        MOV TH0, #0F7H
        SETB TR0
    
        ;initialize timer 1
        MOV TL1, #17H
        MOV TH1, #0FCH
        SETB TR1
    
    LOOPM0:
        MOV C, P2.0
        JC MODE1
        JB TF0, TIMER0
        JB TF1, TIMER1
        SJMP LOOPM0
    
    TIMER0:
        CPL P2.6
        CLR TF0
        SJMP LOOPM0
    
    TIMER1:
        CPL P2.7
        CLR TF1
        SJMP LOOPM0
    
    MODE1:
        ; This part corresponds to switch =1, F1 gets timer 1, F2 gets timer 0
        ; To be implemented
    

    END
    


here is my proteus setup:


Solution

  • You initialize the timer only at the beginning of the program. After overflow, you have to initialize it again because it counts again from the value 0x0000. You have to set TLx as soon as possible, otherwise you can lose one count. You can shorten the program if you use the instruction JBC instead of JB.

    Because it looks like a school assignment I won't write the correct code.