[通用8051核FLASH系列]

HC89S003F4 脉宽调制

[复制链接]
3360|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%的方波
void main()
{
/************************************系统初始化****************************************/
        WDTCCR = 0x00;                                                //关闭看门狗
                                                //本例程为方便测试关闭看门狗,实际使用中,建议客户打开看门狗,详见WDT复位例程
        CLKSWR = 0x51;                                                //选择内部高频RC为系统时钟,内部高频RC 2分频,Fosc=16MHz
        CLKDIV = 0x01;                                                //Fosc 1分频得到Fcpu,Fcpu=16MHz
/************************************PWM3初始化****************************************/
        P2M1 = P2M1&0xF0|0x08;                //P22设置为推挽输出
        PWM3_MAP = 0x22;                                        //PWM3映射P22口
        //周期计算         = 0xFF / (Fosc / PWM分频系数)                (Fosc见系统时钟配置的部分)
        //                        = 0xFF /(16000000 / 4)                       
        //                         = 255 /4000000
        //                        = 63.75us                即15.69KHZ               

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

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


使用特权

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

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

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

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

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

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


使用特权

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

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

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

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

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

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


使用特权

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

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

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


使用特权

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

        EA = 1;                                                                    //打开总中断
        while(1);
}

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


使用特权

评论回复
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

帖子

3

粉丝