为什么要用do……while(0)把宏定义的多条语句括起来?
答案:
这是一个奇怪的循环,它就只会运行一次,为什么不去掉外面的do{..}while结构呢?原来这也是非常巧妙的技巧。在工程中可能经常会引起麻烦,而上面的定义能够保证这些麻烦不会出现。下面是解释:
假设有这样一个宏定义
#define macro(condition) \
if(condition) dosomething()
现在在程序中这样使用这个宏:
if(temp)
else
一切看起来很正常,但是仔细想想。这个宏会展开成:
if(temp)
else
这时的else不是与第一个if语句匹配,而是错误的与第二个if语句进行了匹配
最近做一个电源用到了PWM,以前觉得很简单,不就是方波么 o(∩_∩)o...,搞了几天才知道要考虑的东西实在是太多了,光是AVR的相关寄存器就看了将近一个礼拜,有喜有忧啊。今天终于把AVR的PWM搞明白了,心得:注重实际,光看手册是没有用滴,放开手去做实验,不明白原理也要做,不要怕犯错误,一种模式一种模式的去试,效果——相当的好。
名词解释:
BOTTOM 计数器计到0x0000 时即达到BOTTOM
MAX
TOP
计数器(TCNT0)由0开始不断的作+1计数,计数到最大值时,计数器又返回到0开始作+1计数(单斜率),如此循环;
1.Profile
Profile: a collection of device descriptions which
together form a cooperative application
规范:就是为了多个设备,各种厂家的设备,可以互连,互通,而制定的约束。
例如:远程控制开关规范
2.Cluster
Cluster:is a container for one or more attributes
Attribute: a data entity which represents a physical quantity or
state
在许多中文资料里把它翻译成“簇”。
例如:
颜色:就是cluster
红,白,清,蓝,紫,黑:就是attributes
也可以,这样理解,温度就是cluster,温度值,具体的就是attributes。
在通信时,首先基于温度,这个cluster,这个属性来进行通信,具体传输的就是温度值这个属性。
从颜色的例子,就可以好理解,为什么一个cluster里,有多个attributes。
3.Identifier
简称:ID,可以理解为“标识符”
就是具体某一项东西的一个代号
就好像一个具体的人,要给它起个名字,有一个身份证号,这个身份证号就是ID
4.帧类型
总的帧类型,有两种,分别为:KVP 和 MSG
KVP: key-value
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
1. Zigbee来源于蓝牙:
一般把(void*)0定义为NULL
表示这是个空指针
void的含义
void的字面意思是“无类型”,void *则为“无类型指针”,void *可以指向任何类型的数据。
众所周知,如果指针p1和p2的类型相同,那么我们可以直接在p1和p2间互相赋值;如果p1和p2指向不同的数据类型,则必须使用强制类型
转换运算符把赋值运算符右边的指针类型转换为左边指针的类型。
例如:
float *p1;
int *p2;
p1 = p2;
其中p1 = p2语句会编译出错,提示“'=' : cannot convert from
'int *' to 'float *'”,必须改为:
p1 = (float *)p2;
而void *则不同,任何类型的指针都可以直接赋值给它,无需进行强制类型转换:
void *p1;
int *p2;
p1 = p2;
但这并不意味着,void *也可以无需强制类型转换地赋给其它类型的指针。因为“无类型”可以包容“有类型”,而“有类型”则不能包
容“无类型”。道理很简单,我们可以说“男人和女人都是人”,
(1)16位的无符号整型信号量的计数值(0-65535);
(2)由等待该信号量的任务组成的等待任务表。
Ucosii提供了6个对信号量进行操作的函数,当OS_CFG.H中OS_SEM_EN设为0时,所有的信号量函数都不能用,若配置为1时,OSSemCreate(),OSSemPend(),OSSemPost()必须有。
该函数用来建立一个信号量,并对它付初值。中断服务程序不能调用该函数