PCA

所涉及的寄存器

CCON

CMOD

CCAPM0

CCAPM1

CL_CH_CCAPnL_CCAPnH

PCA 模块工作模式设定

PCA_PWM0_PCA_PWM1

PCA_PWM 结构图

PCA定时器 结构图

注意,与Timerx不同,CCAPMnH/CCAPMnL需要每次计数给一个步进才能正常计数(从下往上计数)

例子

PCA_PWM0_PWM1

PCA_PWM.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#ifndef __PCA_PWM_H
#define __PCA_PWM_H

#include <reg52.h>

sfr CCON = 0xd8;
sfr CMOD = 0xd9;
sfr CCAPM0 = 0xda;
sfr CCAPM1 = 0xdb;
sfr CL = 0xe9;
sfr CH = 0xf9;
sfr CCAP0L = 0xea;
sfr CCAP0H = 0xfa;
sfr CCAP1L = 0xeb;
sfr CCAP1H = 0xfb;
sfr PCA_PWM0 = 0xe2;
sfr PCA_PWM1 = 0xf3;

sfr AUXR = 0x8e;
sfr AUXR1 = 0xa2;

sbit CCF0 = CCON^0;
sbit CCF = CCON^1;
sbit CR = CCON^6;
sbit CF = CCON^7;

void PCA_PWM_Init();
#endif

PCA_PWM.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "PCA_PWM.h"

void PCA_PWM_Init()
{
TR0 = 1; // Init Timer0 1t
TMOD = 0x02;
TH0 = TL0 = 256 - 4 ; // 1/(10K*256) = TIMS*(1/11059200) TIMS = 4.3
AUXR = 0x80;


CCON = 0; //clear

CL = CH = 0; //clear

CMOD = 0x04; //set PCA timer clock source as Timero

CCAP0H = CCAP0L = 0x80; //256/2 = 128 = 0x80 50%duty cycle square wave

CCAPM0 = 0x42 ; //work in 8 bit PWM0 mode no PCA interrupt

CCAP1H = CCAP1L = 0x40; //256/4 = 64 = 0x40 75%duty cycle square wave

CCAPM1 = 0x42 ; //work in 8 bit PWM1 mode

CR = 1; //enable PCA

}

main.c

1
2
3
4
5
6
7
#include "main.h"

void main()
{
PCA_PWM_Init(); // P13 PWM0 p14 pwm1
while(1);
}

main.h

1
2
3
4
5
6
7
8
#ifndef __MAIN_H
#define __MAIN_H

#include <reg52.h>
#include "PCA_PWM.h"

#endif

PCA_Timer

PCA_Timer.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <PCA_Timer.h>

unsigned int count ;
unsigned int value ;


void PCA_Timer_Init()
{
CCON = CMOD = 0; //clear

CMOD =0x08; //PCA Timer source from Systemclock/1 1/11059200HZ

CL = CH = 0; //clear

CCAPM0 = 0x49 ; //PCA work in 16 bit Timer enable PCA interrupt

CCAP0L = value ;

CCAP0H = value>>8;

CR = 1; //start PCA

EA = 1; //enable main interrupt

count = 0;

}


void PCA_Interrupt() interrupt 7
{
CCF0 = 0; //clear interrupt flag
CCAP0L = value; //reload
CCAP0H = value>>8;
value+=TIMS; //add stepping!
count++;
if(count>=1000)
{
count = 0;
LED = !LED; //1s
}
}

PCA_Timer.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#ifndef __PCA_TIMER_H
#define __PCA_TIMER_H



#include <reg52.h>

#define TIMS (11059200L/1000)

sfr CCON = 0xd8;
sfr CMOD = 0xd9;
sfr CCAPM0 = 0xda;
sfr CCAPM1 = 0xdb;
sfr CL = 0xe9;
sfr CH = 0xf9;
sfr CCAP0L = 0xea;
sfr CCAP0H = 0xfa;
sfr CCAP1L = 0xeb;
sfr CCAP1H = 0xfb;
sfr PCA_PWM0 = 0xe2;
sfr PCA_PWM1 = 0xf3;

sfr AUXR = 0x8e;
sfr AUXR1 = 0xa2;

sbit CCF0 = CCON^0;
sbit CCF = CCON^1;
sbit CR = CCON^6;
sbit CF = CCON^7;

sbit LED = P3^0;



void PCA_Timer_Init();

#endif


main.c

1
2
3
4
5
6
7
8
9
10
11
#include "main.h"



void main()
{
PCA_Timer_Init();

while(1);
}

main.h

1
2
3
4
5
6
7
8
9
10
#ifndef __MAIN_H
#define __MAIN_H

#include <reg52.h>
#include "PCA_Timer.h"


#endif