//头文件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;//防止干扰信号误动作
}
}