您的位置 首页 发布

STC单片机之PCA/PWM

2路PCA的捕获、高速输出、16bit定时器、PWM模块PCA.c*文件名:PCA.c*芯片:STC12C5A60S2*晶振:12MHz*创建者:冷月*…

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

PCA.c

* 文 件 名:PCA.c

* 芯 片:STC12C5A60S2

* 晶 振:12MHz

* 创 建 者:冷月

* 创立日期:2010.8.18

* 修 改 者:

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

* 功用描绘:2路PCA的捕获、高速输出、16bit守时器、PWM完成

*/

#include

#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

#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);

}

}

}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/changshang/fabu/274900.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部