目的: 本次主要针对CAN协议 定义了共用体 例如一个帧 字节0 是运行模式
字节0里面的各个位的定义不一样, 可以对字节0 整体进行操作,可以对字节0里面
的某一个位进行操作
定义CANDATA 结构体数据类型
在com.c 文件中定义变量 并初始化
Candata=CANDATA_DEFAULTS 不能放在com init()中完成初始化
如果需要在函数中进行初始化, 是否需要应用 for()循环函数赋值 ?
接收回调函数 并没有在 主循环中 使用 但是 还是可以发现在 不断的接收
后面尝试一下 能不能把这个 CANRunMode 再变成位阈型 结构体
将上面的 candata 中的元素 定义成 位阈型 结构体
方法:
Typedef union _CANRunModeInfo
{
Uint 8 Byte ; //这样可以对一个字节 进行操作
Struct
{
Uint 8 DLC :4 ; //最低位
Uint8 undef : 2; //未定义
Uint8 mode:2 //运行模式 00 转速模式 01 转矩模式
}Bits
}CANRunModeInfo //这个数据类型就叫做 CANRunModeInfo
然后新定义结构体
typedef struct {
CANRunModeInfo CANRunMode //上位机器的运行模式
uint16 CANSetSpeed ; //上位机给定转速
uint8 Press1_pul; //压力传感器1的标幺值
uint8 Press2_pul; //压力传感器2的标幺值
} CANDATA;
现在 我想 能不能这样 赋值 如下图
candata.CANRunMode = Com_dataRxUBA[2][0];
第二 我能不能 这样操作
candata.CANRunMode.mode 这样就把 uint8 数据类型变量的最高两位CANRunMode
拿出来, 进而去判断
if(candata.CANRunMode.mode ==0) {}
if(candata.CANRunMode.mode ==1) {}
if(candata.CANRunMode.mode ==2) {}
if(candata.CANRunMode.mode ==3) {}
敲打完成程序 发现 candata.CANRunMode = Com_dataRxUBA[2][0];
是不行的。
我想需要这样操作 :
candata.CANRunMode.Byte= Com_dataRxUBA[2][0];
问题得到解决
改正以后
结构体的一个成员是联合体 数据类型 可以对位进行操作, 也可以整体操作
初始化
引用方式
用ZLG 调试 发现 联合体 按照位 操作 BITS 下的成员 可以使用
下午接下来需要完成的任务是
第一:更新到博客园
第二:将你这部分实现的方式写进路程图 软件概要设计说明书
举一反三:
对于CAN消息的格式 因为有很多消息, 而消息的 配置格式都一样,
这些消息的29位ID号的格式都是一样的。
这时候 可以 用指针变量 来指向不同消息的首地址, 这样就不用配置很多消息,
只用一个指针指向该消息就好。
定义数据类型
共用体 可以最整体操作 也可以对位阈进行操作
需要注意: 下图中是 DLC 是 最低位开始 不是最高位开始。
然后定义icanmasg message1 变量
以及指针变量 icanmsg *pcan
CheckmaciD 函数定义
void CheckMACID( iCANMSG *piCANMSG ,unsigned char ackcan)reentrant
调用方式
CheckMACID( & message1 ,0);
注意 上图中 调用的 message1 是 实际参数 。是前面定义的全局变量 ,
而在定义函数的过程中 piCANMSG 是形式参数 ,调用函数的时候,将实际参数 传递给形式参数然后 参与计算。
下图是给 形式参数变量的 元素赋值 然后 发送出去。
因为CAN消息很多,而且帧的结构都一样, 故采用指向 ICANMSG 格式指针的方式。
现在开始着手发送函数的配置
现在开始定义压力传感器的接入状态 然后 往上位机 上报的过程
我定义了共用体 4个
第7位 |
第6位 |
第5位 |
第4位 |
第3位 |
第2位 |
第1位 |
第0位 |
压力传感器4接入状态 |
压力传感器3接入状态 |
压力传感器2接入状态 |
压力传感器1接入状态 |
||||
|
|
|
|
|
|
|
|
我的想法是 判断了GPIO 口 如果是高的话
If(GPIO==1)
candata.Press_Sensor_Status.Bits.Press_Sensor1_status=1; //正常
else
candata.Press_Sensor_Status.Bits.Press_Sensor1_status=2; //故障
然后我想 发送邮箱如何赋值 用的是字节8
candata.Press_Sensor_Status.Bits.Press_Sensor1_status=2;
candata.Press_Sensor_Status.Bits.Press_Sensor2_status=2;
candata.Press_Sensor_Status.Bits.Press_Sensor3_status=2;
candata.Press_Sensor_Status.Bits.Press_Sensor4_status=2;
要把状态发送出去
直接就调用
dataTxUBA[]=candata.Press_Sensor_Status.Byte; 就可以了
下图的 idxMsgUB 实际上决定了消息通道 消息通道又是什么?
消息通道是什么 看下面的图
所以选择了3 也就是 选择了 ID号 是 0X19881205
更改前
更改以后:
然后我在主程序 的其他地方 进行赋值 为了方便起见
我就直接先在初始化com_init()中进行 赋值
测试条件
下载程序到TC234 开发板
测试ok 确实 是0XE8 0X03 14 1E 01 02 03 03 E4
总结 综上 :
假如我定义了 发送邮箱 定义了接收邮箱
先说 发送
因为我把气瓶传感器的接入状态 变成了 共用体 可以对位 对整体 分别操作
故在主程序中 可以对位阈型成员 进行赋值
然后 在CAN发送的时候 直接用 下面的赋值语句
如果在接收的过程
我把驱动电机的运行指令 做成了 位阈型 共用体 可以对整体和为进行 分别操作
把接收的数据 直接 赋予给 联合体 candata.CANRunMode.Byte
然后就可以对位阈型成员 进行判断
if( candata.CANRunMode.Bits.mode==0) // mode 判断如果是启动状态 则置位响应的标志位
{
}
直接 可以看到 位阈型成员 mode 就是 3
那么 就可以直接 在下面的 方括号中 置位启动标志
if( candata.CANRunMode.Bits.mode==0) // mode 判断如果是启动状态 则置位响应的标志位
{
}
我定义了一个结构体 存放的是CAN 发送 和 接收的参数
需要注意的是
在接收 和 发送 邮箱 中