OpenEdv-开源电子网

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

STM32F103定时器PWM模式时,通道的输出值恒为1

[复制链接]

1

主题

5

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2020-5-12
在线时间
6 小时
发表于 2020-5-12 09:37:25 | 显示全部楼层 |阅读模式
1金钱
本人的理解:定时器的PWM模式下,对应通道的输出为方波,且当CNT<CCR和CNT>CCR时,电平不相同。

于是就想试一下能否用串口打印对应情况下通道的输出值,发现不管CNT<CCR还是CNT>CCR,对应通道的输出值都为1。这个是为什么呢?

主函数测试代码如下(TIM3的初始化参考正点原子例程)
  1. int main(void)
  2. {
  3.     u8 n, key = 0,k = 0;
  4.     u16 led0pwmval=0;
  5.     u8 dir=1;
  6.     delay_init();                     //延时函数初始化
  7.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
  8.     uart_init(115200);         //串口初始化为115200
  9.     LED_Init();                             //LED端口初始化
  10.     KEY_Init();
  11.     TIM3_Int_Init(10000,71);        //频率为1微秒。
  12.     TIM_SetCompare2(TIM3,5000);
  13.     while(1)
  14.     {
  15.         key = KEY_Scan(0);

  16.         delay_ms(10);
  17.         if(key == KEY0_PRES)
  18.         {
  19.             printf("KEY0Press   ");
  20. //                TIM_SetCounter(TIM3, 5000);
  21. //                TIM_SetCompare2(TIM3,1000);
  22.             TIM_GenerateEvent(TIM3, TIM_EventSource_Update);
  23.             delay_ms(2);
  24.             printf("Counter = %5d, Compare2 = %5d, PBout = %ld\r\n", TIM_GetCounter(TIM3), TIM_GetCapture2(TIM3), PBout(5));
  25.         }

  26.         if(key == KEY1_PRES)
  27.         {
  28.             printf("KEY1Press   ");
  29. //                        TIM_SetCounter(TIM3, 5000);
  30. //                        TIM_SetCompare2(TIM3,6000);
  31.             TIM_GenerateEvent(TIM3, TIM_EventSource_Update);
  32.             delay_ms(7);
  33.             printf("Counter = %5d, Compare2 = %5d, PBout = %ld\r\n", TIM_GetCounter(TIM3), TIM_GetCapture2(TIM3), PBout(5));
  34.         }

  35.         n++;
  36.     }

  37. }
复制代码
串口输出如下:KEY0Press   Counter =  2001, Compare2 =  5000, PBout = 1
KEY1Press   Counter =  7001, Compare2 =  5000, PBout = 1
KEY0Press   Counter =  2001, Compare2 =  5000, PBout = 1
KEY1Press   Counter =  7001, Compare2 =  5000, PBout = 1

最佳答案

