|
本帖最后由 dzzwoaizi 于 2015-12-29 15:14 编辑 今天看到有人转了我的帖子到某论坛里,不是我小气,希望这位仁兄在转的时候标明出处,谢谢(毕竟手打不容易). p, d- T3 K# P2 Y* _3 p (1)typedef, union 和 struct来处理位变量数据然后在同一处理数据例如: typedef union2 [% m9 A# C# V" M7 f$ c$ a { struct { u8 fBreak:1; u8 fBrock:1;5 s( W( p) \3 Z' U& u u8 fBarerr:1;7 O C1 `$ _) p# t) O2 z O u8 fBatLow:1; u8 fBatHig:1;2 ?; m/ ` l: _& b4 i, W5 V u8 fTrap:1; u8 fAmpErr:1;# L7 c9 |6 Y6 `* h6 V u8 fPwmDown:1;" ^) U: A, [5 }. E6 f& B }bit; u8 allbits;2 o: C3 ^9 N6 N5 _) s" i! D! K}Fgs_StopState;. s+ A; Z* s3 U5 d 在电机控制中或者其他控制中有很多标志位,例如刹车标志,低压,过压,过流标志等需要将在运动中的电机停止下来,我们在检测的时候只需要将为标量置一或置零,例如在定义一个联合体:Fgs_StopState Fstop;将某一位置一或清零就可以这么写:Fstop.bit.fAmpErr = 1;在处理数据的时候,我们便于将数据统一处理,所以再此调用 (xx) =allbits;就可以读出所有变量数据了。例如只要以上的变量只要有一个为一就将电机停止,那么在C语言中我们就可以这样:3 y' o9 C( X9 _ if(Fstop.allbits){ //电机停止运行} else {//电机继续运行}- H2 P) i- y4 {; L (2)如果遇到一个只能写不能读的寄存器,你该怎么做呢?还是利用typedef, union 和 struct 下面我们看一个程序 typedef union { struct {unsigned RA0 :1;* m& C9 [$ v; K- J) { unsigned RA1 :1;8 m% D6 v/ u C" ~# E unsigned RA2 :1;" P5 i K; Y4 u- R* l unsigned RA3 :1; unsigned RA4 :1;+ ~: |# f; l7 d unsigned RA5 :1;/ k6 ^; F) Y' h5 x+ ~4 N* w }; } PORTAbits_t; extern volatile PORTAbits_t PORTAbits @ 0x00C;; B7 c! g& e" C) U" |: r3 ]0 V 玩过PIC的人可能很熟悉这段代码,他是头文件里的一段IO的操作代码,我在利用国产单片机的时候遇到一个问题:这个寄存器只能写,不能读的,我想位操作,可能很多人认为简单例如:temp=temp|0x01;(temp为只写寄存器),不好意思在temp|0x01;这里已经读了temp了,即使编译通过通过了,你的数值也是不对的!!所以我大胆的利用以上的代码,嘿!既然可以了!的确很有意思! 有人会问 @ 0x00c是什么意思,我的理解是这个寄存器的地址啦,下面有官方的说明:& |4 j/ r7 Z9 ?) [- K# q" T1 A' H 全局变量地址修改器(@ Address): o8 B" s9 i" m5 N 您可以将全局变量分配给特定的地址与全局变量地址修改器。这些变量被称为“绝对变量”。他们是有用的用于访问内存映射I / O端口,如下语法:3 s! J( d3 Z' F Declaration = < TypeSpec > <Declarator>[@ <Address> | @“<Section >] [= <Initializer>];4 R! _) q" h' h* J" ? < TypeSpec >是类型说明符。 例如、int、char <Declarator>是全局对象的标识符, 例如 ,i, glob <Address> 是物体的绝对地址, 例如,0 xff04,0 x00 + 8 <Initializer>是初始化全局变量的值。 所以我们在操作的时候,就可以PORTAbits .RA0=1;就把第一位置高了,此代码和上面(1)的代码本质差多的,只是在特殊用法上还是突出很大的优势的! y' C) [, p( z6 v) a: m9 k6 ~. L # z4 s+ c+ U2 F4 g; L7 z 未完。。。。。待更新!!!1 x K/ o% W" S i0 p + G' |. S) K+ k8 F, n6 P% v: T |
微信公众号
手机版
* W; k6 |7 A$ u! N; g
typedef struct
{. W% w' B8 X K: e: F2 ?
union
{
u8 byte;
struct
{
u8 bit0:1;
u8 bit1:1;( b% B; b- z9 K; |
u8 bit2:1;
u8 bit3:1;
u8 bit4:1;
u8 bit5:1;1 [- K0 b. }+ h$ U& c4 X/ ]) }
u8 bit6:1;
u8 bit7:1;6 h4 ^! m# d; X4 y3 t$ ^
}FuntionFlag;//bits;
};
}Byte_def;! H* {$ Q' }3 J3 z; |3 w; I; g
我也分享一个,很好用的说。解析一下,bitx:1后的表示占一位,union是一个共用体。Byte_def EBK,那就可以直接用EBK.FuntionFlag.bit0。1 E2 N3 W3 _! v7 Q
在加上宏定义define就清晰很多了,#defined EBKbrake EBK.FuntionFlag.bit0( x( J" u& g1 [$ o; M
记得包含就可以了,& d |% J O; B- W$ t, S; P
可以用) g1 Z/ b0 e5 U5 e) y: v1 w6 s
#ifndef
#define
l8 {4 [; Q( P- ]. N* H
#endif! B2 c' W- S) F
来避免重复包含,然后中间你随便搞,用一个大的 H 文件把所有的模块h 文件包含进去,然后你会发现所有的变量都可以用了,不过变量的声明要加 extern 这个关键词就好了
随便打开一个诸如stm32f10x_gpio.h的文件" U' c, C2 j0 w) P- C' j! }
这里便有正确的用法.
是的,常用到所以经典啊
说的是,我忽略这个了
在累积,以后会慢慢写
谢谢大哥的分享!!非常感谢