OpenEdv-开源电子网

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

WWDG的喂狗问题(这个代码是不是有问题)

[复制链接]

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2015-10-7
在线时间
3 小时
发表于 2015-10-7 11:56:28 | 显示全部楼层 |阅读模式
5金钱
[mw_shl_code=c,true]u8 WWDG_CNT=0x7f; //初始化窗口看门狗 //tr :T[6:0],计数器值 //wr :W[6:0],窗口值 //fprer:分频系数(WDGTB),仅最低2位有效 //Fwwdg=PCLK1/(4096*2^fprer). void WWDG_Init(u8 tr,u8 wr,u32 fprer) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG时钟使能 WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT. WWDG_SetPrescaler(fprer);////设置IWDG预分频值 WWDG_SetWindowValue(wr);//设置窗口值 WWDG_Enable(WWDG_CNT); //使能看门狗 , 设置 counter . WWDG_ClearFlag();//清除提前唤醒中断标志位 WWDG_NVIC_Init();//初始化窗口看门狗 NVIC WWDG_EnableIT(); //开启窗口看门狗中断 } //重设置WWDG计数器的值 void WWDG_Set_Counter(u8 cnt) { WWDG_Enable(cnt);//使能看门狗 , 设置 counter . } void WWDG_IRQHandler(void) { WWDG_SetCounter(WWDG_CNT); //当禁掉此句后,窗口看门狗将产生复位 WWDG_ClearFlag(); //清除提前唤醒中断标志位 LED1=!LED1; //LED状态翻转 }[/mw_shl_code]
如果这里是
u8 WWDG_CNT=0x7f;
那么喂狗的时候
void WWDG_Set_Counter(u8 cnt)
{
   WWDG_Enable(cnt);//使能看门狗 , 设置 counter .
}

不是一直喂的是0x7f吗?那和初始化函数里面设置不是没有关系了吗?

是不是应该用    静态变量 static u8 WWDG_CNT=0x7f;  



原子哥 我第一次发帖,刚开始学,请多多关照!

最佳答案

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

回复【5楼】15721227: --------------------------------- 是的,这个是我们自己随便设定的一个数值,没有特别要求说非要设置为0x7f
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2015-9-21
在线时间
1 小时
发表于 2015-10-7 11:56:29 | 显示全部楼层
回复【5楼】15721227:
---------------------------------
是的,这个是我们自己随便设定的一个数值,没有特别要求说非要设置为0x7f
回复

使用道具 举报

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2015-10-7
在线时间
3 小时
 楼主| 发表于 2015-10-7 11:56:29 | 显示全部楼层
回复【6楼】宋学虎:
---------------------------------
这里设定的值不同的时候,灯闪的频率明显不一样,所有我觉得这里设定不同的值对程序应该是有影响的,
回复

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2015-10-7 13:45:20 | 显示全部楼层
没读明白问题,貌似C语言方面有待加强
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复

使用道具 举报

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2015-10-7
在线时间
3 小时
 楼主| 发表于 2015-10-7 14:00:37 | 显示全部楼层
回复【2楼】龙之谷:
---------------------------------
就是我觉得这个 WWDG_CNT放在前面定义的话,就应该算作全局变量,那么喂狗的时候不就一直送的是这个全局变量吗?  那
 WWDG_CNT=tr&WWDG_CNT;   //初始化WWDG_CNT.  在初始化之后还有作用吗,有些混乱,不好意思
回复

使用道具 举报

6

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2015-9-21
在线时间
1 小时
发表于 2015-10-7 14:02:11 | 显示全部楼层
代码没问题,是你没理解到位,这个只是设置计数器的最大值,每次喂狗后都是从0x7F重新计数循环
回复

使用道具 举报

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2015-10-7
在线时间
3 小时
 楼主| 发表于 2015-10-7 14:05:30 | 显示全部楼层
回复【4楼】宋学虎:
---------------------------------
我就是想说我每次都是从这里计数,那我何必要定义一个初始化的u8 tr 还来写入这个值有什么太大意义,那不是只要在0x40带0x7f 随便设定一个值就好?
回复

使用道具 举报

