|
本帖最后由 dzzwoaizi 于 2015-12-29 15:14 编辑 # B" Y" I4 b9 I+ P# H; b/ H. H 今天看到有人转了我的帖子到某论坛里,不是我小气,希望这位仁兄在转的时候标明出处,谢谢(毕竟手打不容易) (1)typedef, union 和 struct来处理位变量数据然后在同一处理数据例如: typedef union { struct {* `# V) a8 Y+ i7 F L u8 fBreak:1; u8 fBrock:1; u8 fBarerr:1;' Y/ h1 ]. U! b7 _; g u8 fBatLow:1; u8 fBatHig:1;% _% H) g- g+ R' I u8 fTrap:1;) H# r4 A6 `( g" k* P5 ]* { u8 fAmpErr:1; u8 fPwmDown:1; }bit; u8 allbits;}Fgs_StopState; 在电机控制中或者其他控制中有很多标志位,例如刹车标志,低压,过压,过流标志等需要将在运动中的电机停止下来,我们在检测的时候只需要将为标量置一或置零,例如在定义一个联合体:Fgs_StopState Fstop;将某一位置一或清零就可以这么写:Fstop.bit.fAmpErr = 1;在处理数据的时候,我们便于将数据统一处理,所以再此调用 (xx) =allbits;就可以读出所有变量数据了。例如只要以上的变量只要有一个为一就将电机停止,那么在C语言中我们就可以这样:% E0 G2 v+ }3 Q, y2 H# M if(Fstop.allbits){ //电机停止运行} else {//电机继续运行} (2)如果遇到一个只能写不能读的寄存器,你该怎么做呢?还是利用typedef, union 和 struct 下面我们看一个程序 typedef union { struct {unsigned RA0 :1;) h% [6 j2 a5 V& S2 E0 d& f unsigned RA1 :1; unsigned RA2 :1;4 X& W# J& Q0 H6 W5 Y unsigned RA3 :1; unsigned RA4 :1; unsigned RA5 :1; };; P) U& v7 u) W, ^. J } PORTAbits_t; extern volatile PORTAbits_t PORTAbits @ 0x00C;/ O7 |) G( T$ K) k 玩过PIC的人可能很熟悉这段代码,他是头文件里的一段IO的操作代码,我在利用国产单片机的时候遇到一个问题:这个寄存器只能写,不能读的,我想位操作,可能很多人认为简单例如:temp=temp|0x01;(temp为只写寄存器),不好意思在temp|0x01;这里已经读了temp了,即使编译通过通过了,你的数值也是不对的!!所以我大胆的利用以上的代码,嘿!既然可以了!的确很有意思! 有人会问 @ 0x00c是什么意思,我的理解是这个寄存器的地址啦,下面有官方的说明: 全局变量地址修改器(@ Address)1 Z& S# Z. T6 D c r 您可以将全局变量分配给特定的地址与全局变量地址修改器。这些变量被称为“绝对变量”。他们是有用的用于访问内存映射I / O端口,如下语法:# ~/ ?7 c2 T/ }; [7 N" T" f Declaration = < TypeSpec > <Declarator>[@ <Address> | @“<Section >] [= <Initializer>];/ Z- |: C" b; C% l w5 p < TypeSpec >是类型说明符。 例如、int、char & J3 P: \3 f( W# u: o <Declarator>是全局对象的标识符, 例如 ,i, glob # K, F0 s6 h5 c <Address> 是物体的绝对地址, 例如,0 xff04,0 x00 + 8 $ m$ [* E# ?" l0 ~) A8 ~* Z/ N <Initializer>是初始化全局变量的值。 所以我们在操作的时候,就可以PORTAbits .RA0=1;就把第一位置高了,此代码和上面(1)的代码本质差多的,只是在特殊用法上还是突出很大的优势的! ! m B, J8 E: J0 m8 D + o4 B# w0 d4 a4 y/ ]+ x- l9 W5 T 未完。。。。。待更新!!!; ^$ c9 |% h4 f$ n( `4 M9 | 1 s+ D( ~8 }3 J( P. a) s5 K |
微信公众号
手机版
typedef struct " X, _% e# ]4 j: L7 Y( b5 q
{
union: J' p7 B7 V9 A* E+ i0 ~4 d1 k
{
u8 byte;5 u" ^( j3 [# l5 V- ?
struct/ v4 Y; I2 ?. k0 ]& j( A
{% [& T& q- @; Q! W( M; {
u8 bit0:1;* i9 f! R |& W5 k1 P
u8 bit1:1;
u8 bit2:1;4 p6 ~- d+ h# E1 _$ ? `# @. k
u8 bit3:1;
u8 bit4:1;
u8 bit5:1;
u8 bit6:1;3 G' i/ e: d( q/ P4 n4 d
u8 bit7:1;5 `$ b0 ]$ I8 ?8 {! x' i
}FuntionFlag;//bits;4 T( t9 y1 y1 g/ I! U' D& E$ t
}; 1 x8 @& }1 i5 i! y' y
}Byte_def;
我也分享一个,很好用的说。解析一下,bitx:1后的表示占一位,union是一个共用体。Byte_def EBK,那就可以直接用EBK.FuntionFlag.bit0。$ }, w3 @+ e" b6 ^
在加上宏定义define就清晰很多了,#defined EBKbrake EBK.FuntionFlag.bit0
记得包含就可以了,, T e8 S( ]8 {: s/ X2 y
可以用
#ifndef* I# u3 h- e6 x# d5 a! v a; M8 { b" c
#define - x7 h7 [4 ~ E0 i+ _+ t
#endif
来避免重复包含,然后中间你随便搞,用一个大的 H 文件把所有的模块h 文件包含进去,然后你会发现所有的变量都可以用了,不过变量的声明要加 extern 这个关键词就好了
随便打开一个诸如stm32f10x_gpio.h的文件8 i4 h4 p3 e5 J* _8 f8 b
这里便有正确的用法.
是的,常用到所以经典啊
说的是,我忽略这个了
在累积,以后会慢慢写
谢谢大哥的分享!!非常感谢