[通用8051核FLASH系列] HC89S003F4 脉宽调制

[复制链接]
4453|21
 楼主| stm32jy 发表于 2020-2-25 20:28 | 显示全部楼层 |阅读模式
本帖最后由 芯圣电子官方QQ 于 2023-7-25 11:09 编辑

HC89S003F4 是一颗采用高速低功耗 CMOS 工艺设计开发的增强型 8 位单片机,内部有 16K Bytes
FLASH 程序存储器, 256 Bytes IRAM 和 256 Bytes XRAM,最多 18 个双向 I/O 口, 1 个外设功能引脚全
映射模块 PTM,5 个 16 位定时器/计数器,3 组 12 位带死区控制互补 PWM,1 个 8 位 PWM,2 个 UART,
1 个 SPI, 16 个外部中断, 11+2 路 12 位 ADC,四种系统工作模式(正常、低频、掉电和空闲)和 16
个中断源
 楼主| stm32jy 发表于 2020-2-25 20:29 | 显示全部楼层
HC89S003F4 集成了三个 12 位 PWM 模块 PWM0、 PWM1 和 PWM2,三个模块各有一个计数器,
PWM0 的计数器由 PWM0_EN 来控制,只要使能 PWM0_EN,计数器就会启动,计数器的时钟源通过
PWM0C 控制寄存器里的 CK0 来选择。
 楼主| stm32jy 发表于 2020-2-25 20:31 | 显示全部楼层
当需要从芯片管脚输出 PWM 波形时,还需要使能 PWM0_OEN 或 PWM01_OEN,同时需要将端
口设置为强推挽模式。如果不希望从芯片管脚上输出 PWM 波形,可以不用使能 PWM0_OEN 或
PWM01_OEN,这时候 PWM0 的计数器可以当一个定时器来使用,当计数器溢出时,如果中断允许也
会产生 PWM 中断。
 楼主| stm32jy 发表于 2020-2-25 20:52 | 显示全部楼层
如果 EFLT0 置 1, PWM0 输出和其互补输出可由 FLT0 引脚输入信号变化自动关闭。一旦检测到
FLT0 引脚输入有效电平,PWM 输出会立即关闭,但 PWM 内部计数器仍在继续运行,这样方便在 FLT0
引脚错误去除后继续 PWM 输出。在 FLT0 输入信号有效期间, FLT0S 位无法清除。只有当 FLT0 输入
信号消失后,才能软件清除 FLT0S 状态位,此时 PWM 恢复正常输出。
 楼主| stm32jy 发表于 2020-2-25 20:52 | 显示全部楼层
PWM0 故障检测端口 FLT0(P0.0 端口)具有消抖功能,用户可根据需要设置合适的消抖时间。
配置 FLT0 的消抖时间即配置端口 P0.0 的消抖时间,设置方法详见端口消抖控制寄存器 P00DBC、
P01DBC、 P02DBC。三个 PWM 模块的功能及操作完全一样,用户可通过控制寄存器产生 3 路带死区互补的 PWM 或
6 路单独的 PWM 输出。3 个 PWM 模块共用一个中断向量入口,但有各自的控制位及标志位,方便用户定时修改 PWM 模
块下一次循环的周期或占空比。
 楼主| stm32jy 发表于 2020-2-25 20:56 | 显示全部楼层
PWM模块包含 3个独立的波形发生模块,对应的 3对 PWM输出为 PWM0/PWM01、PWM1/PWM11、
PWM2/PWM21,通过控制相关寄存器可使每对 PWM 输出配置成互补输出模式或独立输出模式。
 楼主| stm32jy 发表于 2020-2-25 20:56 | 显示全部楼层
互补输出模式
当 PWMxM(x=0,1,2)置 0: PWM 将工作在互补输出模式 ,互补输出模式时 ,通常使能
PWMx&PWMx(x=0,1,2)1 输出,此时可以控制对应的周期寄存器、占空比寄存器及死区时间寄存器,
从而控制互补波形的输出。互补输出时可选择 PWMx&PWMx1(x=0,1,2)输出极性,方便用户各种电平
驱动需求。
 楼主| stm32jy 发表于 2020-2-25 21:06 | 显示全部楼层
独立输出模式
当 PWMxM 置 1: PWM 将工作在独立输出模式,独立输出模式时,可以控制相关寄存器使能对
应PWM端口单一输出或同时输出,同时让 PWMx&PWMx1输出时,其周期相同但占空比可单独设置。
当为独立输出模式时占空比寄存器将控制 PWMx 的占空比,死区时间控制寄存器将控制 PWMx1 的占
空比,独立输出时也可控制 PWMx&PWMx1 输出极性,方便用户各种电平驱动需求。 (x = 0,1,2)
 楼主| stm32jy 发表于 2020-2-25 21:07 | 显示全部楼层