6

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2015-9-21
在线时间
1 小时
发表于 2015-10-7 14:15:37 | 显示全部楼层
回复【7楼】15721227:
嗯嗯,时间问题,计数器递减是有需要时间的,灯的闪亮有个自己的延时时间,但是对灯的闪亮没有太大影响
回复

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2015-10-7 14:18:42 | 显示全部楼层
你的混乱来自与对窗口看门狗理论知识的不熟悉和C语言的不扎实

既然学习看门狗,说明楼主应该不是工作项目上急用,静下心来学习单片机同时补充一下C语言方面知识,否则即使这里给你说清楚了,以后还会遇到很多此类情况
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复

使用道具 举报

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2015-10-7
在线时间
3 小时
 楼主| 发表于 2015-10-7 14:22:03 | 显示全部楼层
回复【8楼】宋学虎:
---------------------------------
我一直觉得 刚开始  u8 WWDG_CNT=0x7f;  这里应该设定一个有记忆的变量  ,那么 WWDG_CNT=tr&WWDG_CNT;   这一步之后就把值保存到WWDG_CNT里面去,  这样喂狗的时候就不至于一直是0x7f ,因为刚开始看到时候看到原子讲static 有记忆功能,所以我才想着第一步就用
 static   u8 WWDG_CNT=0x7f;   我c语言不太好,不知道这样对不对
回复

使用道具 举报

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2015-10-7
在线时间
3 小时
 楼主| 发表于 2015-10-7 14:23:01 | 显示全部楼层
回复【9楼】龙之谷:
---------------------------------
好吧,谢谢了。
回复

使用道具 举报

6

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2015-9-21
在线时间
1 小时
发表于 2015-10-9 19:43:02 | 显示全部楼层
回复【10楼】15721227:
---------------------------------
,static 是保持一个初值,在使用后是不会清除的,保持初值不变,那你的计数器就不会起到应有的效果
回复

使用道具 举报

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2015-10-7
在线时间
3 小时
 楼主| 发表于 2015-10-15 16:04:05 | 显示全部楼层
开一个自己的学习的帖子
回复

使用道具 举报

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2015-10-7
在线时间
3 小时
 楼主| 发表于 2015-10-15 16:05:06 | 显示全部楼层
定时器中的滤波器的解释     http://blog.sina.com.cn/s/blog_6c46cb860100mzgn.html

结合输入捕获的中断,可以轻松地实现按键的去抖动功能,而不需要软件的干预;这可是由硬件实现的去抖动功能,
大大节省了软件的开销和程序代码的长度。

每个定时器最多可以实现4个按键的输入,这个方法也可以用于键盘矩阵的扫描,而且因为是通过中断实现,软件不
需频繁的进行扫描动作

回复

使用道具 举报

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2015-10-7
在线时间
3 小时
 楼主| 发表于 2015-10-16 16:23:32 | 显示全部楼层