查看完整内容[请看2#楼]

参考103的手册(RM0008),第8章GPIO,图13标准IO结构
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
88
金钱
88
注册时间
2020-5-10
在线时间
25 小时
发表于 2020-5-12 09:37:26 来自手机 | 显示全部楼层
nmsl那没事了 发表于 2020-5-12 14:22
我程序中用的大部分宏都是正点原子例程中定义好的。
程序中PBout(n)宏定义如下:
#define PBout(n)   B ...

参考103的手册(RM0008),第8章GPIO,图13标准IO结构
回复

使用道具 举报

0

主题

71

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2016-1-5
在线时间
1 小时
发表于 2020-5-12 09:37:28 | 显示全部楼层
顶起!!!!!!
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2020-5-12
在线时间
6 小时
 楼主| 发表于 2020-5-12 11:00:46 | 显示全部楼层
顶一下
回复

使用道具 举报

0

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
88
金钱
88
注册时间
2020-5-10
在线时间
25 小时
发表于 2020-5-12 12:30:27 来自手机 | 显示全部楼层
你应该给出PBout的定义。万一程序里是 #define PBout() 1呢。
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2020-5-12
在线时间
6 小时
 楼主| 发表于 2020-5-12 14:22:25 | 显示全部楼层
fnems 发表于 2020-5-12 12:30
你应该给出PBout的定义。万一程序里是 #define PBout() 1呢。

我程序中用的大部分宏都是正点原子例程中定义好的。
程序中PBout(n)宏定义如下:
#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出
PBout(5),即读取PB5的输出数据寄存器。TIM3已经开启部分映射,TIM3的通道2映射到了PB5端口。
回复

使用道具 举报

8

主题

56

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
224
金钱
224
注册时间
2019-4-17
在线时间
34 小时
发表于 2020-5-12 14:41:20 | 显示全部楼层
把TIM3_Int_Init(10000,71);的代码发出来看看
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2020-5-12
在线时间
6 小时
 楼主| 发表于 2020-5-12 14:45:39 | 显示全部楼层
本帖最后由 nmsl那没事了 于 2020-5-12 14:47 编辑
杀马特彪少 发表于 2020-5-12 14:41
把TIM3_Int_Init(10000,71);的代码发出来看看
  1. void TIM3_Int_Init(u16 arr,u16 psc)
  2. {
  3.   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  4.         TIM_OCInitTypeDef TIM_OCInitTypeStruct;
  5.         NVIC_InitTypeDef NVIC_InitStructure;
  6.         GPIO_InitTypeDef GPIO_InitTypeStruct;
  7.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  8.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB| RCC_APB2Periph_AFIO, ENABLE); //时钟使能
  9.         
  10.         GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射  TIM3_CH2->PB5   
  11.         GPIO_InitTypeStruct.GPIO_Mode = GPIO_Mode_AF_PP;
  12.         GPIO_InitTypeStruct.GPIO_Pin = GPIO_Pin_5;
  13.         GPIO_InitTypeStruct.GPIO_Speed = GPIO_Speed_50MHz;
  14.         GPIO_Init(GPIOB, &GPIO_InitTypeStruct);
  15.                
  16.         //定时器TIM3初始化
  17.         TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值        
  18.         TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
  19.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
  20.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
  21.         TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
  22.         TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位

  23.         //pwm初始化
  24.         
  25.         TIM_OCInitTypeStruct.TIM_OCMode = TIM_OCMode_Active;
  26.         TIM_OCInitTypeStruct.TIM_OCPolarity = TIM_OCPolarity_High;
  27.         TIM_OCInitTypeStruct.TIM_OutputState = TIM_OutputState_Enable;
  28.         TIM_OC2Init(TIM3, &TIM_OCInitTypeStruct);
  29.         TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable);  //不使能TIM3在CCR2上的预装载寄存器
  30.         //TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
  31.         
  32.         //中断优先级NVIC设置
  33.         NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
  34.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
  35.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
  36.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  37.         NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器

  38.         
  39.         TIM_Cmd(TIM3, ENABLE);  //使能TIMx                                         
  40. }
复制代码
虽然设置了了中断优先级,但是中断并没有开启。
回复

使用道具 举报

0

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
88
金钱
88
注册时间
2020-5-10
在线时间
25 小时
发表于 2020-5-12 14:55:43 来自手机 | 显示全部楼层
nmsl那没事了 发表于 2020-5-12 14:22
我程序中用的大部分宏都是正点原子例程中定义好的。
程序中PBout(n)宏定义如下:
#define PBout(n)   B ...

一旦配置成alternative function模式后,输出电平的高低与否就不受odr的控制了。
2020-05-12 14.54.55.jpg
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2020-5-12
在线时间
6 小时
 楼主| 发表于 2020-5-12 15:05:14 | 显示全部楼层
本帖最后由 nmsl那没事了 于 2020-5-12 15:11 编辑
fnems 发表于 2020-5-12 14:56
参考103的手册(RM0008),第8章GPIO,图13标准IO结构

非常感谢,问题已经解决了。
总结如下:
在复用推挽输出模式下,对应端口的ODR寄存器确实不能反映正确的输出(因为根本没有用到这个寄存器)。正确的输出值可以在对应端口的IDR寄存器中找到。补上一张推挽输出模式下的清晰的端口结构图:

复用推挽输出模式

复用推挽输出模式
回复

使用道具 举报

0

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
88
金钱
88
注册时间
2020-5-10
在线时间
25 小时
发表于 2020-5-12 15:13:02 | 显示全部楼层
nmsl那没事了 发表于 2020-5-12 15:05
非常感谢,问题已经解决了。
总结如下:
在复用推挽输出模式下,对应端口的ODR寄存器确实不能反映正确 ...

总结的很好
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-29 17:06

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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