OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3996|回复: 3

求助,TIM8输出三路PWM不成功

[复制链接]

66

主题

364

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2015-6-18
在线时间
129 小时
发表于 2016-7-11 12:38:44 | 显示全部楼层 |阅读模式
1金钱
void TIM8_PWM_Init(void)
{                                                          
       
        RCC->APB2ENR|=1<<13;         //TIM8
        RCC->APB2ENR|=1<<4;   


        GPIOC->CRL&=0X00FFFFFF;        //PC6\7\8
        GPIOC->CRH&=0XFFFFFFF0;        //PC6\7\8       
        GPIOC->CRL|=0XBB000000;
        GPIOC->CRH|=0X0000000B;

        TIM8->ARR=999;
        TIM8->PSC=0;
       
        TIM8->CCMR1|=6<<4;    //CH1 PWM2模式
        TIM8->CCMR1|=1<<3;    //CH1预装载使能
        TIM8->CCMR1|=6<<12;          //CH2 PWM2模式                 
        TIM8->CCMR1|=1<<11;         //CH2预装载使能       
        TIM8->CCMR2|=6<<4;    //CH3 PWM2模式
        TIM8->CCMR2|=1<<3;    //CH3预装载使能
       
    TIM8->CCER|=1<<0;           //OC1 输出使能
    TIM8->CCER|=1<<4;           //OC2 输出使能       
    TIM8->CCER|=1<<8;           //OC3 输出使能
       
        TIM8->CR1=0x0080;
    TIM8->CR1|=0x01;  
    TIM8->BDTR|=0x8000;                
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

33

主题

984

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8024
金钱
8024
注册时间
2014-8-13
在线时间
1595 小时
发表于 2016-7-11 13:15:45 | 显示全部楼层
本帖最后由 mack13013 于 2016-7-11 13:20 编辑

贴个代码给你参考一下吧。  TIM1,TIM8各输出4路,还可以各加三路互补输出的。
程序里的标记、注释什么的不强制保留。
注释有地方不匹配,可自行修改。不匹配的原因是后期有些地方代码修改了,注释没有改
[mw_shl_code=c,true]
void Board_Init(void)
{
    RCC ->AHB1ENR |= 0x0000007F;    //PORT ABCDEFG 时钟使能
}
u8 PwmRun()
{
   
    RCC ->APB1ENR |= 1 << 2;        //使能TIM4
   
    RCC ->AHB1ENR |= 1 << 3;        //使能PortD时钟
   
    GPIO_Set(GPIOD, PIN14 | PIN15, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_100M, GPIO_PUPD_PU);             //复用, 输出,  上拉
   
    //PD14、PD15复用为TIM4的CH3和CH4
    GPIO_AF_Set(GPIOD, 14, 2);
    GPIO_AF_Set(GPIOD, 15, 2);
   
    TIM4 ->ARR = 84 - 1;
   
    TIM4 ->PSC = 0;
   
   
    TIM4 ->CCMR2 |= 6 << 4;                     //CH3 PWM模式1   先有效电平后无效电平  有效电平、无效电平是高还是低,由CCER的CCxP位决定
    TIM4 ->CCMR2 |= 6 << 12;                    //CH4 PWM模式1   先有效电平后无效电平  有效电平、无效电平是高还是低,由CCER的CCxP位决定
   
    TIM4  ->CCMR2 |= 1 << 3;                     //CH3 预装载使能
    TIM4  ->CCMR2 |= 1 << 11;                    //CH4 预装载使能
   
   
    TIM4 ->CCER |= 1 << 8;                      //OC3输出使能
    TIM4 ->CCER |= 1 << 12;                     //OC4输出使能
   
   
    TIM4 ->CCER &= ~(1 << 9);                   //OC3高电平有效
    TIM4 ->CCER &= ~(1 << 13);                  //OC4高电平有效
   
    TIM4 ->CCR3 = 21;
    TIM4 ->CCR4 = 63;
   
   
    TIM4 ->CR1 |= 1 << 7;                       //ARR寄存器缓冲
    //TIM4 ->BDTR |= 1 << 15;                     //MOE = 1
   
   
    TIM4 ->CR1 |= 1 << 0;                           //使能定时器4,输出PWM
   
    return 0;
   
   
}
//成功返回0,失败返回1:参数错误
u8 PulseParametersSet(u16 uwTime1, u16 uwTime2, u16 uwTime3, u16 uwTime4, u16 uwHoldLengthUs)
{
    //添加差异补偿或者使用非常好的元件
    u32 unArr;
    u16 uwSparkCnt, uwIgnRestCnt, uwSmplCnt, uwHoldCnt;
//    if(uwTime3 > uwTime1|| uwTime4 + uwHoldLengthUs > uwTime1)
//    {
//        return 1;
//    }
    unArr = (uwTime2 + uwTime1) * 2 - 1;
   
    uwSparkCnt = uwTime1 * 2;
    uwIgnRestCnt = uwTime3 * 2;
    uwSmplCnt = uwTime4 * 2;
    uwHoldCnt = (uwTime4 + uwHoldLengthUs) * 2;
    RCC ->APB2ENR |= 3 << 0;            //使能TIM1  TIM8时钟
    RCC ->AHB1ENR |= 1 << 0;            //使能PortA时钟
    RCC ->AHB1ENR |= 1 << 2;            //使能PortC时钟
    RCC ->AHB1ENR |= 1 << 6;            //使能PortE时钟
    GPIO_Set(GPIOC, PIN6 | PIN7 | PIN8 | PIN9, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_100M, GPIO_PUPD_PU);                 //复用, 输出,上拉
    GPIO_Set(GPIOE, PIN11 | PIN13 | PIN14, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_100M, GPIO_PUPD_PU);                     //复用, 输出,上拉
    GPIO_Set(GPIOA, PIN8, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_100M, GPIO_PUPD_PU);                                      //复用, 输出,上拉
    //PC6、7、8、9复用为TIM8的CH1、2、3、4
    GPIO_AF_Set(GPIOC, 6, 3);
    GPIO_AF_Set(GPIOC, 7, 3);
    GPIO_AF_Set(GPIOC, 8, 3);
    GPIO_AF_Set(GPIOC, 9, 3);

    //PE11、13、14复用为TIM1的CH2、3、4
    GPIO_AF_Set(GPIOE, 11, 1);
    GPIO_AF_Set(GPIOE, 13, 1);
    GPIO_AF_Set(GPIOE, 14, 1);
   
   
    //PA8复用为TIM1的CH1
    GPIO_AF_Set(GPIOA, 8, 1);

    TIM1 ->ARR = unArr;                         //自动装填值,该值与分频数决定PWM的周期长度(从而也确定频率)
    TIM8 ->ARR = unArr;                         //自动装填值,该值与分频数决定PWM的周期长度(从而也确定频率)
//    TIM1 ->PSC = 0;                        //分频器。经过unPsc个TIM1的周期后,TIM1的CNT计数器加1,CNT的数值达到unArr后,产生中断或者事件,然后从0开始计数   每个CNT为0.5us
//    TIM8 ->PSC = 0;                        //分频器。经过unPsc个TIM8的周期后,TIM8的CNT计数器加1,CNT的数值达到unArr后,产生中断或者事件,然后从0开始计数   每个CNT为0.5us
    TIM1 ->PSC = 84 - 1;                        //分频器。经过unPsc个TIM1的周期后,TIM1的CNT计数器加1,CNT的数值达到unArr后,产生中断或者事件,然后从0开始计数   每个CNT为0.5us
    TIM8 ->PSC = 84 - 1;                        //分频器。经过unPsc个TIM8的周期后,TIM8的CNT计数器加1,CNT的数值达到unArr后,产生中断或者事件,然后从0开始计数   每个CNT为0.5us
    TIM1 ->CCMR1 |= 6 << 4;                     //CH1 PWM模式1   先有效电平后无效电平  有效电平、无效电平是高还是低,由CCER的CCxP位决定
    TIM1 ->CCMR1 |= 6 << 12;                    //CH2 PWM模式1   先有效电平后无效电平  有效电平、无效电平是高还是低,由CCER的CCxP位决定
    TIM1 ->CCMR2 |= 6 << 4;                     //CH3 PWM模式1   先有效电平后无效电平  有效电平、无效电平是高还是低,由CCER的CCxP位决定
    TIM1 ->CCMR2 |= 6 << 12;                    //CH4 PWM模式1   先有效电平后无效电平  有效电平、无效电平是高还是低,由CCER的CCxP位决定

    TIM8 ->CCMR1 |= 6 << 4;                     //CH1 PWM模式1   先有效电平后无效电平  有效电平、无效电平是高还是低,由CCER的CCxP位决定
    TIM8 ->CCMR1 |= 6 << 12;                    //CH2 PWM模式1   先有效电平后无效电平  有效电平、无效电平是高还是低,由CCER的CCxP位决定
    TIM8 ->CCMR2 |= 6 << 4;                     //CH3 PWM模式1   先有效电平后无效电平  有效电平、无效电平是高还是低,由CCER的CCxP位决定
    TIM8 ->CCMR2 |= 6 << 12;                    //CH4 PWM模式1   先有效电平后无效电平  有效电平、无效电平是高还是低,由CCER的CCxP位决定

    TIM1  ->CCMR1 |= 1 << 3;                     //CH1 预装载使能
    TIM1  ->CCMR1 |= 1 << 11;                    //CH2 预装载使能
    TIM1  ->CCMR2 |= 1 << 3;                     //CH3 预装载使能
    TIM1  ->CCMR2 |= 1 << 11;                    //CH4 预装载使能
    TIM8  ->CCMR1 |= 1 << 3;                     //CH1 预装载使能
    TIM8  ->CCMR1 |= 1 << 11;                    //CH2 预装载使能
    TIM8  ->CCMR2 |= 1 << 3;                     //CH3 预装载使能
    TIM8  ->CCMR2 |= 1 << 11;                    //CH4 预装载使能

    TIM1 ->CCER |= 1 << 0;                      //OC1输出使能
    TIM1 ->CCER |= 1 << 4;                      //OC2输出使能
    TIM1 ->CCER |= 1 << 8;                      //OC3输出使能
    TIM1 ->CCER |= 1 << 12;                     //OC4输出使能
    TIM8 ->CCER |= 1 << 0;                      //OC1输出使能
    TIM8 ->CCER |= 1 << 4;                      //OC2输出使能
    TIM8 ->CCER |= 1 << 8;                      //OC3输出使能
    TIM8 ->CCER |= 1 << 12;                     //OC4输出使能

    TIM1 ->CCER &= ~(1 << 1);                   //OC1高电平有效
    TIM1 ->CCER &= ~(1 << 5);                   //OC2高电平有效
    TIM1 ->CCER &= ~(1 << 9);                   //OC3高电平有效
    TIM1 ->CCER |= 1 << 13;                     //OC4低电平有效
    TIM8 ->CCER |= 1 << 1;                      //OC1低电平有效
    TIM8 ->CCER &= ~(1 << 5);                   //OC2高电平有效
    TIM8 ->CCER &= ~(1 << 9);                   //OC3高电平有效
    TIM8 ->CCER &= ~(1 << 13);                  //OC4高电平有效


    PULSE1_SPARK = uwSparkCnt;
    PULSE1_IGN_RESET = uwIgnRestCnt;
    PULSE1_SMPL = uwSmplCnt;
    PULSE1_HOLD = uwHoldCnt;
   
   
    PULSE2_SPARK = uwSparkCnt;
    PULSE2_IGN_RESET = uwIgnRestCnt;
    PULSE2_SMPL = uwSmplCnt;
    PULSE2_HOLD = uwHoldCnt;
    TIM1 ->CR1 |= 1 << 7;                       //ARR寄存器缓冲
    TIM1 ->BDTR |= 1 << 15;                     //MOE = 1

    TIM8 ->CR1 |= 1 << 7;                       //ARR寄存器缓冲
    TIM8 ->BDTR |= 1 << 15;                     //MOE = 1
    return 0;
}

//成功返回0
u8 PulseOutputStart(void)
{
    u32 nus;
    nus = TIM8 ->ARR;
    if(TIM1 ->ARR != nus)
    {
        return 1;
    }
    nus += 2;
    nus /= 4;
    TIM8 ->CR1 |= 1 << 0;                           //使能定时器8,输出pulse1
    delay_us(nus);
    TIM1 ->CR1 |= 1 << 0;                           //使能定时器1,输出pulse2
    return 0;
}
void PulseOutputStop(void)
{
    TIM8 ->CR1 &= ~(1 << 0);                           //关闭定时器8,停止输出pulse1
    TIM1 ->CR1 &= ~(1 << 0);                           //关闭定时器1,停止输出pulse2
   
    //--zkek 这里要设置各输出至安全状态,比如,有些器件在PWM停止后,不允许长时间开启,就要置0
}
[/mw_shl_code]

回复

使用道具 举报

66

主题

364

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2015-6-18
在线时间
129 小时
 楼主| 发表于 2016-7-11 14:15:38 | 显示全部楼层
mack13013 发表于 2016-7-11 13:15
贴个代码给你参考一下吧。  TIM1,TIM8各输出4路,还可以各加三路互补输出的。
程序里的标记、注释什么的 ...

额  谢谢   我用TIM1复用输出PWM仿真可以看到输出波形  但是换成TIM8 不复用就不行  不知道为什么
回复

使用道具 举报

66

主题

364

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2015-6-18
在线时间
129 小时
 楼主| 发表于 2016-7-11 14:26:41 | 显示全部楼层
mack13013 发表于 2016-7-11 13:15
贴个代码给你参考一下吧。  TIM1,TIM8各输出4路,还可以各加三路互补输出的。
程序里的标记、注释什么的 ...

上面是TIM8通道1 没有复用,PC6输出PWM
下面是TIM1通道1 复用为PE9输出pwm

QQ截图20160711142444.jpg
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-10 13:49

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表