本帖最后由 any_014 于 2015-6-6 11:34 编辑
用的STC12单片机,选的还是个20脚的...
本来用的PCA功能里的PWM输出功能,可惜是8位的,不过倒是方便,给CH和CL写个数,PCA计时器计时后,如果小于这个值相应管教输出低电平,大于这个值输出高电平。挺省心的。
可现在发现8位有点不够用了,想弄成16位的。
看了下STC官网的例子,用一个定时器生成多路PWM输出。是用一个定时器,每次中断,有个计数值自动加一,增到一定值时,归零,算是周期吧。中间用这个计数值做比较来控制IO口输出高或低。
就是定时器中断太频繁,给其它任务的时间少了。
其他想到的,就是用PCA的16位定时器功能,因为四路PCA公用一个定时器,把其中两路设为16位计时器模式,一路设的值为低电平时间,另一路设成最大值,为整个周期的时间,这样两路引起的中断,分别将单片机IO口拉高和拉低。
就是觉得有点麻烦。
STC的PCA还有个高速输出功能,是计时器到了设定值引发IO口电平反转。
给的例子是,PCA中断后将CH和CL的值自动增加一固定值,这样总是经过固定的时间触发IO口反转。
有没有可能用这个模式产生占空比可调并且周期固定的PWM?
-----------------------------------------------------------------------------------------
现在按自己想的改了下,结果用定时器模式,PCA输出管脚没有变化,不知道哪里设置错了...
void PCAInit()
{
CCON = 0; //Initial PCA control register
//PCA timer stop running
//Clear CF flag
//Clear all module interrupt flag
CL = 0; //Reset PCA base timer
CH = 0;
CMOD = 0x00; //Set PCA timer clock source as Fosc/12
CCAP0H = 0x80; //第一路用来产生固定占空比的方波,想每中断一次,IO管脚翻转一次;
CCAP0L = 0x00;
CCAPM0 = 0x49; //PCA module-0 work in 8-bit PWM mode and no PCA interrupt
CCAP1H = CCAP1L = 0x00; //设为16位定时器模式,到预定值后,PWM管脚输出高电平;CCAP1H,CCAP1L值在主程序里根据测量值改变;
CCAPM1 = 0x49;
CCAP2H = CCAP2L = 0xFF; //设为16位定时器模式,到预定值后,PWM管脚输出低电平;设为0xFFFF,为PWM波一周期计数值;
CCAPM2 = 0x49;
CR = 1; //PCA timer start run
EPCAI = 1;
}
void PCA_isr() interrupt 6 using 1
{
if(CCF0)
{
CCF0 = 0;
VEE = !VEE;
}
if(CCF1)
{
CCF1 = 0;
DAPWM = !DAPWM;
}
if(CCF2)
{
CCF2 = 0;
}
}
-----------------------------------------------------------------------------------------------
发现PCA定时器有个溢出中断,这样应该只用一个PCA模组做16位定时器就可以了。
-------------------------------------------------------------------------------------------------
当模组0计时器引发中断,将IO管脚拉低高;PCA计时器溢出引发中断,将IO管脚拉低。这样试着没问题。
看了下波形,占空比略有变化,估计是其他中断占用时间了。
------------------------------------------------------------------------------------------------------
PCA中断影响主程序时间采样了...
也许该放弃这个了,下次改板时换成STC15系列的吧...
--------------------------------------------------------------------------------------------------
按默认中断优先级来的话,外部中断>定时器中断>串口中断,现在外部中断和计数器中断是轮流开着的,应该没有影响到定时器计数的吧,还是不知道为什么会定时器测量数会跳,难道是硬件问题?
|