原创 STC单片机之PCA

2010-9-5 09:57 15619 8 11 分类: MCU/ 嵌入式

2路PCA的捕获、高速输出、16bit定时器、PWM模块


PCA.c


 


 * 文 件 名:PCA.c


 * 芯    片:STC12C5A60S2


 * 晶    振:12MHz


 * 创 建 者:冷月


 * 创建日期:2010.8.18


 * 修 改 者:


 * 修改日期:2010.9.3      修改设置波特率参数为x%,增加定时器0作为PCA时钟源


 * 功能描述:2路PCA的捕获、高速输出、16bit定时器、PWM实现


 */


 


#include <STC12C5A.H>


#include "PCA.h"


 


#define    uchar      unsigned char


#define    uint  unsigned int


 


//CCAPnL,CCAPnH步进,


//CCAPnL,CCAPnH增加一个相同的数值,下一次中断来临的间隔时间也是相同的


//无须赋值,PCA初始化函数中自动赋值


static uint step0 = 0;


static uint step1 = 0;


 


 


/*


 * 函 数 名:PCA_Capture_Init                                                                 


 * 功能描述:PCA捕获模式初始化


 * 输入参数:module:0-PCA模块0,1-PCA模块1;


 *                  PCA_CCAPMn:设置模块工作模式;


 *                  PCA_CCAPnH,PCA_CCAPnL:16bit的捕获寄存器


 *                  PCACLK:PCA时钟源


 * 返 回 值:无


 */


void PCA_Init(bit module, uchar PCA_CCAPMn, uchar PCA_CCAPnH, uchar PCA_CCAPnL, uchar PCACLK)


{


       //CIDL    -       -       -       CPS2    CPS1    CPS0    ECF


       CMOD = 0x80 | PCACLK;                  //空闲模式下PCA停止工作,PCA/PWM时钟源输入


 


       //CF      CR      -       -       -       -       CCF1    CCF0


       CCON = 0x00;


 


       if (module == 0)                 //PCA模块0


       {


              CCAPM0 = PCA_CCAPMn;


 


              CCAP0L = PCA_CCAPnL;


              CCAP0H = PCA_CCAPnH;


 


              step0 = ((PCA_CCAPnH & 0x00FF)<<8) | PCA_CCAPnL;


       }


       else                                 //PCA模块1


       {


              CCAPM1 = PCA_CCAPMn;


 


              CCAP1L = PCA_CCAPnL;


              CCAP1H = PCA_CCAPnH;


 


              step1 = ((PCA_CCAPnH & 0x00FF)<<8) | PCA_CCAPnL;


       }


 


       CL = 0x00;                   //清PCA计数器


       CH = 0x00;


 


       //-       -       -       -       -       -       EPCnH   EPCnL


       PCA_PWM0 = 0x00;            //PWM模式下,CCAPnL,CCAPnH第九位


       PCA_PWM1 = 0x00;            //PWM模式下,CCAPnL,CCAPnH第九位


 


       //高速脉冲输出时,将中断优先级设为最高级,以避免其他中断干扰


       IPH = 0x80;


       IP = 0x80;


 


       EA = 1;


       CR = 1;                        //启动PCA计数器计数


}


 


 


/*


 * 函 数 名:InitTimer0


 * 功能描述:定时器0作为PCA时钟输入源,工作方式2,1T模式


 * 输入参数:无


 * 返 回 值:无


 */


void InitTimer0(void)


{


       TMOD |= 0x02;            //方式2


       TH0 = 0x00;


       TL0 = 0x00;


 


       //T0x12   T1x12   UM0x6   BRTR    S2SMOD  BRTx12  EXTRAM  S1BRS


       AUXR |= 0x80;             //定时器0设置为1T


 


       TR0 = 1;


}


 


 


/*


 * 函 数 名:Set_PWM_Fre


 * 功能描述:定时器0作为PCA时钟输入源时,设置PWM频率


 * 输入参数:fre:要设置的PWM频率,184Hz~46KHz


 * 返 回 值:无


 */


void Set_PWM_Fre(uint fre)


{


       float timerVal;        //定时器定时时间


       uchar tempTimerVal;


 


       timerVal = 1000000.0 / 256 / fre;        


       tempTimerVal = (uint)(65536 - timerVal*12) % 256;


 


       TH0 = tempTimerVal;


       TL0 = tempTimerVal;


}


 


 


