我是嵌入式编程的新手。我有一个带有2个头文件的PIC单片机:pic.h
和Timer_peripheral.h
。
在pic.h
中,定时器配置寄存器定义为:
__extension__ typedef struct tagT1CONBITS {
union {
struct {
unsigned :1;
unsigned TCS:1;
unsigned TSYNC:1;
unsigned :1;
unsigned TCKPS:2;
unsigned TGATE:1;
unsigned :6;
unsigned TSIDL:1;
unsigned :1;
unsigned TON:1;
};
struct {
unsigned :4;
unsigned TCKPS0:1;
unsigned TCKPS1:1;
};
};
} T1CONBITS;
并且在timer.h
中,某些宏已被定义为:
/* Timer1 Control Register (T1CON) Bit Defines */
#define T1_ON 0xffff /* Timer1 ON */
#define T1_OFF 0x7fff /* Timer1 OFF */
与微控制器数据表相对应。 unsigned
类型是16位。我尝试以这种方式将T1_ON分配给我的struct变量T1CONBITS
:
T1CONBITS=T1_ON // which is wrong.
我知道我可以初始化一个结构,但是我想在我的main函数中做一个赋值,我不想使用结构成员来做它:
T1CONBITS.TCS=1;
T1CONBITS.TSYNC=1;
有没有办法做到这一点?如果没有,为什么你认为timer.h
中的这些宏已被定义?
感谢您的任何见解
答案 0 :(得分:3)
这不起作用,因为您正在尝试为某个完全不相关的类型的变量分配数字。数字与结构的基础位模式匹配的事实是编译器并不关心的事情。
试试这个:
union BitsInt {
struct tagT1CONBITS con;
int bits;
};
T1CONBITS = ((union BitsInt){ .bits = T1_ON }).con;
您将一种类型的数据放入其中,您将获得与无关类型相同的数据。
(使用联合来转换位模式从最新的C标准开始有效。)
答案 1 :(得分:1)
预处理后
T1CONBITS=T1_ON;
就是这样:
T1CONBITS=0xffff;
要struct
变量只能分配相同类型的变量。
您可以通过这样做轻松地将T1CONBITS
设置为所有1
:
memset(&T1CONBITS, 0xff, sizeof(T1CONBITS));
答案 2 :(得分:1)
结构T1CONBITS的名称表示它用于访问T1CON的位。是否有noat还定义了一个寄存器T1CON wherby,你可以写下面的内容吗?
T1CON = T1_ON ;
更好的是,您可以按原样使用T1CONBITS,并且完全不需要T1_ON和T1_OFF:
T1CONBITS.TON = 0 ; // Off
T1CONBITS.TON = 1 ; // On
通过直接分配T1CON,您将所有其他位设置为1,这可能不是您想要的任何情况。相反,你会读取 - 修改 - 写入,这实际上是位访问只是更容易出错,更清晰。
答案 3 :(得分:0)
根据我的经验,编译器为某个微控制器提供的预先制作的寄存器映射是繁重的,不可读的和不可移植的。无论你的特定代码是否有意义,都没有人知道,因为每个编译器都会以不同的方式实现位字段。
如果您可以自行编写寄存器定义,请执行此操作。例如:
#define T1CON (*(uint16_t*)0x1234u) // some address
#define T1CON_TCS 0x4000u
#define T1CON_TSYNC 0x2000u
...
#define T1CON_TCKPS 0x0C00u
然后用标准C编程位设置惯用语设置位:
T1CON |= T1CON_TCS; // set this bit
T1CON &= ~T1CON_TCS; // clear this bit
设置属于同一组的多个位:
#define T1_ON 0x0C00u
#define T1_OFF 0x0400u
T1CON |= (T1CON_TCKPS & T1_ON);
等等。
(虽然请注意这将是read-modify-write,这可能是你想要的也可能不是。如果你必须使用普通位集(特殊情况,清除标志寄存器等),你通常会忽略按位逻辑,只需写入T1CON = T1CON_TCS | TSYNC;
并设置所有需要的位。但请注意,没有guartees,某个C代码是否提供读 - 修改 - 写或位设置是CPU和编译器相关的。反汇编以确保代码符合您的预期。)
这对于世界上的每个C编译器都是100%可移植的,并且每个使用嵌入式系统的C程序员都可以100%读取。