P22口输出频率为15.69KHz,占空比为34%的方波
  1. void main()
  2. {
  3. /************************************系统初始化****************************************/
  4.         WDTCCR = 0x00;                                                //关闭看门狗
  5.                                                 //本例程为方便测试关闭看门狗,实际使用中,建议客户打开看门狗,详见WDT复位例程
  6.         CLKSWR = 0x51;                                                //选择内部高频RC为系统时钟,内部高频RC 2分频,Fosc=16MHz
  7.         CLKDIV = 0x01;                                                //Fosc 1分频得到Fcpu,Fcpu=16MHz
  8. /************************************PWM3初始化****************************************/
  9.         P2M1 = P2M1&0xF0|0x08;                //P22设置为推挽输出
  10.         PWM3_MAP = 0x22;                                        //PWM3映射P22口
  11.         //周期计算         = 0xFF / (Fosc / PWM分频系数)                (Fosc见系统时钟配置的部分)
  12.         //                        = 0xFF /(16000000 / 4)                       
  13.         //                         = 255 /4000000
  14.         //                        = 63.75us                即15.69KHZ               

  15.         PWM3P = 0xFF;                                                  //PWM周期为0xFF
  16.         //有效电平时间计算(即占空比)        
  17.         //                        = 0x55 / (Fosc / PWM分频系数)                (Fosc见系统时钟配置的部分)
  18.         //                        = 0x55 /(16000000 / 4)                       
  19.         //                         = 85 /4000000
  20.         //                        = 21.25us                占空比为 21.25 / 63.75 = 34%

  21.         PWM3D = 0x55;                                                  //PWM占空比设置
  22.         PWM3C = 0x92;                                                 //使能PWM3,关闭中断,允许输出,时钟4分频
  23.        
  24.     while(1);
  25. }


 楼主| stm32jy 发表于 2020-2-25 21:10 | 显示全部楼层
P22,P11输出频率为1.955KHz,占空比为33.3%的方波
  1. void main()
  2. {
  3. /************************************系统初始化****************************************/
  4.         WDTCCR = 0x00;                                                //关闭看门狗
  5.                                                 //本例程为方便测试关闭看门狗,实际使用中,建议客户打开看门狗,详见WDT复位例程
  6.         CLKSWR = 0x51;                                                //选择内部高频RC为系统时钟,内部高频RC 2分频,Fosc=16MHz
  7.         CLKDIV = 0x01;                                                //Fosc 1分频得到Fcpu,Fcpu=16MHz
  8. /*************************************PWM初始化****************************************/
  9.         P2M1 = P2M1&0xF0|0x08;                //P22设置为推挽输出
  10.   P1M0 = P1M0&0xF0|0x08;    //P10设置为推挽输出
  11.        
  12.         PWM0_MAP = 0x22;                                        //PWM0通道映射P22口
  13.         PWM01_MAP = 0x10;                                        //PWM01通道映射P10口
  14.   PWM0C = 0x01;                                                  //PWM0高有效,PWM01高有效,时钟8分频

  15.         //独立模式下,PWM0和PWM01共用一个周期寄存器
  16.         //PWM0的占空比调节使用                        PWM0组的占空比寄存器
  17.         //PWM01的占空比调节使用                        PWM0组的死区寄存器

  18.         //周期计算         = 0x03ff / (Fosc / PWM分频系数)                (Fosc见系统时钟配置的部分)
  19.         //                        = 0x03ff / (16000000 / 8)                       
  20.         //                         = 1023   /2000000
  21.         //                        = 511.5us                                   约1.955kHz

  22.         PWM0PH = 0x03;                                                //周期高4位设置为0x03
  23.         PWM0PL = 0xFF;                                                //周期低8位设置为0xFF

  24.         //占空比计算= 0x0155 / (Fosc / PWM分频系数)                (Fosc见系统时钟配置的部分)
  25.         //                        = 0x0155 / (16000000 / 8)                       
  26.         //                         = 341          / 2000000
  27.         //                        = 170.5us                   占空比为 170.5/511.5 = 33.3%

  28.         PWM0DH = 0x01;                                                //PWM0高4位占空比0x01
  29.         PWM0DL = 0x55;                                                //PWM0低8位占空比0x55
  30.         PWM0DTH = 0x01;                                                //PWM01高4位占空比0x01
  31.         PWM0DTL = 0x55;                                                //PWM01低8位占空比0x55
  32.         PWM0EN = 0x0F;                                                //使能PWM0,工作于独立模式
  33.        
  34.         while(1);
  35. }


 楼主| stm32jy 发表于 2020-2-25 21:11 | 显示全部楼层