[mw_shl_code=c,true]u8 TPAD_Scan(u8 mode) { static u8 keyen=0; //0,可以开始检测;>0,还不能开始检测 u8 res=0; u8 sample=3; //默认采样次数为3次 u16 rval; if(mode) { sample=6; //支持连按的时候,设置采样次数为6次 keyen=0; //支持连按 } rval=TPAD_Get_MaxVal(sample); if(rval>(tpad_default_val+TPAD_GATE_VAL))//大于tpad_default_val+TPAD_GATE_VAL,有效 { if(keyen==0)res=1; //keyen==0,有效 printf("r:%d\r\n",rval); if(res) // printf("zzm\r\n"); // printf("%d\r\n",keyen); keyen=3; //至少要再过3次之后才能按键有效 [/mw_shl_code] [mw_shl_code=c,true]            //这里keyen的值在按键按下的时候除了显示有效位 [/mw_shl_code] [mw_shl_code=c,true]//没有其他什么意义,但是在松开时,他会使得下一次按下 //的时间是keyen*delay_ms(10),才可以。如果你设成100,那么下一次按键有效就需要1s钟 //这里至少要按下30ms才能起作用 和主函数里面的东西有关 } if(keyen)keyen--; return res; } [/mw_shl_code]
第一点
这里每次主函数中的while 都要调用TPAD_Scan函数
每次进来的时候都会设置res=0;如果mode=1时;那么

每次keyen =1;每次都能输出res=1;这时候连按指示灯的变化时间是10ms(由主函数进行设置的)

当keyen=0时 那么经过while循环之后keyen最后都为2,就是说,再也不能进入到res=1的条件;因此不能够支持连按了,
第二点
这里keyen的值在按键按下的时候除了显示有效位
没有其他什么意义,但是在松开时,他会使得下一次按下
的时间是keyen*delay_ms(10),才可以。如果你设成100,那么下一次按键有效就需要1s钟
[mw_shl_code=c,true]u16 TPAD_Get_Val(void) { TPAD_Reset(); while(TIM_GetFlagStatus(TIM5, TIM_IT_CC2) == RESET)//等待捕获上升沿 //只有在开了中断标志的时候才用TIM_GetITStatus 这个的源 //码看出哪个后者要求更严格 { // printf("ok"); if(TIM_GetCounter(TIM5)>TPAD_ARR_MAX_VAL-500)return TIM_GetCounter(TIM5);//超时了,直接返回CNT的值 }; return TIM_GetCapture2(TIM5); //直接返回通道2获取到的值 } [/mw_shl_code]
本来总觉得
[mw_shl_code=c,true]while(TIM_GetFlagStatus(TIM5, TIM_IT_CC2) == RESET)//等待捕获上升沿 //只有在开了中断标志的时候才用TIM_GetITStatus 这个的源 //码看出哪个后者要求更严格 { // printf("ok"); if(TIM_GetCounter(TIM5)>TPAD_ARR_MAX_VAL-500)return TIM_GetCounter(TIM5);//超时了,直接返回CNT的值 }; [/mw_shl_code]


这段会有死循环,其实不是这样的,你每次做这个while之前是有一个
TPAD_Reset();的,这一句就保证了你必须是在等待上升沿捕获的,先放电,然后 自动的等待捕获 ,如果没有捕获什么都不做,捕获来了,把捕获的值送出,这里有个疑惑是为什么不写
if(TIM_GetCounter(TIM5)>TPAD_ARR_MAX_VAL-500)return TIM_GetCounter(TIM5);//超时了,直接返回CNT的值
也可以呢,那捕获没来的时候 就连值都不返回? 什么时候会发生所谓的超时?
[mw_shl_code=c,true] [/mw_shl_code]
回复

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2015-10-16 17:28:33 | 显示全部楼层
回复【15楼】15721227:
---------------------------------
加油~~~~~
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复

使用道具 举报

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2015-10-7
在线时间
3 小时
 楼主| 发表于 2015-10-31 14:32:06 | 显示全部楼层

学习过程中迷茫了一段时间,但是还是加油!

 

 

如何学习

参考链接 http://blog.chinaunix.net/uid-20453876-id-1945039.html

http://blog.csdn.net/zhzht19861011/article/details/5974945

 

不管学51还是32位机,看书、视频是没有用的,最有效的方式是买块学习板,为不起广告嫌疑,不说太细,反正买个200块钱以内功能还行的就可以了。
两本电书是必备的:《STM32F10xxx参考手册》,《STM32F10xxx 固件库》,英文好的话直接去官网下英文,不好的话搜下中文版。
上网的时候少玩游戏,多上专业论坛,拿几个小的,能正常运行的例程跑跑,再根据自己的想法修改,修正,运行,不知不觉你就是高手了  -_^

 

笔者做任何事情前,习惯写一个计划——可能是在公司的时候,每天、每周、每月必写计划和总结养成的毛病,呵呵。正如在上一节中提及:我们要用一个月内上手STM32!我们开始考虑,如何更好地利用好这一个月的时间呢?我想起了第一天公司入职的情景。我的工作导师让我先领一台PC,安装必要的软件,然后告诉我近一个月的任务是什么。当时我很不屑,因为刚参加了公司组织的培训,以为自己啥都会,但是失败了。原因:盲目进行项目,没有一个计划。

没有计划的日子会很惨。就像每天早上醒来睁开眼睛,却不知道自己今天要干啥。闲话不说,我们谈一谈计划和时间安排。

笔者认为,学习STM32,实际上也是进行项目的过程。进行项目,就必须有项目进度文档,至少需要预计项目的耗时。虽然没有那么规范,但建议大家至少要给自己一个时间表:告诉自己从2010xy日至2010mn日,必须能够进行独立的项目开发。比如定为30天,把这个时间分三个阶段:

第一阶段:找感觉——谈及STM32,立即反应到调试的方法如何。

第二阶段:修改例程——按自己的意愿修改例程,让自己有点成就感。

第三阶段:主动攻击——给自己找一个小项目,把它实现出来。

每个阶段有一个目标后,再细化该目标到每天,写出每天要完成的任务。注意,每天的任务不可太多,否则时间太紧,完成不了当天的任务,反而会进入恶性循环,导致第二天、第三天,以后的任务也将无法完成。最终导致整个计划的失败。

每天的任务需要根据自己的具体情况来定。如果有充足的时间,可以安排多一些任务。如果每天只有2个小时,切记,宁可少安排任务,也不可追求加快项目进度。当然,心中有事情后,每天自然就会忙碌起来!你的学习生活会更加充实!

 

 

 

volatile的作用

volatile的作用是: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值.

简单地说就是防止编译器对代码进行优化.比如如下程序:

1

2

3

4

XBYTE[2]=0x55;

XBYTE[2]=0x56;

XBYTE[2]=0x57;

XBYTE[2]=0x58;

对外部硬件而言,上述四条语句分别表示不同的操作,会产生四种不同的动作,但是编译器却会对上述四条语句进行优化,认为只有XBYTE[2]=0x58(即忽略前三条语句,只产生一条机器代码)。如果键入volatile,则编译器会逐一的进行编译并产生相应的机器代码(产生四条代码).

 

 

原子的开发板,和我的屏幕的显示区别是: LCD_LED=0;                      //点亮背光


这里是不一样的

回复

使用道具 举报

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2015-10-7
在线时间
3 小时
 楼主| 发表于 2015-11-19 18:21:41 | 显示全部楼层

IIC总线读取240c的问题

       往这个rom写入数据的时候要注意   连续写入的时候

              if(key==KEY1_PRES)//KEY_UP按下,写入24C02

              {

                     LCD_Fill(0,170,239,319,WHITE);//清除半屏   

                    LCD_ShowString(30,170,200,16,16,"Start Write 24C02....");

                     AT24CXX_Write(0,(u8*)TEXT_Buffer,SIZE);

                     AT24CXX_Write(SIZE-1,(u8*)myTxt,6); //一定要注意当你写后面的字符时要用size-1\

                     因为size的大小包含有最后一个'\0'字符

                     LCD_ShowString(30,170,200,16,16,"24C02 Write Finished!");//提示传送完成

 

 


回复

使用道具 举报

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2015-10-7
在线时间
3 小时
 楼主| 发表于 2016-1-9 20:29:54 | 显示全部楼层
GPS模块调试
__packed是字节对齐的意思。
1__packed是字节对齐的意思。
比如说int float double char它的总大小是4 + 4 + 8 + 1 = 17
但如果不用__packed的话,系统将以默认的方式对齐(假设是4字节),那么它占4 + 4 + 8 + 4 = 20;(不足4字节以4字节补齐)。
align修饰数组后,可以去掉packed关键字了.  
对齐的使用:  
1.__align(num)  
   这个用于修改最高级别对象的字节边界。在汇编中使用LDRD或者STRD  
   就要用到此命令__align(8)进行修饰限制。来保证数据对象是相应对齐。  
   这个修饰对象的命令最大是8个字节限制,可以让2字节的对象进行4字节  
   对齐,但是不能让4字节的对象2字节对齐。  
  __align是存储类修改,他只修饰最高级类型对象不能用于结构或者函数对象。  
     
2.__packed   
__packed是进行一字节对齐  
  1.不能对packed的对象进行对齐  
  2.所有对象的读写访问都进行非对齐访问  
3.float及包含float的结构联合及未用__packed的对象将不能字节对齐  
4.__packed对局部整形变量无影响  
  5.强制由unpacked对象向packed对象转化是未定义,整形指针可以合法定  
  义为packed  
    __packed int* p;  //__packed int 则没有意义
'\0'不是指ASCII码值,它是字符,它的ASCII码值是0,也就是ASCII码表的第一个字符。  
sprintf((char *)dtbuf,"Validsatellite:%02d",gpsx.posslnum);               //用于定位的卫星数
使用sprintf函数直接可以将各个数据和这个字母连接在一起
Dtbuf 设置的缓存目录
后面是要显示连在一起的东西
l  复制地址的时候 u8 *p =buf ;  //这样赋值就正常
*p ; p = buf;却不可以  这要引起足够的重视


难点程序
//GPS校验和计算
//buf:数据缓存区首地址
//len:数据长度
//cka,ckb:两个校验结果.
void Ublox_CheckSum(u8 *buf,u16 len,u8*cka,u8*ckb)
{
       u16i;
       *cka=0;*ckb=0;
       for(i=0;i<len;i++)
       {
              *cka=*cka+buf;   //一个使用buf相加
              *ckb=*ckb+*cka;//统计所有的cka的值
       }
}
//str转换为数字,','或者'*'结束
//buf:数字存储区
//dx:小数点位数,返回给调用函数
//返回值:转换后的数值
int NMEA_Str2num(u8 *buf,u8*dx)
{
       u8*p=buf;
       u32ires=0,fres=0;
       u8ilen=0,flen=0,i;
       u8mask=0;
       intres;
       while(1)//得到整数和小数的长度
       {
              if(*p=='-'){mask|=0X02;p++;}//是负数   
              //这里使用mask只是遍历一遍查找特殊的字符以供后续程序使用
              if(*p==','||(*p=='*'))break;//遇到结束了
              if(*p=='.'){mask|=0X01;p++;}//遇到小数点了
              elseif(*p>'9'||(*p<'0'))    //有非法字符
              {      
                     ilen=0;
                     flen=0;
                     break;
              }      
              if(mask&0X01)flen++;//小数个数计数
              elseilen++;//              整数个数计数
              p++;       //P的目的是将数组先遍历一遍
       }
      
       //前面是遍历函数
      
       if(mask&0X02)buf++; //去掉负号
       for(i=0;i<ilen;i++)       //得到整数部分数据
       {  
              ires+=NMEA_Pow(10,ilen-1-i)*(buf-'0');
       }
       if(flen>5)flen=5;  //最多取5位小数
       *dx=flen;                   //小数点位数
       for(i=0;i<flen;i++)       //得到小数部分数据
       {  
              fres+=NMEA_Pow(10,flen-1-i)*(buf[ilen+1+i]-'0');  
              //分数就是在整数的后面的值,所以呀直接就是在ilen+1+i  就可以满足题意了
              //这里的1是指小数点的字符数
       }
       res=ires*NMEA_Pow(10,flen)+fres;  //这个处理了之后还是得到的是整数
       if(mask&0X02)res=-res;            
       returnres;
}           
//buf里面得到第cx个逗号所在的位置
//返回值:0~0XFE,代表逗号所在位置的偏移.
//      0XFF,代表不存在第cx个逗号                                                
u8 NMEA_Comma_Pos(u8 *buf,u8 cx)
{                     
       u8*p=buf;   //这里两个必须要都是同样的u8*不然不能加减
       while(cx)
       {              
              if(*buf=='*'||*buf<''||*buf>'z')return 0XFF;//遇到'*'或者非法字符,则不存在第cx个逗号
              if(*buf==',')cx--;
              buf++;
       }
       returnbuf-p;        
}
&#216;  下面这个程序可以实现字符串转数字的功能
if(*p == '-') {mask = 0x01;p++;}  //mask的作用就是做一个标志
                     if(*p==','||(*p=='*'))break;//遇到结束了前面的只是做个标记而已
                     if(*p=='.'){mask|=0X02;p++;}//遇到小数点了
                     elseif(*p>'9'||(*p<'0'))    //有非法字符
                     {
                            fcnt= 0;
                            icnt=0;
                            break;
                     }
                     if(mask&0x02)fcnt ++;
                     elseicnt++;
                     p++;// 最后这个p才是实现移动位置的关键
l  当一个程序中有传递过来的数组时(实质是指针)先复制指针地址再做其他的事情。先要遍历一遍特殊字符,用mask来标记。
l  抢占优先级和响应优先级,其实是一个中断所包含的两个优先级,其中前者是对抢占优先级的级别划分,后者是相同抢占优先级的优先级别的划分。
比如:
中断A抢占优先级比B高,那么A的中断可以在B里面触发,忽略响应优先级;
A和B抢占优先级相同,则A、B的响应优先级决定谁先响应。


程序学习:
1.     字符串转数字的方法。
2.     特定字符的检查,数据提取。
3.     多个逗号后面的数据提取。
4.     结构体数据的使用。

回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-22 00:27

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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