CAN总线通信应用

实验生产线环境检测系统构建

一、系统构成

 

 二、代码分析

 

//CAN总线配置
void CAN_User_Config(CAN_HandleTypeDef* hcan )  
{
	  CAN_FilterTypeDef  sFilterConfig;  
    HAL_StatusTypeDef  HAL_Status;  
    sFilterConfig.FilterBank = 0; //过滤器0   
    sFilterConfig.FilterMode =  CAN_FILTERMODE_IDMASK;//屏蔽位模式  
    sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //32位宽   
    sFilterConfig.FilterIdHigh = 0x0000;  //32位ID  
    sFilterConfig.FilterIdLow  = 0x0000;  
    sFilterConfig.FilterMaskIdHigh = 0x0000; //32位MASK  
    sFilterConfig.FilterMaskIdLow  = 0x0000;  
    sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; //接收到的报文放入到FIFO0中  
    sFilterConfig.FilterActivation = ENABLE; //激活过滤器    
    sFilterConfig.SlaveStartFilterBank  = 0;  
    HAL_Status=HAL_CAN_ConfigFilter(hcan, &sFilterConfig);  
    HAL_Status=HAL_CAN_Start(hcan);  //开启CAN     
    if(HAL_Status!=HAL_OK)  
    {  
        printf("开启CAN失败\r\n");  
    }  
    HAL_Status=HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING);     
    if(HAL_Status!=HAL_OK)  
    {  
        printf("开启挂起中段允许失败\r\n");         
    } 
}
//启动CAN总线
void can_start(void)
{
	HAL_CAN_Start(&hcan);   
}
//停止CAN总线
void can_stop(void)
{
	HAL_CAN_Stop(&hcan);  
}

//CAN数据发送函数
uint8_t Can_Send_Msg_StdId(uint16_t My_StdId,uint8_t len,uint8_t Type_Sensor)
{	
		CAN_TxHeaderTypeDef  TxMeg;   
    ValueType ValueType_t;  
    uint8_t vol_H,vol_L;  
    uint16_t i=0;  
    uint8_t data[8];  
  
    TxMeg.StdId=My_StdId;             // 标准标识符   
    TxMeg.ExtId=0x00;                       // 设置扩展标示符   
    TxMeg.IDE=CAN_ID_STD;   // 标准帧  
    TxMeg.RTR=CAN_RTR_DATA;           // 数据帧  
    TxMeg.DLC=len;                          // 要发送的数据长度  
    for(i=0;i<len;i++)  
    {  
        data[i]=0;  
    }  
      
    data[0] =   Sensor_Type_t;  
		data[3] =   (uint8_t)My_StdId&0x00ff;        //取低两位做ID  
    data[4] =  My_StdId>>8;   //高位在后
    printf("Can_Send_Msg_StdId >>My_StdId 标准帧ID= %x   \r\n",My_StdId);  
    printf("Can_Send_Msg_StdId >>Sensor_Type_t %d \r\n",data[0]);  
    ValueType_t=ValueTypes(Type_Sensor);  
    printf("Can_Send_Msg_StdId >>ValueType_t %d \r\n",ValueType_t);  
      
      
    switch(ValueType_t)  
    {  
        case Value_ADC:  
              
                    vol_H = (vol&0xff00)>>8;  
                    vol_L = vol&0x00ff;  
                    data[1]=vol_H;  
                    data[2]=vol_L;        
                    printf("Can_Send_Msg_StdId >> Value_ADC TxMessage.Data[1]=vol_L %d \r\n",data[1]);  
                    printf("Can_Send_Msg_StdId >> Value_ADC TxMessage.Data[2]=vol_L %d \r\n",data[2]);  
            break;  
        case Value_Switch:  
                    data[1]=switching;  
                    data[2]=0;  
            break;  
        case Value_I2C:  
                    data[1]=sensor_tem;  
                    data[2]=sensor_hum;  
                    printf("Can_Send_Msg_StdId >> Value_I2C TxMessage.Data[1]=vol_L %d \r\n",data[1]);  
                    printf("Can_Send_Msg_StdId >> Value_I2C TxMessage.Data[2]=vol_L %d \r\n",data[2]);   
            break;  
        default:  
            break;  
    }  
      
    if (HAL_CAN_AddTxMessage(&hcan, &TxMeg, data, &TxMailbox) != HAL_OK)  
    {  
        printf("Can send data error\r\n");  
    }  
    else  
    {  
        printf("Can send data success\r\n");  
    }  
  
    return 0;
}


