OpenEdv-开源电子网

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

这个定时器的单脉冲为啥产生不出来?

[复制链接]

3

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2018-5-2
在线时间
16 小时
发表于 2022-9-10 19:37:15 | 显示全部楼层 |阅读模式
5金钱
做了一个用STM32F103RBT6芯片控制可控硅加热的实验,用TIM4作为单脉冲主时钟输出通过定时器内部链接到TIM2 (TIM4->TIM2,通道连接ITR3),TIM2产生占空比可调的pwm,在TIM2_CH2/CH3/CH4上产生三路周期10ms脉宽可调的单脉冲PWM。实际程序运行后TIM2_CH2/CH3/CH4上没有产生10ms脉宽单脉冲PWM,不知道到底问题在那儿,请求哪位大侠帮忙看下。(外部中断是10ms的交流过零信号)


以下是源代码:


void GPIOInit()   //一共10个PWM端口,初始化GPIOA与GPIOB端口
{
        GPIO_InitTypeDef  GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA, ENABLE); //开启端口时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

         //初始化定时器TIM1、TIM2、TIM3比较输出PWM管脚
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_6|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;// GPIOA端口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                  //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure);
       
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1;// GPIOB端口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                  //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //IO口速度为50MHz         
GPIO_Init(GPIOB, &GPIO_InitStructure);       
        //初始化外部触发中断管脚
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_6;            // GPIOB_Pin6中断输入端口
GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IPU;       //PB15设置成上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //IO口速度为50MHz         
GPIO_Init(GPIOB, &GPIO_InitStructure);
       
}


void TIM4_PWM_Init(u16 arr,u16 psc)
{  

        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);        //使能定时器4时钟


   //初始化TIM4
        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_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
       
        //产生触发信号
        TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable);//开启定时器4主从模式
        TIM_SelectOutputTrigger(TIM4, TIM_TRGOSource_Update);//选择TIM4输出TRGO信号
       
        TIM_Cmd(TIM4,ENABLE); //使能定时器
}


void TIM2_CH1_OPM_Init(u16 arr,u16 psc,u16 ccr)
{  
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_OCInitTypeDef  TIM_OCInitStructure;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);        //使能定时器2时钟
       
   //初始化TIM2
        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_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
        TIM_Cmd(TIM2,ENABLE);

//初始化TIM2  PWM模式         
        TIM_OCInitStructure.TIM_Pulse = ccr;
        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_OC2Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC2
        TIM_OC3Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC3
        TIM_OC4Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC4
       
       
        TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR2上的预装载寄存器
        TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR3上的预装载寄存器
        TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR4上的预装载寄存器
        TIM_ARRPreloadConfig(TIM2,ENABLE);   //立即生效,使能预装载寄存器
       
        TIM_SelectOnePulseMode(TIM2,TIM_OPMode_Single);//开启单脉冲模式
       
        TIM_SelectSlaveMode(TIM2,TIM_SlaveMode_Trigger);//设置从模式寄存器
        TIM_SelectInputTrigger(TIM2, TIM_TS_ITR3);//TIM4主连接从TIM2,TIM_TS_ITR3

       
}



void EXTIX_Init(void)
{

          EXTI_InitTypeDef EXTI_InitStructure;
          NVIC_InitTypeDef NVIC_InitStructure;

          RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);        //使能复用功能时钟

    //GPIOB.6 中断线以及中断初始化配置   上升沿触发
          GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource6);

          EXTI_InitStructure.EXTI_Line=EXTI_Line6;       
          EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;       
          EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发
          EXTI_InitStructure.EXTI_LineCmd = ENABLE;
          EXTI_Init(&EXTI_InitStructure);                 //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

    //中断优先级配置
          NVIC_InitStructure.NVIC_IRQChannel =  EXTI9_5_IRQn;                //使能PB6所在的外部中断通道
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;        //抢占优先级2
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;                                        //子优先级0
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                                //使能外部中断通道
          NVIC_Init(&NVIC_InitStructure);            //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

}







  //外部GPIOB_Pin_6中断服务程序
void EXTI9_5_IRQHandler(void)
{
        EXTI_ClearITPendingBit(EXTI_Line6);    //清除LINE6上的中断标志位  
       
  TIM4_PWM_Init(7200-1,100-1);                                    //主定时器:72000000/7200/100 = 100Hz
        TIM2_CH1_OPM_Init(10000-1,72-1,2000);        //从定时器:T = 72/72000000 * 1000000 = 1us
                                                                                                                                                                  //t_delay = 000 * T = 2ms
                                                                                                                                                                  //t_pluse = (10000 - 2000) * T = 8ms                       
       
}



int main(void)
{

        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
        GPIOInit();
        EXTIX_Init();
               
         
  while(1)
        {

        }         
}

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

使用道具 举报

11

主题

2131

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4728
金钱
4728
注册时间
2015-1-10
在线时间
590 小时
发表于 2022-9-15 16:56:20 | 显示全部楼层
思路跟7年前我做毕设差不多,不过我不是双定时器,单定时器就可以实现啊,TIM2的固定脉宽的单脉冲可以出来吗
回复

使用道具 举报

11

主题

2131

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4728
金钱
4728
注册时间
2015-1-10
在线时间
590 小时
发表于 2022-9-15 16:58:15 | 显示全部楼层
等等,你的main里面没有初始化定时器啊
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-26 04:13

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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