微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > STC12C5A单片机pwm的占空比的设置问题

STC12C5A单片机pwm的占空比的设置问题

时间:10-02 整理:3721RD 点击:
CCAP0H,CCAP0L要怎么设置,我要产生占空比为5%,7.5%,10%的pwm

求帮忙啊。

* 文 件 名:PCA.c
* 芯    片:STC12C5A60S2
* 晶    振:12MHz
* 创 建 者:冷月
* 创建日期:2010.8.18
* 修 改 者:
* 修改日期:2010.9.3      修改设置波特率参数为x%,增加定时器0作为PCA时钟源
* 功能描述:2路PCA的捕获、高速输出、16bit定时器、PWM实现
*/

#include <STC12C5A.H>
#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 <STC12C5A.H>
#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);
              }
       }   
}

好好啊好!

神一样的冷月高手高手高手高手

谢谢小编分享,好资料,先收藏了。

555555555555555555555555555555555

now I see it from your expound

好马扎子回复

高手,佩服佩服!

关于stc12c5a60s的PWM输出的问题;看了你的程序里面有残缺
#include "Delay.h"
这个头文件没有
不知道能否发一份到我邮箱295936912@qq.com
不胜感激  急用  谢谢

高手,高手,

不错。不过,不应该是先处理完数据在清除中断标志不会发上同个中断不断嵌套的情况发生么?

不错。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top