【STC15】3路PWM波形输出示例演示


本示例采用的是STC官方所给的《STC15系列库函数与例程测试版V2.0》里面的示例程序,测试的芯片型号:STC15W408AS。自制的开发板,采用外部晶振16MHz。《【开源分享】自制STC15W408AS开发板》

  • 使用逻辑分析仪实时采集的P25、P26、P27引脚的PWM波形。
  • 逻辑分析仪对波形数据参数测量显示:频率:2.667KHz

实测是符合预期效果的,采用的16MHz的晶振。

PWM频率 = MAIN_Fosc / PWM_DUTY,MAIN_Fosc = 16MHZ, PWM_DUTY = 6000, 则输出PWM频率为2666.6666666.

  • 示波器采集测试采集到的数据参数

程序代码


/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-755-82905966 -------------------------------------------*/
/* --- Tel: 86-755-82948412 -------------------------------------------*/
/* --- Web: www.STCMCU.com --------------------------------------------*/
/* 如果要在文章中应用此代码,请在文章中注明使用了宏晶科技的资料及程序   */
/*---------------------------------------------------------------------*/#include   <reg52.h>/*************   功能说明    **************输出3路9~16位PWM信号。PWM频率 = MAIN_Fosc / PWM_DUTY, 假设 MAIN_Fosc = 16MHZ, PWM_DUTY = 6000, 则输出PWM频率为2666.6666666.******************************************//***************************用户宏定义*******************************************************/
#define     MAIN_Fosc       16000000UL  //定义主时钟#define      PWM_DUTY        6000        //定义PWM的周期,数值为PCA所选择的时钟脉冲个数。
#define     PWM_HIGH_MIN    80          //限制PWM输出的最小占空比, 避免中断里重装参数时间不够。
#define     PWM_HIGH_MAX    (PWM_DUTY - PWM_HIGH_MIN)       //限制PWM输出的最大占空比。/********************************************************************************************/#define   PCA0            0
#define PCA1            1
#define PCA2            2
#define PCA_Counter     3
#define PCA_P12_P11_P10_P37 (0<<4)
#define PCA_P34_P35_P36_P37 (1<<4)
#define PCA_P24_P25_P26_P27 (2<<4)
#define PCA_Mode_PWM                0x42
#define PCA_Mode_Capture            0
#define PCA_Mode_SoftTimer          0x48
#define PCA_Mode_HighPulseOutput    0x4c
#define PCA_Clock_1T    (4<<1)
#define PCA_Clock_2T    (1<<1)
#define PCA_Clock_4T    (5<<1)
#define PCA_Clock_6T    (6<<1)
#define PCA_Clock_8T    (7<<1)
#define PCA_Clock_12T   (0<<1)
#define PCA_Clock_Timer0_OF (2<<1)
#define PCA_Clock_ECI   (3<<1)
#define PCA_Rise_Active (1<<5)
#define PCA_Fall_Active (1<<4)
#define PCA_PWM_8bit    (0<<6)
#define PCA_PWM_7bit    (1<<6)
#define PCA_PWM_6bit    (2<<6)#define     ENABLE      1
#define     DISABLE     0typedef    unsigned char   u8;
typedef     unsigned int    u16;
typedef     unsigned long   u32;sfr AUXR1 = 0xA2;
sfr CCON = 0xD8;
sfr CMOD = 0xD9;
sfr CCAPM0 = 0xDA;     //PCA模块0的工作模式寄存器。
sfr CCAPM1 = 0xDB;     //PCA模块1的工作模式寄存器。
sfr CCAPM2 = 0xDC;     //PCA模块2的工作模式寄存器。sfr CL     = 0xE9;
sfr CCAP0L = 0xEA;     //PCA模块0的捕捉/比较寄存器低8位。
sfr CCAP1L = 0xEB;     //PCA模块1的捕捉/比较寄存器低8位。
sfr CCAP2L = 0xEC;     //PCA模块2的捕捉/比较寄存器低8位。sfr CH     = 0xF9;
sfr CCAP0H = 0xFA;     //PCA模块0的捕捉/比较寄存器高8位。
sfr CCAP1H = 0xFB;     //PCA模块1的捕捉/比较寄存器高8位。
sfr CCAP2H = 0xFC;     //PCA模块2的捕捉/比较寄存器高8位。sbit CCF0  = CCON^0;  //PCA 模块0中断标志,由硬件置位,必须由软件清0。
sbit CCF1  = CCON^1;   //PCA 模块1中断标志,由硬件置位,必须由软件清0。
sbit CCF2  = CCON^2;   //PCA 模块2中断标志,由硬件置位,必须由软件清0。
sbit CR    = CCON^6;   //1: 允许PCA计数器计数,0: 禁止计数。
sbit CF    = CCON^7;   //PCA计数器溢出(CH,CL由FFFFH变为0000H)标志。//PCA计数器溢出后由硬件置位,必须由软件清0。
sbit PPCA  = IP^7;     //PCA 中断 优先级设定位sfr P2M1 = 0x95;    //P2M1.n,P2M0.n     =00--->Standard,    01--->push-pull
sfr P2M0 = 0x96;   //                  =10--->pure input,  11--->open drain//================================================================sbit   P25 = P2^5;
sbit    P26 = P2^6;
sbit    P27 = P2^7;u16     CCAP0_tmp,PWM0_high,PWM0_low;
u16     CCAP1_tmp,PWM1_high,PWM1_low;
u16     CCAP2_tmp,PWM2_high,PWM2_low;u16    pwm0,pwm1,pwm2;void PWMn_Update(u8 PCA_id, u16 pwm);
void    PCA_Init(void);
void    delay_ms(u8 ms);/******************** 主函数 **************************/
void main(void)
{PCA_Init();    //PCA初始化EA = 1;P2M1 &= ~(0xe0);   //P2.7 P2.6 P2.5 设置为推挽输出P2M0 |=  (0xe0);while (1){delay_ms(2);if(++pwm0 >= PWM_HIGH_MAX) pwm0 = PWM_HIGH_MIN;PWMn_Update(PCA0,pwm0);if(++pwm1 >= PWM_HIGH_MAX)    pwm1 = PWM_HIGH_MIN;PWMn_Update(PCA1,pwm1);if(++pwm2 >= PWM_HIGH_MAX)    pwm2 = PWM_HIGH_MIN;PWMn_Update(PCA2,pwm2);}
}//========================================================================
// 函数: void  delay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================
void  delay_ms(u8 ms)
{unsigned int i;do{i = MAIN_Fosc / 13000;while(--i)    ;}while(--ms);
}//========================================================================
// 函数: void PWMn_SetHighReg(unsigned int high)
// 描述: 更新占空比数据。
// 参数: high:    占空比数据,即PWM输出高电平的PCA时钟脉冲个数。
// 返回: 无
// 版本: VER1.0
// 日期: 2013-5-15
// 备注:
//========================================================================
void PWMn_Update(u8 PCA_id, u16 pwm)
{if(pwm > PWM_HIGH_MAX)  pwm = PWM_HIGH_MAX;    //如果写入大于最大占空比数据,强制为最大占空比。if(pwm < PWM_HIGH_MIN)   pwm = PWM_HIGH_MIN;    //如果写入小于最小占空比数据,强制为最小占空比。if(PCA_id == PCA0){CR = 0;                       //停止PCA一会, 一般不会影响PWM。PWM0_high = pwm;           //数据在正确范围,则装入占空比寄存器。PWM0_low = PWM_DUTY - pwm;  //计算并保存PWM输出低电平的PCA时钟脉冲个数。CR = 1;                      //启动PCA。}else if(PCA_id == PCA1){CR = 0;                     //停止PCA。PWM1_high = pwm;           //数据在正确范围,则装入占空比寄存器。PWM1_low = PWM_DUTY - pwm;  //计算并保存PWM输出低电平的PCA时钟脉冲个数。CR = 1;                      //启动PCA。}else if(PCA_id == PCA2){CR = 0;                     //停止PCA。PWM2_high = pwm;           //数据在正确范围,则装入占空比寄存器。PWM2_low = PWM_DUTY - pwm;  //计算并保存PWM输出低电平的PCA时钟脉冲个数。CR = 1;                      //启动PCA。}
}//========================================================================
// 函数: void PCA_Init(void)
// 描述: PCA初始化程序.
// 参数: none
// 返回: none.
// 版本: V1.0, 2013-11-22
//========================================================================
void    PCA_Init(void)
{CR = 0;AUXR1 = (AUXR1 & ~(3<<4)) | PCA_P24_P25_P26_P27;    //切换IO口CCAPM0 = (PCA_Mode_HighPulseOutput | ENABLE);   //16位软件定时、高速脉冲输出、中断模式CCAPM1 = (PCA_Mode_HighPulseOutput | ENABLE);CCAPM2 = (PCA_Mode_HighPulseOutput | ENABLE);CH = 0;CL = 0;CMOD  = (CMOD  & ~(7<<1)) | PCA_Clock_1T;           //选择时钟源PPCA  = 1;  // 高优先级中断pwm0 = (PWM_DUTY / 4 * 1);    //给PWM一个初值pwm1 = (PWM_DUTY / 4 * 2);pwm2 = (PWM_DUTY / 4 * 3);PWMn_Update(PCA0,pwm0);PWMn_Update(PCA1,pwm1);PWMn_Update(PCA2,pwm2);CR    = 1;    // 运行PCA定时器
}
//======================================================================//========================================================================
// 函数: void PCA_Handler (void) interrupt 7
// 描述: PCA中断处理程序.
// 参数: None
// 返回: none.
// 版本: V1.0, 2012-11-22
//========================================================================
void    PCA_Handler (void) interrupt 7
{if(CCF0)       //PCA模块0中断{CCF0 = 0;       //清PCA模块0中断标志if(P25)    CCAP0_tmp += PWM0_high;   //输出为高电平,则给影射寄存器装载高电平时间长度else    CCAP0_tmp += PWM0_low;    //输出为低电平,则给影射寄存器装载低电平时间长度CCAP0L = (u8)CCAP0_tmp;            //将影射寄存器写入捕获寄存器,先写CCAP0LCCAP0H = (u8)(CCAP0_tmp >> 8);    //后写CCAP0H}if(CCF1) //PCA模块1中断{CCF1 = 0;       //清PCA模块1中断标志if(P26)    CCAP1_tmp += PWM1_high;   //输出为高电平,则给影射寄存器装载高电平时间长度else    CCAP1_tmp += PWM1_low;    //输出为低电平,则给影射寄存器装载低电平时间长度CCAP1L = (u8)CCAP1_tmp;            //将影射寄存器写入捕获寄存器,先写CCAP0LCCAP1H = (u8)(CCAP1_tmp >> 8);    //后写CCAP0H}if(CCF2) //PCA模块2中断{CCF2 = 0;       //清PCA模块1中断标志if(P27)    CCAP2_tmp += PWM2_high;   //输出为高电平,则给影射寄存器装载高电平时间长度else    CCAP2_tmp += PWM2_low;    //输出为低电平,则给影射寄存器装载低电平时间长度CCAP2L = (u8)CCAP2_tmp;            //将影射寄存器写入捕获寄存器,先写CCAP0LCCAP2H = (u8)(CCAP2_tmp >> 8);    //后写CCAP0H}
}

