Honsiti 发表于 2023-12-27 10:08:41

求助帖 关于PWM配置问题







void PWMA_config(void)
{
        u8        ccer1;
        u8        ccer2;
        u8        ps;
        P_SW2 |= 0x80;                //SFR enable   
        PWMA_ENO    = 0;        // IO输出禁止
        PWMA_IER    = 0;        // 禁止中断
        PWMA_SR1    = 0;        // 清除状态
        PWMA_SR2    = 0;        // 清除状态
        PWMA_CR1    = 0;        // 清除控制寄存器
        PWMA_CR2    = 0;        // 清除控制寄存器
        ccer1 = 0;
        ccer2 = 0;
        ps    = 0;
        eno   = 0;
        PWMA_ISR_En = 0;

        PWMA_PSCR = 100;        // 预分频寄存器, PWM时钟 = 12MHz/(11+1)=1MHz,
        PWMA_DTR= 12;       
                                       

        PWMA_ARRH=((PWMA_DUTY-1) >> 8);
PWMA_ARRL=((PWMA_DUTY-1) & 0xFF);
       
       
        PWMA_CCMR3 = 0x10;                // 通道模式配置, PWM模式1, 预装载允许
        PWMA_CCR3= pwma2;         // 比较值, 控制占空比(高电平时钟数)
        ccer2 |= 0x05;                        // 开启比较输出, 高电平有效
        ps    |= 0x00;                                // 选择IO, 0:选择P1.0 P1.1, 1:选择P2.0 P2.1, 2:选择P6.0 P6.1,
        eno   |= 0x30;                        // IO输出允许,bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,bit3: ENO2N,bit2: ENO2P,bit1: ENO1N,bit0: ENO1P
        PWMA_ISR_En |= 0x08;        // 使能中断
       
        PWMA_CCMR2 = 0x68;                // 通道模式配置, PWM模式1, 预装载允许
        PWMA_CCR2= pwma1;        // 比较值, 控制占空比(高电平时钟数)
        ccer1 |= 0x50;                        // 开启比较输出, 高电平有效
        ps    |= 0;                                // 选择IO, 0:选择P1.0 P1.1, 1:选择P2.0 P2.1, 2:选择P6.0 P6.1,
        eno   |= 0x0C;                        // IO输出允许,bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,bit3: ENO2N,bit2: ENO2P,bit1: ENO1N,bit0: ENO1P
//        PWMA_IER   |= 0x01;        // 使能中断

        PWMA_CCER1= ccer1;        // 捕获/比较使能寄存器1
        PWMA_CCER2= ccer2;        // 捕获/比较使能寄存器2
        PWMA_PS   = ps;                // 选择IO

        PWMA_BRK    = 0x80;                // 主输出使能 相当于总开关
        PWMA_CR1    = 0x81;                // 使能计数器, 允许自动重装载寄存器缓冲, 边沿对齐模式, 向上计数,bit7=1:写自动重装载寄存器缓冲(本周期不会被打扰), =0:直接写自动重装载寄存器本(周期可能会乱掉)
        PWMA_EGR    = 0x01;                //产生一次更新事件, 清除计数器和预分频计数器, 装载预分频寄存器的值
        PWMA_ENO    = 0x00;                // 允许IO输出
       
}



void main(void)
{
       
        PWMA_config();
       

        ES = 1;
        EA = 1;        // 开启总中断
       

        while (1){}

}

在这一段配置代码中只要我开启语句PWMA_IER |= 0x08;就会导致我的I/O口电平被拉低 ,我 注释掉语句PWMA_IER |= 0x08;或者将该语句放到 main 函数中,I/O口状态就不会被拉低,请问各位老师这是什么原因所导致的??

乘风飞扬 发表于 2023-12-27 10:45:00

你PWM初始化函数里面最后一条指令,关闭了PWM输出通道:
PWMA_ENO    = 0x00;
PWM模块就不会对IO口产生影响。
另外你没有进行IO口初始化,脚位默认是高阻输入模式。

Honsiti 发表于 2023-12-27 11:30:21

