×
嵌入式 > 技术百科 > 详情

STC12C5410AD单片机PCA应用图文详解

发布时间:2020-06-17 发布时间:
|

任务:


利用STC12C5410AD自带的4路PCA,扩展4路外部中断;利用4路外部中断来对输入的脉冲序列进行计数。


备注:


本文工程文件里还涉及到STC12C5410AD的UART、Time0等接口函数,请读者自行理解


一、PCA16位定时器计数器结构



从图中得知,要产生PCA溢出中断需要进行一下设置:


1、 选择PCA16计数器的时钟源。时钟源的选择由PCA的CMOD寄存器的CPS1和CPS0决定。



2、 IDLE跟CIDL必须有一位为0(常规的置CIDL为0)


3、 CR必须置1,允许计数器开始计数


4、 CMOD的ECF必须置1,以允许CCOD中的CF位在产生中断时:CF=1


5、 需要给PCA的16位计数器CH和CL赋初值


二、PCA捕获模式



PCA工作于捕获模式需要进行一下设置:(主要是配合CCON寄存器和CCAPMn寄存器)


1、 设置PCA捕获模块的对外部脉冲的捕获方式:主要是允许上升沿捕获或者下降沿捕获。由CCAPMn的CAPPn跟CAPNn决定:当CAPPn=1,允许上升沿捕获;当CAPNn=1,允许下降沿捕获


2、 使能CCFn中断。设置相应的ECCFn=1


具体的工作流程如下,以PCA0为例并设置为上升沿捕获:PCA0模块对P3^7(PCA0的输入管脚)进行跳变捕获,当采样到有效的上升沿时,PCA在硬件上会把PCA的计数器寄存器(CH/CL)的值转载到PCA0的捕获寄存器(CCAP0L和CCAPOH)中,置位中断标志位:CF =1,CCF0=1。使用者则只需要,在中断函数里进行相关的操作即可,记得要清零中断标志位。


三、IO口初始化函数、PCA初始化函数、PCA中断处理函数


/*******************************************************************************

* Function Name  : IO_Init

* Description    : IO初始化

* Input          : None

* Output         : None

* Return         : None

* Others         : 系统时钟20Mhz

*******************************************************************************/

void IO_Init(void)

{

P3M0 |= 0xA0;//初始化P3^7(PCA0),P3^5(PCA1)的IO状态为:仅为输入,

P3M1 |= 0x00;

P2M0 |= 0x10;//初始化P2^4(PCA3)的IO状态为:仅为输入

P2M1 |= 0x00;

}

/*******************************************************************************

* Function Name  : PCA_Init

* Description    : PCA初始化

* Input          : None

* Output         : None

* Return         : None

* Others         : 系统时钟20Mhz

*******************************************************************************/

void PCA_Init(void)

{

CMOD |= 0x01;//CMOD=00000011

//CIDL=0,空闲模式下允许PCA继续工作

//CPS1:CPS0=01,PCA的时钟系统为:sysclk/2

//ECF=1,允许寄存器CCON中CF位的中断

CCON |= 0x00;//CCON=01000000

    //CF=0,PCA计数器阵列溢出标志位清零

//CR=0,关闭PCA计数器阵列

//CCF0-3=0,PCA模块0123中断标志位清零

CCAPM0 |= 0x21;//CCAPM0=00100001

//ECOM0=0,不允许比较器功能

//CAPP0=1,允许上升沿捕获

//MAT0=0,PCA计数值与模块的捕获值相匹配时,置位中断CCP0

//ECCF0=1,使能CCF0中断

CCAPM1 |= 0x21;//CCAPM1=00100001

//ECOM1=0,不允许比较器功能

//CAPP1=1,允许上升沿捕获

//MAT1=0,PCA计数值与模块的捕获值相匹配时,置位中断CCP1

//ECCF1=1,使能CCF1中断

CCAPM2 |= 0x21;//CCAPM2=00100001

//ECOM2=0,不允许比较器功能

//CAPP2=1,允许上升沿捕获

//MAT2=0,PCA计数值与模块的捕获值相匹配时,置位中断CCP2

//ECCF2=1,使能CCF2中断

CCAPM3 |= 0x21;//CCAPM3=00100001

//ECOM3=0,不允许比较器功能

//CAPP3=1,允许上升沿捕获

//MAT3=0,PCA计数值与模块的捕获值相匹配时,置位中断CCP3

//ECCF3=1,使能CCF3中断

CH = 0;//PCA装载值的高8位

CL = 0;//PCA装载值的低8位

CCAP0L = 0;//PCA0捕获计数值的高8位

CCAP0H = 0;//PCA0捕获计数值的低8位

CCAP1L = 0;//PCA1捕获计数值的高8位

CCAP1H = 0;//PCA1捕获计数值的低8位

CCAP2L = 0;//PCA2捕获计数值的高8位

CCAP2H = 0;//PCA2捕获计数值的低8位

CCAP3L = 0;//PCA3捕获计数值的高8位

CCAP3H = 0;//PCA3捕获计数值的低8位


CR = 1;    //CR=1,启用PCA计数器阵列

IE |= 0x40;//EPCA_LVD=1,允许PCA模块和低压监测中断 

EA = 1;    //EA=1,打开总中断 

}

/*******************************************************************************

* Function Name  : PCA_ISR

* Description    : PCA扩展中断处理函数

* Input          : None

* Output         : None

* Return         : None

* Others         : None

*******************************************************************************/

void PCA_ISR(void) interrupt 7 using 1

{

EPCA_LVD = 0;//关闭PCA中断

if(1 == CF)//有信号就进入捕获中断

{

CF = 0; //清零PCA总的捕获中断标志位

}

if(1 == CCF0)

{

CCF0 = 0;    //清零PCA0的捕获中断标志位

CCF0_Flag++; //CCF0_Flag标志位递增

}

if(1 == CCF1)

{

CCF1 = 0;    //清零PCA1的捕获中断标志位

CCF1_Flag++; //CCF1_Flag标志位递增

}

if(1 == CCF2)

{

CCF2 = 0;    //清零PCA2的捕获中断标志位

CCF2_Flag++; //CCF2_Flag标志位递增

}

if(1 == CCF3)

{

CCF3 = 0;    //清零PCA3的捕获中断标志位

CCF3_Flag++; //CCF3_Flag标志位递增

}

EPCA_LVD = 1;//打开PCA中断

}

 


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
家庭网络:从带宽共享走向内容共享