OpenEdv-开源电子网

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

函数初始化设置

[复制链接]

3

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2018-8-6
在线时间
17 小时
发表于 2018-8-19 20:23:23 | 显示全部楼层 |阅读模式
比如TIM_TimeBaseInit();函数中,加入上面的结构体成员没有全部设置,那么没设置的成员是什么状态呢?
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

756

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4163
金钱
4163
注册时间
2017-10-24
在线时间
251 小时
发表于 2018-8-19 20:40:22 | 显示全部楼层
根据C语言的标准,对于函数中设定的无static关键字标志的普通局部变量,其初始值是随机的;这里的结构体成员的值也不例外,也是随机的。

经过实验,确实如此:

3.png


代码在战舰板的串口实验上经过简单修改得来:

[mw_shl_code=c,true]#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"


/************************************************
ALIENTEKÕ½½¢STM32¿a·¢°åêμÑé4
′®¿úêμÑé
¼¼êõÖ§3Ö£owww.openedv.com
ìÔ±|μêÆì£ohttp://eboard.taobao.com
1Ø×¢Î¢DÅ1«Öúƽì¨Î¢DÅoÅ£o"ÕyμãÔ-×ó"£¬Ãa·Ñ»ñè¡STM32×êáÏ¡£
1ãÖYêDDÇòíμç×ó¿Æ¼¼óDÏT1«Ë¾  
×÷ÕߣoÕyμãÔ-×ó @ALIENTEK
************************************************/

typedef struct
{
        int a;
        float b;
        u8 c;
        u32 d;
}test;


void disp(void);


int main(void)
{               
        u16 t;  
        u16 len;       
        u16 times=0;
        delay_init();                     //Ñóê±oˉêy3õê¼»ˉ          
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //éèÖÃNVICÖD¶Ï·Ö×é2:2λÇàÕ¼óÅÏè¼¶£¬2λÏìó|óÅÏè¼¶
        uart_init(115200);         //′®¿ú3õê¼»ˉÎa115200
        LED_Init();                             //LED¶Ë¿ú3õê¼»ˉ
        KEY_Init();          //3õê¼»ˉóë°′¼üᬽóμÄó2¼t½ó¿ú
         printf("System OK.\r\n");
        while(1)
        {
                delay_ms(1000);
                disp();
        }         
}


void disp(void)
{
        test ttt;
       
        printf("ttt.a=%d\r\n",ttt.a);
        printf("ttt.b=%f\r\n",ttt.b);
        printf("ttt.c=%u\r\n",ttt.c);
        printf("ttt.d=%u\r\n",ttt.d);
       
        printf("\r\n==============\r\n");
}

[/mw_shl_code]

楼主可以亲自试一下。

局部变量初始化值查看.zip (315.49 KB, 下载次数: 41)
十六进制带我飞。
回复 支持 反对

使用道具 举报

31

主题

1955

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4524
金钱
4524
注册时间
2018-5-11
在线时间
947 小时
发表于 2018-8-20 17:07:49 来自手机 | 显示全部楼层
这个除了上面讨论的结构体成员初始值外,还与库函数的具体实现有关,有些有关联的值可能库函数会默认赋值,要彻底搞清楚就要去看一下库函数的具体代码。说到这里就体现出寄存器编程的优势了,手册上都列出了各寄存器的复位值,你只须修改你需要改变的内容就可以了
回复 支持 反对

使用道具 举报

3

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2018-8-6
在线时间
17 小时
 楼主| 发表于 2018-8-20 15:54:47 | 显示全部楼层
DreamWaterPro 发表于 2018-8-19 20:40
根据C语言的标准,对于函数中设定的无static关键字标志的普通局部变量,其初始值是随机的;这里的结构体成 ...