【STC15】3路PWM波形输出示例演示相关推荐

  1. STM32: 利用高级定时器产生6路互补PWM波形输出在BLDC中H-PWM-L-ON驱动方式下驱动无刷电机

    原文网址:http://jingyan.eeboard.com/article/73847#/prettyPhoto%5Bpp_gal%5D/6/ http://jingyan.eeboard.com ...

  2. BLE芯片PHY6222---两路PWM互补输出

    文章目录 前言 处理 前言 两路PWM驱动电机,一定情况下PHY6222存在复位且电机控制力度不足 两路PWM波形输出理应为异步,原因在于采用了定时不断开启,关闭,长时间运行会导致定时精度不准确,导致 ...

  3. 控制AVR单片机5路PWM波形

    控制AVR单片机5路PWM波形 控制AVR单片机5路PWM波形 现开发了单片机控制5路PWM波形,也可以同时控制15路直流三色灯板,按触摸屏顺序点亮的电路和程序,供大家参考. 电路为 单片机ATMEG ...

  4. 分享PWM输入模式捕捉4路PWM波形的周期和占空比

    源:分享PWM输入模式捕捉4路PWM波形的周期和占空比 转载于:https://www.cnblogs.com/LittleTiger/p/10324117.html

  5. STM32F103-TIM3 4路PWM波输出

    STM32F1 定时器TIM3 4路PWM波输出 ,部分复用IO口 ,由于TIM3PWM输出引脚与JTAG 引脚冲突 所以要先禁用JTAG .才会有4路PWM输出. main.c /* 使用为正点原子 ...

  6. 基于CubeMX-STM32F103RCT6_单通道双路PWM互补输出

    文章目录 基于CubeMX-STM32F103RCT6_单通道双路PWM互补输出 简介 CubeMX-TIM配置详情 单通道双路 PWM 互补输出配置 参数配置 时钟配置 工程管理 修改代码 基于Cu ...

  7. 嵌入式学习——使用定时器输出PWM波形,实现 LED呼吸灯的效果

    嵌入式学习--使用定时器输出PWM波形,实现 LED呼吸灯的效果 目录 嵌入式学习--使用定时器输出PWM波形,实现 LED呼吸灯的效果 1. 任务要求 2 PWM波介绍, 2.1 什么是PWM(Pu ...

  8. STM32输出PWM波形

    简单介绍一下PWM PWM,英文名Pulse Width Modulation,是脉冲宽度调制缩写,它是通过对一系列脉冲的宽度进行调制,等效出所需要的波形(包含形状以及幅值),对模拟信号电平进行数字编 ...

  9. MSP430单片机串口控制5路PWM频率变化程序

    MSP430单片机串口控制5路PWM频率变化程序 下面介绍一段MSP430单片机通过232串口发送0x00,0x01,0x02,0x03,0x04控制IO端口P1,P2,P4,P5,P6输出6路PWM ...

最新文章

  1. 超人类AI的幻想与思考:自下而上构建的自我迭代意识系统
  2. C语言编写Windows服务程序
  3. 入门Mac快捷键详细分类整理,包括Eclipse和Android Studio中一些常用的快捷键
  4. android 导入so库
  5. 一条来自 GitHub 重磅消息!
  6. 惠普m154a状态页_惠普新品NS—1005w无线智能应用与驱动安装篇
  7. mysql修改视图字段长度_SQL Server 数据库创建视图时修改字段长度
  8. Android m3u8网络视频播放
  9. uni-app H5实现公众号微信授权登入遇到的问题(前端)
  10. 参考文献自动生成--
  11. 威斯康星大学硕士计算机科学,2020年威斯康星大学密尔沃基分校排名TFE Times美国最佳计算机科学硕士专业排名第90...
  12. 微信h5支付添加域名时报错,“h5支付域名需要提供完整的支付路径“
  13. Discuz蜘蛛统计seo插件-蜘蛛统计插件
  14. Python——matplotlib中的乱七八糟(一)【注释,图例,tick能见度,移动坐标轴】
  15. 【转】deepin Linux下Picked up _JAVA_OPTIONS错误
  16. 孙正义式风投是如何一步步垮掉的?
  17. 零售贸易公司财务部门的5个痛点与RPA应用的4大场景
  18. 如何区分单核与多核cpu及理解并行与并发
  19. 微软的人工智能 Copilot 到底有多强大?带你来体验一下
  20. 存储网络 – 了解FCoE的八个技术细节

热门文章

  1. ECharts 数据可视化插件
  2. 小米3android版本,小米手机
  3. iVMS-4200 Vs区别_【5G科普】5G知识知多少?#之5G与4G的区别
  4. 优秀课程案例|如何用scratch画扇形统计图
  5. Django路由写法
  6. vue屏幕分辨率适配实战解析
  7. java 将xxxx年x月x日转换成xxxx/xx/xx,日期格式化个位数前补0
  8. 数据分析报告中如何选择合适的统计图表
  9. 最快速的文件传输软件,解析镭速文件传输软件
  10. python列表推导式去除m3u8中的广告视频地址下载视频