乘风飞扬 发表于 2023-12-27 10:45
你PWM初始化函数里面最后一条指令,关闭了PWM输出通道:
PWMA_ENO    = 0x00;
PWM模块就不会对IO口产生影响 ...

I/O口子啊另外一个文件是配置成准双向了
因为一上电PWM不需要输出 只要保持高电平就行
现在就是PWMA_IER |= 0x08; 语句放在PWM配置文件就出问题放在main 没事 所以现在暂时只能先这样解决着


在 后续运行中 PWM 的输出函数PWM_SlowChang()实际是影响着其他I/O口的电平状态,导致硬件无法开机。所以现在感觉无从下手。PWM_SlowChang()也只是配置了 PWM的占空比变换状态。
void PWM_SlowChang(u16 PWM_Position)
{
                        if(PWM_Position == 0 )
                {
                        PWM_OFF = 1;
                }
                else if( PWM_Position != 0)
                {
                        PWM_OFF = 0;
                }
               
                while((currentValue1 < Dury1[ PWM_Position ] )&& (currentValue2< Dury3[ PWM_Position]))
                {
                        while( PWM_Time);
                        currentValue1 += increment;
                        currentValue2 += increment;
                        pwma1= currentValue1;
                        pwma2N = currentValue2;
                        if((currentValue1 == Dury1[ PWM_Position ] ) && (currentValue2 ==Dury3[ PWM_Position]))
                        {
                                pwma1= currentValue1;
                                pwma2N = currentValue2;
                        }
                        PWM_Time = PWM_Countdown;
                }
                while((currentValue1 >= Dury1[ PWM_Position] )&& (currentValue2 >= Dury3[ PWM_Position]))
                {
                        while( PWM_Time);
                        currentValue1 -= increment;
                        currentValue2 -= increment;
                        pwma1= currentValue1;
                        pwma2N = currentValue2;
                        if((currentValue1 == Dury1[ PWM_Position] ) && (currentValue2 ==Dury3[ PWM_Position]))
                        {
                                pwma1   = currentValue1;
                                pwma2N= currentValue2;
                                PWM_Kut = 1;
                        }

                        PWM_Time = PWM_Countdown; //重置倒计时
                }
}

乘风飞扬 发表于 2023-12-27 13:19:54

Honsiti 发表于 2023-12-27 11:30
I/O口子啊另外一个文件是配置成准双向了
因为一上电PWM不需要输出 只要保持高电平就行
现在就是PWMA_ ...

像这样只提供一鳞半爪的,没法帮你分析。
你公开的main函数里面只有4条代码,完全不知道你还做过什么。
屏蔽其它代码,只初始化IO口跟公开的PWM配置函数试试。

梁工 发表于 2023-12-28 16:25:38

你有PWM中断函数吗?如果没有,则各种问题都是正常的。

Honsiti 发表于 2024-1-6 10:25:14

乘风飞扬 发表于 2023-12-27 13:19
像这样只提供一鳞半爪的,没法帮你分析。
你公开的main函数里面只有4条代码,完全不知道你还做过什么。
...

目前通过重建解决了问题 现在看来是我的PWM某个配置出现了问题

Honsiti 发表于 2024-1-6 10:29:05

梁工 发表于 2023-12-28 16:25
你有PWM中断函数吗?如果没有,则各种问题都是正常的。

梁工我想问一个问题,就是PWM移相我目前是通过两路通道输出实现的,一路使用PWM模式,一路使用比较输出模式,虽然这个方法可以实现0-180度移相,但是有一个问题就是比较输出模式无法像PWM一样实现0占空比,只能通过使能PWM_EMO实现PWM的关断从而实现0占空比。
有没有比较好的方法解决这个问题。或者是不是可以使用PWMB作为主模式PWMA作为从模式这种方式实现移相

梁工 发表于 2024-1-6 10:56:23

Honsiti 发表于 2024-1-6 10:29
梁工我想问一个问题,就是PWM移相我目前是通过两路通道输出实现的,一路使用PWM模式,一路使用比较输出模 ...

最简单就是用ENO控制,输出高低均可,我就是如此。
页: [1]
查看完整版本: 求助帖 关于PWM配置问题