P22,P10输出频率为1.955KHz,占空比为33.4%的方波,两路互补输出,死区时间为18.5us。
  1. void main()
  2. {
  3. /************************************系统初始化****************************************/
  4.         WDTCCR = 0x00;                                                //关闭看门狗
  5.                                                 //本例程为方便测试关闭看门狗,实际使用中,建议客户打开看门狗,详见WDT复位例程
  6.         CLKSWR = 0x51;                                                //选择内部高频RC为系统时钟,内部高频RC 2分频,Fosc=16MHz
  7.         CLKDIV = 0x01;                                                //Fosc 1分频得到Fcpu,Fcpu=16MHz
  8. /*************************************PWM初始化****************************************/
  9.         P2M1 = P2M1&0xF0|0x08;                //P22设置为推挽输出
  10. //  P1M0 = P1M0&0xF0|0x08;    //P10设置为推挽输出
  11.        
  12.           P0M0 = P0M0&0x0F|0x80;    //P01设置为推挽输出
  13.        
  14.        
  15.         PWM0_MAP = 0x22;                                        //PWM0通道映射P22口
  16. //        PWM01_MAP = 0x10;                                        //PWM01通道映射P10口
  17.                 PWM01_MAP = 0x01;                                        //PWM01通道映射P01口
  18.        
  19.     PWM0C = 0x01;                                                //PWM0和PWM01均为高有效,时钟8分频

  20.         //互补模式:互补模式中对于PWM0的有效期间为占空比期间,PWM01的有效期间为占空比的互补期间

  21.         //PWM0组的周期寄存器        调节PWM组的周期
  22.         //PWM0组的占空比寄存器        调节PWM组的占空比
  23.         //PWM0组的死区寄存器        调节PWM组的死区时间

  24.         //周期计算         = 0x03ff / (Fosc / PWM分频系数)                (Fosc见系统时钟配置的部分)
  25.         //                        = 0x03ff /(16000000 / 8)                       
  26.         //                         = 1023         /2000000
  27.         //                        = 511.5us                   约1.955KHZ
  28.         PWM0PH = 0x03;                                                //周期高4位设置为0x03
  29.         PWM0PL = 0xFF;                                                //周期低8位设置为0xFF

  30.         //占空比计算= 0x0155 / (Fosc / PWM分频系数)                (Fosc见系统时钟配置的部分)
  31.         //                        = 0x0155 /(16000000 / 8)                       
  32.         //                         = 341          /2000000
  33.         //                        = 170.5us                   占空比为 170.5/511.5 = 33.4%
  34.         PWM0DH = 0x01;                                                //PWM0,PWM01高4位占空比0x01
  35.         PWM0DL = 0x55;                                                //PWM0,PWM01低8位占空比0x55

  36.         //死区调节的是PWM01相对于PWM0左右各缩减的时间
  37.         //死区计算        = 0x025  / (Fosc / PWM分频系数)                (Fosc见系统时钟配置的部分)
  38.         //                        = 0x025  /(16000000 / 8)                       
  39.         //                         = 37          /2000000
  40.         //                        = 18.5us                  
  41.        
  42.         PWM0DTH = 0x00;                                                //PWM0,PWM01高4位死区时间0x00
  43.   PWM0DTL = 0x25;                                          //PWM0,PWM01低8位死区时间0x25
  44.         PWM0EN = 0x07;                                                //使能PWM0,工作于互补模式
  45.    
  46.         while(1);
  47. }


 楼主| stm32jy 发表于 2020-2-25 21:12 | 显示全部楼层
