# PWM in 8051 with PCA counter

I read in documentation of AT89C51RC2, that I can make one of 5 ports to generate PWM signal if I set properly some registers. Some things I don't understand. I don't know what PCA counter is and how it behaves. There is what I came up with according to documentation.

CEX0 equ P1.3
CCAPM0 equ 0DAh
CCAP0L equ 0EAh
CCAP0H equ 0FAh
CL equ 0E9h
CCON equ 0D8h

DSEG at 30h

CSEG

ORG 0000h
AJMP START

START:
MOV CCAPM0,#10000010B
MOV CCAP0H,#0FFh
MOV CCAP0L,#0FFh
ORL CCON,#01000000B

MAIN:

MOV R6,#0FFh
DJNZ R6,$MOV A,01000000B XRL A,CCON JNZ null LJMP MAIN null: MOV CL,#0 MOV CCON,#01000000B LJMP MAIN END  I don't know which direction the CPA counter counts, whether it is needed to reset it, I don't know If I forgot to set some registers. This code doesn't work. Looks like the counter doesn't even count. Any suggestions? ## 1 Answer Another one register is needed to set. CMOD equ 0D9h  I need to set mode of the PCA counter and enable Counter Overflow Interrupt. So the code goes CEX0 equ P1.3 CCAPM0 equ 0DAh CCAP0L equ 0EAh CCAP0H equ 0FAh CL equ 0E9h CCON equ 0D8h CMOD equ 0D9h DSEG at 30h CSEG ORG 0000h AJMP START START: MOV SP,#70H SETB EA ; global interrupt enable MOV CCAPM0,#10000010B MOV CCAP0H,#0FFh MOV CCAP0L,#0FFh ORL CCON,#01000000B ANL CMOD,#11111001B ; PCA counter mode 0 ORL CMOD,#00000001B ; PCA counter interrupt enable MAIN: MOV R6,#0FFh ;delay, because I use serial to change duty cycle, DJNZ R6,$       ;so it had time to change

MOV A,01000000B
XRL A,CCON
JNZ null

LJMP MAIN

null:
MOV CL,#0
MOV CCON,#01000000B
LJMP MAIN

END


I can see it's working with voltmeter or LED attached to port P1.3.

• The CL counter and overFlow flag in CCON doesn't need to be reset in code. It works without it. Apr 22 '15 at 20:26