/*


 * 函 数 名:Set_PWM0


 * 功能描述:设置PWM0占空比


 * 输入参数:duty:占空比0~100


 * 返 回 值:无


 */


void Set_PWM0(uchar duty)


{


       uchar temp;


      


       if (duty == 0)                      //PWM固定输出低


       {


              //-       -       -       -       -       -       EPCnH   EPCnL


              PCA_PWM0 = 0x03;            //PWM模式下,CCAPnL,CCAPnH第九位


              temp = 0xFF;


       }


       else if (duty == 100)             //PWM固定输出高


       {


              //-       -       -       -       -       -       EPCnH   EPCnL


              PCA_PWM0 = 0x00;            //PWM模式下,CCAPnL,CCAPnH第九位


              temp = 0;


       }


       else


       {


              PCA_PWM0 = 0x00;


              temp = 256 - 256*duty/100;


       }


             


       CCAP0L = temp;


       CCAP0H = temp;


}


 


 


/*


 * 函 数 名:Set_PWM1


 * 功能描述:设置PWM1占空比


 * 输入参数:duty:占空比0~100


 * 返 回 值:无


 */


void Set_PWM1(uchar duty)


{


       uint temp;


      


       if (duty == 0)                      //PWM固定输出低


       {


              //-       -       -       -       -       -       EPCnH   EPCnL


              PCA_PWM1 = 0x03;            //PWM模式下,CCAPnL,CCAPnH第九位


              temp = 0xFF;


       }


       else if (duty == 100)             //PWM固定输出高


       {


              //-       -       -       -       -       -       EPCnH   EPCnL


              PCA_PWM1 = 0x00;            //PWM模式下,CCAPnL,CCAPnH第九位


              temp = 0;


       }


       else


       {


              PCA_PWM1 = 0x00;


              temp = 256 - 256*duty/100;


       }


 


       CCAP1L = temp;


       CCAP1H = temp;


}


 


 


/*


 * 函 数 名:PCA_Int


 * 功能描述:PCA


 * 输入参数:无


 * 返 回 值:无


 */


void PCA_Int(void) interrupt 7


{


       uint temp;


 


       if (CCF0 == 1)                    //PCA模块0中断


       {


              CCF0 = 0;                    //清PCA模块中断标志


 


              //CCAPnL,CCAPnH增加一个相同的数值,下一次中断来临的间隔时间也是相同的


              temp = ((CCAP0H & 0x00FF)<<8) | CCAP0L;


              temp += step0;


              CCAP0L = temp & 0x00FF;


              CCAP0H = (temp & 0xFF00) >> 8;


 


              //


       }


       if (CCF1 == 1)                    //PCA模块1中断


       {


              CCF1 = 0;                    //清PCA模块中断标志


 


              //CCAPnL,CCAPnH增加一个相同的数值,下一次中断来临的间隔时间也是相同的


              temp = ((CCAP1H & 0x00FF)<<8) | CCAP1L;


              temp += step1;


              CCAP1L = temp & 0x00FF;


              CCAP1H = (temp & 0xFF00) >> 8;


 


              //


       }


 


       if (CF == 1)


       {


              CF = 0;


       }


 


       //


}


 


 


 


PCA.h


/*


 * 文 件 名:PCA.h


 * 芯    片:STC12C5A60S2


 * 晶    振:12MHz


 * 创 建 者:冷月


 * 创建日期:2010.8.18


 * 修 改 者:


 * 修改日期:


 * 功能描述:2路PCA的捕获、高速输出、16bit定时器、PWM接口


 */


 


#ifndef    _PCA_H_


#define    _PCA_H_


 


#define    uchar      unsigned char


#define    uint  unsigned int


 


 


//CCAPMn   -  ECOMn CAPPn CAPNn MATn TOGn PWMn CCFn


// 00H     0    0     0     0    0    0    0    0     无操作,待机状态


// 42H     0    1     0     0    0    0    1    0     8位PWM输出,无中断


// 63H     0    1     1     0    0    0    1    1     8位PWM输出,产生CEXn上升沿中断


// 53H     0    1     0     1    0    0    1    1     8位PWM输出,产生CEX0n下降沿中断