那么在这个结构体中
typedef struct
{
  uint16_t TIM_Prescaler;         /*!< Specifies the prescaler value used to divide the TIM clock.
                                       This parameter can be a number between 0x0000 and 0xFFFF */

  uint16_t TIM_CounterMode;       /*!< Specifies the counter mode.
                                       This parameter can be a value of @ref TIM_Counter_Mode */

  uint16_t TIM_Period;            /*!< Specifies the period value to be loaded into the active
                                       Auto-Reload Register at the next update event.
                                       This parameter must be a number between 0x0000 and 0xFFFF.  */

  uint16_t TIM_ClockDivision;     /*!< Specifies the clock division.
                                      This parameter can be a value of @ref TIM_Clock_Division_CKD */

  uint8_t TIM_RepetitionCounter;  /*!< Specifies the repetition counter value. Each time the RCR downcounter
                                       reaches zero, an update event is generated and counting restarts
                                       from the RCR value (N).
                                       This means in PWM mode that (N+1) corresponds to:
                                          - the number of PWM periods in edge-aligned mode
                                          - the number of half PWM period in center-aligned mode
                                       This parameter must be a number between 0x00 and 0xFF.
                                       @note This parameter is valid only for TIM1 and TIM8. */
} TIM_TimeBaseInitTypeDef;     

假如TIM_RepetitionCounter这个参数没有设置,而其他参数如下设置

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(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

        这个TIM_RepetitionCounter要是随机的话,TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);处理TIM_RepetitionCounte的时候怎么办?
回复 支持 反对

使用道具 举报

35

主题

560

帖子

2

精华

资深版主

Rank: 8Rank: 8

积分
17786
金钱
17786
注册时间
2018-3-3
在线时间
523 小时
发表于 2018-8-20 16:47:03 | 显示全部楼层
确实是随机的,但是普通定时器是没有TIM_RepetitionCounter这个东西的,只有高级定时器才有。所以高级定时器这个东西不能用默认的,普通的可以
/*
*
*
*
*
*
*/
回复 支持 反对

使用道具 举报

3

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2018-8-6
在线时间
17 小时
 楼主| 发表于 2018-8-20 18:35:15 | 显示全部楼层
首先,感谢二楼的方法!
我测试了PWM的配置!主函数代码如下:
#include "sys.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "usart.h"
#include "stm32f10x_tim.h"

TIM_OCInitTypeDef TIM_OCInitTypeDefStrue;

void test(void)
{
        printf("TIM_OCInitTypeDefStrue.TIM_OCMode=%d\r\n",TIM_OCInitTypeDefStrue.TIM_OCMode);
        printf("TIM_OCInitTypeDefStrue.TIM_OCNPolarity=%d\r\n",TIM_OCInitTypeDefStrue.TIM_OCNPolarity);
        printf("TIM_OCInitTypeDefStrue.TIM_OutputState=TIM_CounterMode_Up=%d\r\n",TIM_OCInitTypeDefStrue.TIM_OutputState);
        printf("TIM_OCInitTypeDefStrue.TIM_OCNIdleState=%d\r\n",TIM_OCInitTypeDefStrue.TIM_OCNIdleState);
        printf("TIM_OCInitTypeDefStrue.TIM_Pulse=%d\r\n",TIM_OCInitTypeDefStrue.TIM_Pulse);
        printf("TIM_OCInitTypeDefStrue.TIM_OCIdleState=%d\r\n",TIM_OCInitTypeDefStrue.TIM_OCIdleState);
        printf("TIM_OCInitTypeDefStrue.TIM_OutputNState=%d\r\n",TIM_OCInitTypeDefStrue.TIM_OutputNState);
       
        printf("\r\n ============== \r\n");
}

int main(void)
{
        TIM_OCInitTypeDefStrue.TIM_OCMode=TIM_OCMode_PWM2;
        TIM_OCInitTypeDefStrue.TIM_OCNPolarity=TIM_OCPolarity_High;
        TIM_OCInitTypeDefStrue.TIM_OutputState=TIM_OutputState_Enable;
       
        TIM_OC2Init(TIM3,&TIM_OCInitTypeDefStrue);
        delay_init();  //延时函数初始化
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //设置NVIC中断分组2:两位抢占优先级,两位响应优先级
        uart_init(115200);   //串口初始化为115200
        LED_Init();    //LED端口初始化
        KEY_Init();   //初始化相应函数
  while(1)
        {
         test();
                delay_ms(10000);
               
        }
       
       
}

