你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

PWM仿真有波形,下载没有输出

[复制链接]
laoguren1122 提问时间:2014-11-21 20:52 /
如题,程序里有两个功能,一是定时器1输出两路PWM,单独仿真和下载进去没有问题,都有输出;
二是通过定时器2周期性中断改变定时器1的脉宽,实现脉宽调节功能,加上这个功能后,仿真可以实现,下载后没输出
什么原因呢?
void TIM1_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;
// NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //使能定时器3时钟

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9; //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
GPIO_ResetBits(GPIOA,GPIO_Pin_8|GPIO_Pin_9);
   //初始化TIM1
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned3;  //TIM向上计数模式
// TIM_TimeBaseStructure.TIM_RepetitionCounter = 10;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC1Init(TIM1, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
  TIM_OC2Init(TIM1, &TIM_OCInitStructure);

// TIM_ClearFlag(TIM1, TIM_FLAG_Update); //清中断,以免一启用中断后立即产生中断
// TIM_CtrlPWMOutputs(TIM1,ENABLE);
// TIM_Cmd(TIM1, ENABLE);  //使能TIM3

}

void TIM3_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能

TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

TIM_Cmd(TIM3, ENABLE);  //使能TIMx外设

}





收藏 评论11 发布时间:2014-11-21 20:52

举报

11个回答
laoguren1122 回答时间:2014-11-21 20:53:16
本帖最后由 laoguren1122 于 2014-11-21 20:54 编辑

extern u16 Pulse1,Pulse2;
extern u16  Pulse_Add; // 5%

//定时器3中断服务程序
void TIM3_IRQHandler(void)   //TIM3中断
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源

if(Pulse_Add==0)
{ TIM_SetCompare1(TIM1,500);
   TIM_SetCompare2(TIM1,500);
}
else
{Pulse_Add=Pulse_Add-25;
    Pulse1=500+Pulse_Add;
    Pulse2=500-Pulse_Add;
TIM_SetCompare1(TIM1,Pulse1);
    TIM_SetCompare2(TIM1,Pulse2);
}
}
// TIM_CtrlPWMOutputs(TIM1,ENABLE);
// TIM_Cmd(TIM1, ENABLE);  //使能TIM3

}

int main(void)
{
// u16 led0pwmval=0;
// u8 dir=1;
delay_init();     //延时函数初始化  
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
// uart_init(9600); //串口初始化为9600
// LED_Init();     //LED端口初始化
// TIM3_PWM_Init(899,0); //不分频。PWM频率=72000/900=8Khz
    TIM3_Int_Init(999,7199);
  TIM1_PWM_Init(999,0);        //预分频9,PWM频率=72000000/1000=72khz    定时器输出频率的计算公式:f(OC1) = 72,000,000 / (ARR - 1)*(PSC - 1);
TIM_SetCompare1(TIM1,500+475);
TIM_SetCompare2(TIM1,500-475);
TIM_CtrlPWMOutputs(TIM1,ENABLE);
TIM_Cmd(TIM1, ENABLE);
TIM_Cmd(TIM3, ENABLE);
    while(1)
  {  }
}file:///c:/users/administrator/appdata/roaming/360se6/User Data/temp/2dafc4b100a5b1e6648d038b530e1b2f_655.jpgfile:///c:/users/administrator/appdata/roaming/360se6/User Data/temp/2dafc4b100a5b1e6648d038b530e1b2f_655.jpg


下载进板子就没输出,为什么呢?可以确定管脚没问题,因为单独不变占空比可以有输出的
8.jpg
laoguren1122 回答时间:2014-11-22 20:06:11
没人遇到过么,或者哪位大侠用我的程序自己试试呢?
沐紫 回答时间:2014-11-24 09:26:54
帮顶,求大侠帮助
netlhx 回答时间:2014-11-24 11:42:31
全局变量前面加上volatile试试看
laoguren1122 回答时间:2014-11-25 10:52:49
netlhx 发表于 2014-11-24 11:42
全局变量前面加上volatile试试看

谢谢大侠,我试试,大侠提醒了我看来应该定位到编译器的优化问题上
laoguren1122 回答时间:2014-11-25 18:14:29
好像也不行,另外我试了另一种做法,在主函数里可以实现PWM输出。
        while(1)
        {  
                delay_ms(10);         
                if(Pulse_Add==0)
                        {         TIM_SetCompare1(TIM1,500+0);
                        TIM_SetCompare2(TIM1,500-0);
                        }
                else
                        {Pulse_Add=Pulse_Add-1;
                    Pulse1=500+Pulse_Add;
                    Pulse2=500-Pulse_Add;
                        TIM_SetCompare1(TIM1,Pulse1);
                    TIM_SetCompare2(TIM1,Pulse2);
                        }
                 //  TIM_CtrlPWMOutputs(TIM1,ENABLE);
         //  TIM_Cmd(TIM1, ENABLE);  //使能TIM3
          
        }
和用定时器的原理一样的,10ms改变一次占空比,怎么回事呢?用T3定时输出就是没有         
wenyangzeng 回答时间:2014-11-25 20:01:15
你把这2句屏蔽掉了,PWM可能就没有输出了吧:
// TIM_CtrlPWMOutputs(TIM1,ENABLE);
// TIM_Cmd(TIM1, ENABLE);
laoguren1122 回答时间:2014-11-26 12:54:16
wenyangzeng 发表于 2014-11-25 20:01
你把这2句屏蔽掉了,PWM可能就没有输出了吧:
// TIM_CtrlPWMOutputs(TIM1,ENABLE);
// TIM_Cmd(TIM1, ENAB ...

主程序里面有,这个屏蔽了也可以的,有输出。
现在就是用在中断里改变占空比没输出,在while里改变有输出,其他都一样,怎么回事?
wenyangzeng 回答时间:2014-11-26 22:21:19
laoguren1122 发表于 2014-11-26 12:54
主程序里面有,这个屏蔽了也可以的,有输出。
现在就是用在中断里改变占空比没输出,在while里改变有输出 ...

你要随时改变TIM3的定时时长应该是在中断中改变定时器3 的计数值,看你这个函数头,感觉你是随时进行TIM3初始化:void TIM3_Int_Init(u16 arr,u16 psc)
是否由此引起?
laoguren1122 回答时间:2014-11-30 15:42:28
wenyangzeng 发表于 2014-11-26 22:21
你要随时改变TIM3的定时时长应该是在中断中改变定时器3 的计数值,看你这个函数头,感觉你是随时进行TIM3 ...

楼上误解我的程序了,TIM3的定时时长是不变的,主函数里已经定下来是10ms,我在TIM3的中断里改变的是TIM1的占空比,TIM3本身的定时值不变的
laoguren1122 回答时间:2014-12-6 11:02:37
自己顶一下

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版