当前位置: 首页 > news >正文

Arduino CH552 PWM的使用

Arduino CH552 PWM的使用


  • 🌿相关篇《Arduino CH552 定时器的使用》

📑CH552 PWM简介

CH552 提供了 2 路 8 位 PWM,PWM 可以选择默认的输出极性为低电平或者高电平,可以动态修改PWM 的输出占空比,通过简单 RC 电阻电容进行积分低通滤波后,即可获得各种输出电压,相当于低速数模转换器 DAC。PWM1 输出占空比= PWM_DATA1 / 256,支持范围 0%到 99.6%。PWM2 输出占空比= PWM_DATA2 / 256,支持范围 0%到 99.6%。
实际应用中,建议允许 PWM 引脚输出并且设置 PWM 输出引脚为推挽输出模式。

📘PWM1 和 PWM2 相关寄存器

在这里插入图片描述

  • PWM2 数据寄存器(PWM_DATA2):
    在这里插入图片描述
  • PWM1 数据寄存器(PWM_DATA1):
    在这里插入图片描述
  • PWM 控制寄存器(PWM_CTRL):
    在这里插入图片描述
    • PWM 时钟分频设置寄存器(PWM_CK_SE):
      在这里插入图片描述
📝测试代码

开启PWM中断,需要在固件:C:\Users\Administrator\AppData\Local\Arduino15\packages\CH55xDuino\hardware\mcs51\0.0.23\cores\ch55xduino\main.c文件中,将PWM中断函数添加进去:void PWMInterrupt( void ) __interrupt(INT_NO_PWMX);

