搜档网
当前位置:搜档网 › STC12C5A60S2程序实现0-256分之一晶振任意频率PWM输出

STC12C5A60S2程序实现0-256分之一晶振任意频率PWM输出

STC12C5A60S2程序实现0-256分之一晶振任意频率PWM输出
STC12C5A60S2程序实现0-256分之一晶振任意频率PWM输出

//头文件STC12C5A.h可在网上下载

#include "STC12C5A.H"

#define uint unsigned int

#define uchar unsigned char

uchar t=0;

sbit sign=CCON^2;//此位为预留位置,开发用作表示振动片工作模式,0为一//般模式,1为ADC模式

void init_T0(void);//初始化T0

void init_T1(void);//初始化[T1

void init_INT0(void);//初始化外部中断0

void init_INT1(void);//初始化外部中断1

void init_PCA(void);//初始化PCA模块

void init_ADC(void);//初始化A/D转化模块

void main(void)

{

sign=0;//默认工作在固定模式

P17=1;//开始时P3^0输出为高电平

EA=1;//开总中断

init_T0();//初始化T0

init_T1();//初始化T1

init_INT0();//初始化外部中断0

init_INT1();//初始化外部中断1

init_PCA();//初始化PCA模块

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

init_ADC(); //初始化A/D转化模块

while(1)

{

if(sign==1) //工作在ADC模式

{

if(ADC_CONTR&ADC_FLAG!=0)//转换结束

{

TH0=ADC_RES; //溢出率与初值成正比

TL0=ADC_RES;

ADC_CONTR=ADC_CONTR & 0xE7;//将ADC_FLAG(转

换结//束标志位)与ADC_START清零,其余位不变

ADC_CONTR=ADC_CONTR | 0x08;//将ADC_START置1 }

}

else //工作在固定模式

{

TH0=0x30; //输出一固定频率的PWM波

TL0=0x30;

}

}

}

void init_T0(void)//T0做PCA的时钟源输入

{ //通过改变定时器0溢出率实现可调频率的PWM输出TMOD=0x02; //定时器0工作在方式2,8位定时计数器自动重装载

TH0=0x80; //设置T0定时所对应的初值

TL0=0x80; //设置T0每次定时结束后重装载的值

ET0=1; //允许定时器0中断

TR0=1; //定时器0开始计数

}

void init_T1(void)//T1定时100ms,用于产生呼气吸气脉冲

{

TMOD=TMOD|0x10;//设置定时器1的工作方式为方式2且不改变定时器0的工作方式

TH1=0x3c; //设置定时100ms的处初值

TL1=0xb0;

ET1=1; //允许定时器1中断

TR1=1; //定时器1开始计数

}

void init_INT0(void)

{

IT0=1; //由下降沿触发,输入引脚P3^2

EX0=1; //开外部中断0

}

void init_INT1(void)

{

IT1=1; //由下降沿触发,输入引脚P3^3

EX1=1; //开外部中断1

}

void init_PCA(void)

{

CMOD=0x04; //CIDL=0(D7):空闲模式下继续计数,D4~D6不用//CPS2/CPS1/CPS0(D3~D1)=010,选择T0做PCA时钟源输入

//ECF(D0)=0,关PCA计数器溢出中断

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

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

CR=0; //关闭PCA计数器

CH=0; //PCA计数器高8位置零

CL=0; //PCA计数器低8位置零

CCAPM0=0X42;//PCA模块0的工作模式寄存器设置为0X42表示8位PWM无中断

CCAP0H=0x80; //设置PWM波的占空比为0.5

CCAP0L=0x80; //溢出后会将CCAP0H中值赋给CCAP0L

CCAPM1=0x31; //PCA模块1扩展为上升沿下降沿均可触发的外部中断}

void init_ADC(void)

{

uint i;

for(i=10000;i!=0;i--)//若晶振为6MHZ,是延时20ms等待ADC模块内部模拟电源稳定

{;}

ADC_CONTR=0x80;//开ADC模块电源并选择P1^0作为模拟量输入引脚

P1ASF=0x01; //P1口模拟量功能设置寄存器:使用P1^0的模拟量功能

AUXR1=AUXR1 & 0xfb;//ADRJ=0,ADC_RES存放A/D转换结果高8位

//ADC_RESL存放A/D转换结果低8位ADC_RES=0; //检测前将其清零

ADC_RESL=0;//检测前将其清零

EADC=1; //开A/D转换中断

}

void INT0_ISR(void) interrupt 0 //外部中断0服务程序

{

sign=0; //工作在固定模式

ADC_CONTR=ADC_CONTR&0xF7;//关闭ADC电源

}

void INT1_ISR(void) interrupt 2 //外部中断1服务程序

{

sign=1; //工作在ADC模式

ADC_CONTR|=0x08; //打开ADC电源,由用户决定PWM频率}

void T1_ISR(void) interrupt 3 //定时器1中断服务程序

{

TH1=0x3C; //工作在方式1溢出后不能自动重装载

TL1=0xB0;

t++;

if(t==20) //2s后输出低电平

P17=!P17;

if(t==50)

{

t=0;//5s为一个周期

P17=!P17;

}

}

void PCA_ISR(void) interrupt 7

{

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

{

if(P14==0)//判断是上升沿触发还是下降沿触发,等于0为下降沿触发

{

while(t!=25); //延时0.5s

CCAP0H=0x80; //设置PWM波的占空比为0.5

CCAP0L=0x80;

}

else //上升沿触发

{

CCAP0H=0xFF; //PWM输出低电平

CCAP0L=0xFF;

}

CCF1=0;

else

CCF0=0;//防止干扰信号误动作

}

}

相关主题