输出结果:
TIM_OCInitTypeDefStrue.TIM_OCMode=112
TIM_OCInitTypeDefStrue.TIM_OCNPolarity=0
TIM_OCInitTypeDefStrue.TIM_OutputState=TIM_CounterMode_Up=1
TIM_OCInitTypeDefStrue.TIM_OCNIdleState=0
TIM_OCInitTypeDefStrue.TIM_Pulse=0
TIM_OCInitTypeDefStrue.TIM_OCIdleState=0
TIM_OCInitTypeDefStrue.TIM_OutputNState=0

==============

个人总结的话:就是假如配置,那么就是选取相应配置的值!假如没操作,就是0!好像和复位电平为0有关!

五楼的建议,我确实去看了,但C语言水平有限,没搞明白!
回复 支持 反对

使用道具 举报

3

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2018-8-6
在线时间
17 小时
 楼主| 发表于 2018-8-20 18:36:45 | 显示全部楼层
Psheng 发表于 2018-8-20 16:47
确实是随机的,但是普通定时器是没有TIM_RepetitionCounter这个东西的,只有高级定时器才有。所以高级定时 ...

确实如此!我也是当时随机打开文件举个例子,不过还是谢谢你!
回复 支持 反对

使用道具 举报

3

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2018-8-6
在线时间
17 小时
 楼主| 发表于 2018-8-20 18:38:12 | 显示全部楼层
warship 发表于 2018-8-20 17:07
这个除了上面讨论的结构体成员初始值外,还与库函数的具体实现有关,有些有关联的值可能库函数会默认赋值, ...

谢谢建议!说实话,库函数的实现,我很多地方都看不明白!具体我操作了下,在六楼!
回复 支持 反对

使用道具 举报

35

主题

560

帖子

2

精华

资深版主

Rank: 8Rank: 8

积分
17786
金钱
17786
注册时间
2018-3-3
在线时间
523 小时
发表于 2018-8-20 19:46:13 | 显示全部楼层
不一定是0的。你的栈区没有被污染 ,所以是0。
/*
*
*
*
*
*
*/
回复 支持 反对

使用道具 举报

3

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2018-8-6
在线时间
17 小时
 楼主| 发表于 2018-8-20 20:13:47 | 显示全部楼层
Psheng 发表于 2018-8-20 19:46
不一定是0的。你的栈区没有被污染 ,所以是0。

我的理解是,程序启动文件里,默认启动的时候是把这些寄存器的位,配置为0了,对吧?
回复 支持 反对

使用道具 举报

35

主题

560

帖子

2

精华

资深版主

Rank: 8Rank: 8

积分
17786
金钱
17786
注册时间
2018-3-3
在线时间
523 小时
发表于 2018-8-21 10:15:34 | 显示全部楼层
chenboyu 发表于 2018-8-20 20:13
我的理解是,程序启动文件里,默认启动的时候是把这些寄存器的位,配置为0了,对吧?

没有的,寄存器的值是芯片上电分配的默认值。但是栈是可以重复利用的,但是栈里面的数是不会清理的。所以栈里面是会保留上次别的函数的数据,你这个局部变量得到的栈区是其他函数释放的,这个得到的值就是不确定的。
/*
*
*
*
*
*
*/
回复 支持 反对

使用道具 举报

3

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2018-8-6
在线时间
17 小时
 楼主| 发表于 2018-8-21 10:50:54 | 显示全部楼层
Psheng 发表于 2018-8-21 10:15
没有的,寄存器的值是芯片上电分配的默认值。但是栈是可以重复利用的,但是栈里面的数是不会清理的。所以 ...

学习了,十分感谢!!!
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-11 19:51

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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