P22,P10输出频率1.955KHz,占空比为33.4%的方波,如果P02输入低电平,P22,P10输出高电平
  1. void main()
  2. {
  3. /************************************系统初始化****************************************/
  4.         WDTCCR = 0x00;                                                //关闭看门狗
  5.                                                 //本例程为方便测试关闭看门狗,实际使用中,建议客户打开看门狗,详见WDT复位例程
  6.         CLKSWR = 0x51;                                                //选择内部高频RC为系统时钟,内部高频RC 2分频,Fosc=16MHz
  7.         CLKDIV = 0x01;                                                //Fosc 1分频得到Fcpu,Fcpu=16MHz
  8. /*************************************PWM初始化****************************************/
  9.         P2M1 = P2M1&0xF0|0x08;                //P22设置为推挽输出
  10.         P1M0 = P1M0&0xF0|0x08;    //P10设置为推挽输出
  11.         P0M1 = P0M1&0xF0|0x02;    //P02设置为上拉输入
  12.         PWM2_MAP = 0x22;                                        //PWM0通道映射P22口
  13.         PWM21_MAP = 0x10;                                        //PWM01通道映射P10口
  14.         PWM2C = 0x01;                                                  //PWM时钟8分频

  15.         //周期计算         = 0x03ff / (Fosc / PWM分频系数)                (Fosc见系统时钟配置的部分)
  16.         //                        = 0x03ff /(16000000 / 8)                       
  17.         //                         = 1023         /2000000
  18.         //                        = 511.5us                   约1.955KHZ
  19.         PWM2PH = 0x03;                                                //设置周期寄存器高4位为0x03
  20.         PWM2PL = 0xFF;                                                //设置周期寄存器低8位为0xFF

  21.         //占空比计算= 0x0155 / (Fosc / PWM分频系数)                (Fosc见系统时钟配置的部分)
  22.         //                        = 0x0155 /(16000000 / 8)                       
  23.         //                         = 341          /2000000
  24.         //                        = 170.5us                   占空比为 170.5/511.5 = 33.4%
  25.         PWM2DH = 0x01;                                                //设置占空比寄存器高4位为0x01
  26.         PWM2DL = 0x55;                                                //设置占空比寄存器低8位为0x55
  27.         PWM2EN = 0x77;                                                //工作于互补模式,故障时输出高电平
  28.    
  29.         while(1);
  30. }


 楼主| stm32jy 发表于 2020-2-25 21:13 | 显示全部楼层
将PWM0设置为定时器模式,每过32.76Ms进入一次中断,P00电平翻转
  1. void main()
  2. {
  3. /************************************系统初始化****************************************/
  4.         WDTCCR = 0x00;                                                //关闭看门狗
  5.                                                 //本例程为方便测试关闭看门狗,实际使用中,建议客户打开看门狗,详见WDT复位例程
  6.         CLKSWR = 0x51;                                                //选择内部高频RC为系统时钟,内部高频RC 2分频,Fosc=16MHz
  7.         CLKDIV = 0x01;                                                //Fosc 1分频得到Fcpu,Fcpu=16MHz
  8. /**********************************相关配置初始化**************************************/
  9.         P0M0 = P0M0&0xF0|0x08;                //P00设置为推挽输出
  10. /*************************************PWM初始化****************************************/
  11.         PWM0C = 0x83;                                                  //PWM时钟128分频,打开中断
  12.    
  13.         //周期计数完成后,会产生PWM中断,通过设置周期寄存器实现精确定时功能
  14.         //周期计算         = 0x0FFF / (Fosc / PWM分频系数)                (Fosc见系统时钟配置的部分)
  15.         //                        = 0x0FFF /(16000000 / 128)                       
  16.         //                         = 4095         /125000
  17.         //                        = 32.76Ms         (即定时的时间)
  18.    
  19.         PWM0PH = 0x0F;                                                //设置周期寄存器高4位为0x0F
  20.         PWM0PL = 0xFF;                                                //设置周期寄存器低8位为0xFF
  21.         PWM0EN = 0x0F;                                                //使能模块

  22.         EA = 1;                                                                    //打开总中断
  23.         while(1);
  24. }

  25. /***************************************************************************************
  26.   * @说明          PWM中断服务函数
  27. ***************************************************************************************/
  28. void PWM_Rpt(void) interrupt PWM_VECTOR
  29. {
  30.         P0_0 =~ P0_0;                                                  //P00翻转
  31.         PWM0C &=~ 0x40;                                                //清除中断标志位
  32. }


jiaisr123 发表于 2020-3-24 21:15 | 显示全部楼层
这么好的帖子没有人回复,可惜了。我还是复制下来吧
龙卷轰 发表于 2021-3-30 10:11 | 显示全部楼层
我想使用PWM3产生2.7kHz的方波,是不是做不到?只能使用PWM0,1,2?
单片小菜 发表于 2021-4-1 16:32 | 显示全部楼层
感谢楼主分享,不错的。
里面有晴雨 发表于 2021-4-1 17:37 | 显示全部楼层
感谢楼主的分享,很细致,很大威。
单片小菜 发表于 2021-4-13 22:46 | 显示全部楼层
感谢楼主的分享,知识很重要。
huquanz711 发表于 2021-4-15 07:52 来自手机 | 显示全部楼层
感谢楼主的讲解,学习了。
yangxiaor520 发表于 2021-4-16 18:20 来自手机 | 显示全部楼层
没有CAN控制器?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

44

主题

1118

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部