编程语言
首页 > 编程语言> > CAN 通讯 联合体 公用体 调试 使程序更整洁 好 20201226 C盘的路径 20201221

CAN 通讯 联合体 公用体 调试 使程序更整洁 好 20201226 C盘的路径 20201221

作者:互联网

目的: 本次主要针对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 发送 和 接收的参数  

 

 

 

需要注意的是  

在接收 和 发送 邮箱 中

 

 

 

 

 

 

 

 

源程序的百度网盘链接地址 

 

标签:candata,定义,CANRunMode,C盘,mode,Press,20201221,Bits,20201226
来源: https://www.cnblogs.com/bailongwei654321/p/14242064.html