/*PWM_F = Fsys/256/分频系数PWM默认输出通道:PWM1:P15 PWM2: P34开启备用输出通道:PWM1PINAlter( )和PWM2PINAlter( )之后PWM输出引脚PWM1 使用 P3.0PWM2 使用 P3.1同时开启2个通道,PWM1通道输出会有杂波
*/
#include <Arduino.h>#define  LED_BUILTIN  11
#define LED_PIN 17volatile uint16_t count = 0;  // 中断计数器
const uint16_t target = 500;  // 500次中断(每次1ms)
static bool LED_FLAG = 0;
static bool LED2_FLAG = 0;#define  PWM_INTERRUPT  1#define SetPWMClk(CK_SE) (PWM_CK_SE = CK_SE)                                  //分频,默认时钟Fsys  0 ~ 255  #define SetPWM1Dat(dat)  (PWM_DATA1 = dat)                                    //设置PWM输出占空比
#define SetPWM2Dat(dat)  (PWM_DATA2 = dat)#define PWM1PINAlter( )  {PIN_FUNC |= bPWM1_PIN_X;}                           //PWM映射脚P30
#define PWM2PINAlter( )  {PIN_FUNC |= bPWM2_PIN_X;}                           //PWM映射脚P31#define ForceClearPWMFIFO( ) {PWM_CTRL |= bPWM_CLR_ALL;}                      //强制清除PWM FIFO和COUNT
#define CancleClearPWMFIFO( ) {PWM_CTRL &= ~bPWM_CLR_ALL;}                    //取消清除PWM FIFO和COUNT#define PWM1OutEnable()  (PWM_CTRL |= bPWM1_OUT_EN)                           //允许PWM1输出                           
#define PWM2OutEnable()  (PWM_CTRL |= bPWM2_OUT_EN)                           //允许PWM2输出  
#define DsiablePWM1Out() (PWM_CTRL &= ~bPWM1_OUT_EN)                          //关闭PWM1输出                           
#define DisablePWM2Out() (PWM_CTRL &= ~bPWM2_OUT_EN)                          //关闭PWM2输出  #define PWM1OutPolarHighAct()(PWM_CTRL &= ~bPWM1_POLAR)                       //PWM1输出默认低,高有效                           
#define PWM2OutPolarHighAct()(PWM_CTRL &= ~bPWM2_POLAR)                       //PWM2输出默认低,高有效  
#define PWM1OutPolarLowAct() (PWM_CTRL |= bPWM1_POLAR)                        //PWM1输出默认高,低有效                         
#define PWM2OutPolarLowAct() (PWM_CTRL |= bPWM2_POLAR)                        //PWM2输出默认高,低有效 /*******************************************************************************
* Function Name  : PWMInterruptEnable()
* Description    : PWM中断使能
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void  PWMInterruptEnable()
{PWM_CTRL |= bPWM_IF_END | bPWM_IE_END;                                      //清除PWM中断,使能PWM中断IE_PWMX = 1;  
}void PWM_Init()
{P1_MOD_OC &= ~(bPWM1 | bPWM2);                         //设置PWM引脚为推挽输出P1_DIR_PU |= bPWM1 | bPWM2; SetPWMClk(94);                                                              //PWM时钟配置 ,Fsys/256/94分频=24000,000/256/94=992HzForceClearPWMFIFO( );                                                      //强制清除PWM FIFO和COUNTCancleClearPWMFIFO( );                                                     //取消清除PWM FIFO和COUNTPWM1OutEnable( );                                                          //允许PWM1输出                           PWM2OutEnable( );                                                          //允许PWM2输出   PWM1OutPolarHighAct( );                                                    //PWM1输出默认低,高有效                                                   PWM2OutPolarLowAct( );                                                     //PWM2输出默认高,低有效 
#if PWM_INTERRUPTPWMInterruptEnable(); EA = 1;SetPWM1Dat(64);                  //占空比25%SetPWM2Dat(0x7f); 
#else SetPWM1Dat(0x10);                                                          //占空比0x10/256                                                         SetPWM2Dat(0x40); while(1){if(PWM_CTRL&bPWM_IF_END){PWM_CTRL |= bPWM_IF_END;                                               //清除PWM中断        SetPWM1Dat(64);SetPWM2Dat(0x7f); //   printf("PWM_CYC_END  %02X\n",(UINT16)PWM_CTRL);USBSerial_printf("PWM_CYC_END %02X\n",(uint16_t)PWM_CTRL);// wait for a secondUSBSerial_flush();//等待串口数据发送结束(串口数据发送必不可少)}}
#endif  }/*******************************************************************************
* Function Name  : PWMInterrupt(void)
* Description    : PWM中断服务程序   
*******************************************************************************/
void  PWMInterrupt( void )  __interrupt(INT_NO_PWMX)  __using(1)                     //PWM1&2中断服务程序,使用寄存器组1
{PWM_CTRL |= bPWM_IF_END;                                                  //清除PWM中断SetPWM1Dat(64);//   SetPWM2Dat(0x7f); //   LED2_FLAG = !LED2_FLAG;//   digitalWrite(LED_PIN, LED_FLAG);  // 翻转LED}// 定时器2中断服务函数
void Timer2Interrupt(void) __interrupt(INT_NO_TMR2) __using(3) 
{if (TF2) {TF2 = 0;  // 清除定时器2溢出标志count++;if (count >= target) {count = 0;LED_FLAG = !LED_FLAG;// 执行500ms任务digitalWrite(LED_BUILTIN, LED_FLAG);  // 翻转LED}}}void Timer2_init()
{// 配置定时器2T2CON = 0x00;    // 清除T2CON,设置为16位自动重载模式T2MOD = 0x00;    // 时钟=Fsys(24MHz)// 计算定时器初值(24MHz时钟,1ms中断)uint16_t timerValue = 65536 - 1000;//1msRCAP2L = timerValue & 0xFF;   // 低8位RCAP2H = (timerValue >> 8);   // 高8位// 装载初值TL2 = RCAP2L;TH2 = RCAP2H;// 使能定时器2中断ET2 = 1;  // 使能定时器2中断EA = 1;   // 使能全局中断// 启动定时器2TR2 = 1;
}// the setup function runs once when you press reset or power the board
void setup() {// initialize digital pin LED_BUILTIN as an output.pinMode(LED_BUILTIN, OUTPUT);digitalWrite(LED_BUILTIN, LOW);pinMode(LED_PIN, OUTPUT);digitalWrite(LED_PIN, LOW);  // 初始化为低电平(LED熄灭)PWM_Init();Timer2_init();
}// the loop function runs over and over again forever
void loop() {//   USBSerial_println("Hello World123!");// USBSerial_flush();// delay(1000);                       // wait for a second//   USBSerial_println("perseverance51");// wait for a second//   USBSerial_flush();//等待串口数据发送结束(串口数据发送必不可少)
}
  • 同时输出双路PWM输出,在PWM中断中重新装载计数值,PWM1输出波形中偶尔会出现杂波。只启用单路输出没有。两路PWM共用一个中断,只有PWM1有溢出标志位。
http://www.dtcms.com/a/264990.html

相关文章:

  • 项目开发基本流程
  • 深入理解Unicode:字符编码的终极指南
  • RGB下的色彩变换:用线性代数解构色彩世界
  • vue3 JavaScript localeCompare 比较两个字符串 localeCompare is not a function
  • 如何将文件从 iPhone 传输到 Android(新指南)
  • Spring Boot 集成 GeoTools 详解
  • 昇腾机器节点磁盘状态检查与问题处理方法
  • 智能攻击原理和架构
  • 深入Flink核心概念:解锁大数据流处理的奥秘
  • vue-36(为组件编写单元测试:属性、事件和方法)
  • 【Linux】Rocky Linux 安装教程
  • vscode基本使用
  • armv8汇编码分析
  • QGIS+CesiumIon
  • 多模态进化论:GPT-5V图文推理能力在工业质检中的颠覆性应用
  • 媲美 GPT-4o,Kontext 实现高效文本驱动图像编辑
  • vscode、openocd 使用
  • Excel 如何让数据自动按要求排序或筛选?
  • Learning PostgresSQL读书笔记: 第16章 Configuration and Monitoring
  • PostgreSQL大表创建分区实战
  • Arduino CH552 ADC的使用
  • NumPy 或 PyTorch/TensorFlow 中的张量理解
  • Servlet开发流程(包含IntelliJ IDEA项目添加Tomcat依赖的详细教程)
  • 【论文阅读】DeepEyes: Incentivizing “Thinking with Images” via Reinforcement Learning
  • 【新手小白的嵌入式学习之路】-STM32的学习_GPIO 8种模式学习心得
  • JavaWeb笔记03
  • GC393:一款低功耗双电压比较器芯片
  • 设计模式-责任链模式
  • SpringBoot控制反转
  • vue中的toRef