// 73H     0    1     1     1    0    0    1    1     8位PWM输出,产生CEXn跳变中断


// 20H     0    x     1     0    0    0    0    0     16位捕获模式,CEXn上升沿触发捕获


// 10H     0    x     0     1    0    0    0    0     16位捕获模式,CEXn下降沿触发捕获


// 30H     0    x     1     1    0    0    0    0     16位捕获模式,CEXn跳变触发捕获


// 48H     0    1     0     0    1    0    0    0     16位软件定时器


// 4CH     0    1     0     0    1    1    0    0     16位高速脉冲输出


 


//捕获


#define    RISE      0x20              //上升沿捕获


#define    DOWN   0x10              //下降沿捕获


 


//定时器


//CCAPnH,CCAPnL = t / (1/PCA时钟源)


#define    TIMER   0x48


 


//高速输出(8Hz~6MHz)


//CCAPnH,CCAPnL = INT(PCA时钟源/(2*f) + 0.5)


#define    HIGH_SPEED_OUT     0x4C


 


//PWM


//PWM频率 = PCA时钟源 / 256


//占空比 = (CCAP0L / 256) *100%


#define    PWM             0x42


 


//PCA模块中断充许


#define    ECCF     0x01  


 


 


//PCA时钟源


#define CLK0     0x00        //Fosc/12


#define CLK1     0x02        //Fosc/2


#define CLK2     0x04        //定时器0的溢出率


#define CLK3     0x06        //ECI外部时钟


#define CLK4     0x08        //Fosc/1


#define CLK5     0x0a        //Fosc/4


#define CLK6     0x0c        //Fosc/6


#define CLK7     0x0e        //Fosc/8


 


 


/*


 * 函 数 名:PCA_Init


 * 调    用:PCA_Init(0, RISE|ECCF, 0x00, 0x00, CLK0);


 *                  第1路PCA上捕获模式,升沿捕获


 *


 *                  PCA_Init(1, TIMER|ECCF, 0x03, 0xE8, CLK0);


 *                  第2路PCA定时器模式,PCA时钟源Fosc/12,定时1ms


 *


 *                  PCA_Init(0, HIGH_SPEED_OUT|ECCF, 0x17, 0x70, CLK0);


 *                  第1路PCA高速输出模式,PCA时钟源Fosc/12,输出脉冲频率1KHz


 *


 *                  PCA_Init(1, PWM, 0xFF, 0xFF, CLK0);


 *                  第2路PCA的PWM模式,PCA时钟源Fosc/12


 * 功能描述:PCA初始化


 */


void PCA_Init(bit module, uchar PCA_CCAPMn, uchar PCA_CCAPnH, uchar PCA_CCAPnL, uchar PCACLK);


 


 


/*


 * 函 数 名:InitTimer0


 * 调    用:InitTimer0();


 * 功能描述:定时器0作为PCA时钟源时,要先初始化定时器0


 */


void InitTimer0(void);


 


 


/*


 * 函 数 名:Set_PWM_Fre


 * 调    用:Set_PWM_Fre(523);


 *                  设置PWM频率为523Hz


 * 功能描述:定时器0作为PCA时钟源时,PWM可设置184Hz~46KHz


 */


void Set_PWM_Fre(uint fre);


 


 


/*


 * 函 数 名:Set_PWM0


 * 调    用:Set_PWM0(40);


 *                  占空比40%


 * 功能描述:设置PWM0占空比


 */


void Set_PWM0(uchar duty);


 


 


/*


 * 函 数 名:Set_PWM1


 * 调    用:Set_PWM1(40);


 *                  占空比40%


 * 功能描述:设置PWM1占空比


 */


void Set_PWM1(uchar duty);


 


#endif


 


 


 


main.c


/*


 * 文 件 名:main.c


 * 芯    片:STC12C5A60S2


 * 晶    振:12MHz


 * 创 建 者:冷月


 * 创建日期:2010.8.18


 * 修 改 者:


 * 修改日期:


 * 功能描述:PCA之PWM模式实现LED灯渐亮渐灭


 */


 


#include <STC12C5A.H>


#include "Delay.h"


#include "PCA.h"


 


 


/*


 * 函 数 名:main


 * 功能描述:程序入口


 * 输入参数:无


 * 返 回 值:无


 */


void main(void)


