STC單片機之PCA/PWM
PCA.c
本文引用地址:http://m.butianyuan.cn/article/201611/316864.htm* 文 件 名:PCA.c
* 芯 片:STC12C5A60S2
* 晶 振:12MHz
* 創(chuàng) 建 者:冷月
* 創(chuàng)建日期:2010.8.18
* 修 改 者:
* 修改日期:2010.9.3 修改設置波特率參數(shù)為x%,增加定時器0作為PCA時鐘源
* 功能描述:2路PCA的捕獲、高速輸出、16bit定時器、PWM實現(xiàn)
*/
#include
#include "PCA.h"
#define uchar unsigned char
#define uint unsigned int
//CCAPnL,CCAPnH步進,
//CCAPnL,CCAPnH增加一個相同的數(shù)值,下一次中斷來臨的間隔時間也是相同的
//無須賦值,PCA初始化函數(shù)中自動賦值
static uint step0 = 0;
static uint step1 = 0;
/*
* 函 數(shù) 名:PCA_Capture_Init
* 功能描述:PCA捕獲模式初始化
* 輸入?yún)?shù):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計數(shù)器
CH = 0x00;
//- - - - - - EPCnH EPCnL
PCA_PWM0 = 0x00; //PWM模式下,CCAPnL,CCAPnH第九位
PCA_PWM1 = 0x00; //PWM模式下,CCAPnL,CCAPnH第九位
//高速脈沖輸出時,將中斷優(yōu)先級設為最高級,以避免其他中斷干擾
IPH = 0x80;
IP = 0x80;
EA = 1;
CR = 1; //啟動PCA計數(shù)器計數(shù)
}
/*
* 函 數(shù) 名:InitTimer0
* 功能描述:定時器0作為PCA時鐘輸入源,工作方式2,1T模式
* 輸入?yún)?shù):無
* 返 回 值:無
*/
void InitTimer0(void)
{
TMOD |= 0x02; //方式2
TH0 = 0x00;
TL0 = 0x00;
//T0x12 T1x12 UM0x6 BRTR S2SMOD BRTx12 EXTRAM S1BRS
AUXR |= 0x80; //定時器0設置為1T
TR0 = 1;
}
/*
* 函 數(shù) 名:Set_PWM_Fre
* 功能描述:定時器0作為PCA時鐘輸入源時,設置PWM頻率
* 輸入?yún)?shù):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;
}
/*
* 函 數(shù) 名:Set_PWM0
* 功能描述:設置PWM0占空比
* 輸入?yún)?shù):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;
}
/*
* 函 數(shù) 名:Set_PWM1
* 功能描述:設置PWM1占空比
* 輸入?yún)?shù):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;
}
/*
* 函 數(shù) 名:PCA_Int
* 功能描述:PCA
* 輸入?yún)?shù):無
* 返 回 值:無
*/
void PCA_Int(void) interrupt 7
{
uint temp;
if (CCF0 == 1) //PCA模塊0中斷
{
CCF0 = 0; //清PCA模塊中斷標志
//CCAPnL,CCAPnH增加一個相同的數(shù)值,下一次中斷來臨的間隔時間也是相同的
temp = ((CCAP0H & 0x00FF)<<8) | CCAP0L;
temp += step0;
CCAP0L = temp & 0x00FF;
CCAP0H = (temp & 0xFF00) >> 8;
//
}
if (CCF1 == 1) //PCA模塊1中斷
{
CCF1 = 0; //清PCA模塊中斷標志
//CCAPnL,CCAPnH增加一個相同的數(shù)值,下一次中斷來臨的間隔時間也是相同的
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
* 創(chuàng) 建 者:冷月
* 創(chuàng)建日期: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 無操作,待機狀態(tài)
// 42H 0 1 0 0 0 0 1 0 8位PWM輸出,無中斷
// 63H 0 1 1 0 0 0 1 1 8位PWM輸出,產(chǎn)生CEXn上升沿中斷
// 53H 0 1 0 1 0 0 1 1 8位PWM輸出,產(chǎn)生CEX0n下降沿中斷
// 73H 0 1 1 1 0 0 1 1 8位PWM輸出,產(chǎn)生CEXn跳變中斷
// 20H 0 x 1 0 0 0 0 0 16位捕獲模式,CEXn上升沿觸發(fā)捕獲
// 10H 0 x 0 1 0 0 0 0 16位捕獲模式,CEXn下降沿觸發(fā)捕獲
// 30H 0 x 1 1 0 0 0 0 16位捕獲模式,CEXn跳變觸發(fā)捕獲
// 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
/*
* 函 數(shù) 名:PCA_Init
* 調(diào) 用: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);
/*
* 函 數(shù) 名:InitTimer0
* 調(diào) 用:InitTimer0();
* 功能描述:定時器0作為PCA時鐘源時,要先初始化定時器0
*/
void InitTimer0(void);
/*
* 函 數(shù) 名:Set_PWM_Fre
* 調(diào) 用:Set_PWM_Fre(523);
* 設置PWM頻率為523Hz
* 功能描述:定時器0作為PCA時鐘源時,PWM可設置184Hz~46KHz
*/
void Set_PWM_Fre(uint fre);
/*
* 函 數(shù) 名:Set_PWM0
* 調(diào) 用:Set_PWM0(40);
* 占空比40%
* 功能描述:設置PWM0占空比
*/
void Set_PWM0(uchar duty);
/*
* 函 數(shù) 名:Set_PWM1
* 調(diào) 用:Set_PWM1(40);
* 占空比40%
* 功能描述:設置PWM1占空比
*/
void Set_PWM1(uchar duty);
#endif
main.c
/*
* 文 件 名:main.c
* 芯 片:STC12C5A60S2
* 晶 振:12MHz
* 創(chuàng) 建 者:冷月
* 創(chuàng)建日期:2010.8.18
* 修 改 者:
* 修改日期:
* 功能描述:PCA之PWM模式實現(xiàn)LED燈漸亮漸滅
*/
#include
#include "Delay.h"
#include "PCA.h"
/*
* 函 數(shù) 名:main
* 功能描述:程序入口
* 輸入?yún)?shù):無
* 返 回 值:無
*/
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);
}
}
}
評論