//CAN中断回调函数
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)      
{
	CAN_RxHeaderTypeDef RxMeg;  
    uint8_t  Data[8] = {0};  
    HAL_StatusTypeDef   HAL_RetVal;  
    int i;  
      
    RxMeg.StdId=0x00;  
    RxMeg.ExtId=0x00;  
    RxMeg.IDE=0;  
    RxMeg.DLC=0;  
  
    HAL_RetVal=HAL_CAN_GetRxMessage(hcan,  CAN_RX_FIFO0, &RxMeg,  Data);  
    if ( HAL_OK==HAL_RetVal)  
    {                                         
        for(i=0;i<RxMeg.DLC;i++)  
        {    
            Can_data[i]= Data[i];  
            printf("%02X ",Data[i]);  
              
        }         
        printf("\r\n");  
        flag_send_data=1;  
    } 
}

        网关主函数

  while (1)
  {
    /* USER CODE END WHILE */
		if(1)
		{
			Value_Type=ValueTypes(Sensor_Type_t);
			switch(Value_Type)
			{
				case Value_ADC:                                    //光照 空气 火焰 可燃气体
					sensor_number=1;
					vol=Get_Voltage();
				  printf("vol=Get_Voltage  ===== %x \r\n",vol);				
					break;
				case Value_Switch:				                         //人体 红外 声音
					sensor_number=1; 
					switching=Switching_Value();	 
					printf("switching=Switching_Value== %d \r\n",switching);
					break;
				case Value_I2C:
					sensor_number=2;
				  SHT1x_get_temperature(&sensor_tem);           //温度
				  SHT1x_get_relative_humidity(&sensor_hum);     //湿度
				  printf("sensor_tem   ===== %d :;sensor_hum===%d \r\n",(int)sensor_tem,(int)sensor_hum);
					break;
				default:
					break;
			}	
			//把本块板子的传感数据发送到网关  
      Master_To_Gateway(Can_STD_ID, Value_Type, vol,  switching, sensor_hum, sensor_tem ); 
			
		}	
		HAL_Delay(1500);
		
		//发送从CAN总线接收的其他节点数据至网关  
		if(flag_send_data==1)  
		{     
				CAN_Master_To_Gateway( Can_data,9);   
				flag_send_data=0;  
		}  

		//USART1 通过M3主控模块配置工具配置采集传感器类型 或 或者CAN发送标准帧ID (注标准帧不能超过0 to 0x7FF)
		if(!usart1_data_fifo_is_empty())
		{			
			HAL_Delay(100);
			process_up();		
		} 
    /* USER CODE BEGIN 3 */
  }

        节点主函数

  while (1)
  {
    /* USER CODE END WHILE */
		if(1)
		{
			Value_Type=ValueTypes(Sensor_Type_t);
			switch(Value_Type)
			{
				case Value_ADC:                                    //光照 空气 火焰 可燃气体
					sensor_number=1;
					vol=Get_Voltage();
				  printf("vol=Get_Voltage  ===== %x \r\n",vol);				
					break;
				case Value_Switch:				                         //人体 红外 声音
					sensor_number=1; 
					switching=Switching_Value();	 
					printf("switching=Switching_Value== %d \r\n",switching);
					break;
				case Value_I2C:
					sensor_number=2;
				  SHT1x_get_temperature(&sensor_tem);           //温度
				  SHT1x_get_relative_humidity(&sensor_hum);     //湿度
				  printf("sensor_tem   ===== %d :;sensor_hum===%d \r\n",(int)sensor_tem,(int)sensor_hum);
					break;
				default:
					break;
			}	
			//把本块板子的传感数据发送到网关  
      Master_To_Gateway(Can_STD_ID, Value_Type, vol,  switching, sensor_hum, sensor_tem ); 
			
		}	
		HAL_Delay(1500);
		
		//发送从CAN总线接收的其他节点数据至网关  
		if(flag_send_data==1)  
		{     
				CAN_Master_To_Gateway( Can_data,9);   
				flag_send_data=0;  
		}  

		//USART1 通过M3主控模块配置工具配置采集传感器类型 或 或者CAN发送标准帧ID (注标准帧不能超过0 to 0x7FF)
		if(!usart1_data_fifo_is_empty())
		{			
			HAL_Delay(100);
			process_up();		
		} 
    /* USER CODE BEGIN 3 */
  }

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李今天摸鱼了嘛?

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值