{


       uchar i;


 


       PCA_Init(0, PWM, 0xFF, 0xFF, CLK0);


       PCA_Init(1, PWM, 0xFF, 0xFF, CLK0);


      


       while (1)


       {


              for (i=0; i<100; i++)


              {


                     Set_PWM1(100-i);


                     Set_PWM0(i);


                     DelayMs1T(40);


 


              }


              for (i=100; i>0; i--)


              {


                     Set_PWM0(i);


                     Set_PWM1(100 - i);


                     DelayMs1T(40);


              }


       }    


}

PARTNER CONTENT

文章评论3条评论)

登录后参与讨论

用户435839 2012-11-8 09:59

你好,如何将PCA的中断优先级设置为最高!!

用户230358 2010-9-1 11:08

zhxlt 你能把代码弄整齐下吗,这么看不来,呵呵

用户329322 2010-8-25 23:04

最近开始用STC12C5408AD的单片机,用的晶体是4.194304M,现在要用PCA高速输出模式产生32.768K的方波,调了好几天都没有调出来,宏晶的手册有不好看懂,汇编的多,希望能指点指点,感激不尽!!! 自己写的代码如下:#define CCAP0L_Value 32 /*fosc=4.194304MHz*/ void PCA0_init(void) //PWM初始化 高速模式 { P3M0=P3M0&(~BIT(7));P3M1=P3M1|BIT(7); //P3.7作为输出口 CMOD =0x02; //设置PCA定时器,空闲模式下停止PCA计数, 时钟源f/2,禁止PCA计数器溢出 CCON= 0x00; //禁止PCA计数器工作,清除中断标志-溢出标志CCON=PCA模块中断标志 CL = 0x00; //PCA计数器低8位,清计数器 CH = 0x00; //PCA计数器高8位 CCAPM0 = 0x4D; CCAP0L=CCAP0L_Value; //输出为32.768K方波 CCAP0H=0x00; // IP = 0x40; //PCA中断唯一优先 IPH = 0x40; EPCA_LVD=1; //开PCA中断 CR = 1; EA = 1; } void PCA0_fast() interrupt 6 { CCF0=0; if(CCAP0L<=(255-CCAP0L_Value)) CCAP0L= CCAP0L+CCAP0L_Value; else { CCAP0L=CCAP0L_Value-(256-CCAP0L); if (CCAP0H<255) CCAP0H++; else CCAP0H=0; } }
相关推荐阅读
用户230358 2010-12-06 17:38
通用Makefile
Makefile初学者,看了点Makefile的资料,想着写个通用的Makefile,于是写了三天。。。可能还有很多错误,测试通过的有gcc的.s和.c,以及嵌入式开发arm-linux-gcc的.S...
用户230358 2010-11-28 09:30
RFID MFRC522
单片机:STC12C5A60S2读卡器:MFRC522非接触IC卡:M1卡keil版本:V4程序是看了网上找的,做了些整理,其中有?号的,是不理解为什么那么设置射频做了好多天,还是有很多不明白,希望对...
用户230358 2010-09-16 23:33
eclipse代码自动提示功能设置
默认是输入"."后出现自动提示,用于类成员的自动提示,可是有时候我们希望它能在我们输入类的首字母后就出现自动提示,可以节省大量的输入时间(虽然按alt + /会出现提示,但还是要多按一次按键,太麻烦了...
用户230358 2010-09-16 23:32
EmEditor配置JAVA
1、选择“工具->外部工具->自定义工具”菜单;2、在“外部工具”对话框中点击“新建”按钮,并进行如下设置:   标题:JAVAC   命令:F:\JDK\bin\javac.exe   ...
用户230358 2010-09-05 10:32
独立按键扫描
定时器1每20ms扫描一次按键,可处理短按、长按 key.c/* * 文 件 名:key.c * 芯    片:STC12C5A60S2 * 晶    振:12MHz * 创 建 者:冷月 * 创建日...
用户230358 2010-09-05 10:23
PWM实现蜂呜器唱歌
PWM用定时器0作时钟源可改变频率,用于输出音符频率,占空比输出音符音长 电路图: BUZZ.C /* * 文 件 名:BUZZ.C * 芯    片:STC12C5A60S2 * 晶    振:12...
EE直播间
更多
我要评论
3
8
关闭 站长推荐上一条 /3 下一条