学习CANOpen 几周终于移植成功,现将移植教程做记录备份封装,方便以后使用
- CanFestival 移植
固定的头文件及C文件 很多例程有整理移植,偷懒拷贝别家的即可,再次感谢很多人。 -
添加C文件:(文件必须的子程序)
void setTimer(TIMEVAL value)
{}
TIMEVAL getElapsedTime(void)
{}
unsigned char canSend(CAN_PORT notused, Message *m)
{}
- 定时器配置:
- CAN 配置 500K 的配置速率
- 使用对象字典生成一个具有心跳(1000ms)的TestSlave文件
- 整体修改 步骤3的子程序 创建一个头文件
#include "canfestival.h"
# include "main.h"
#include "Knowledge.h"
#include "TestSlave.h"
#define CANOPEN_TIM_PERIOD 65535 //웓퉘㉵?
/* 웓퉘큉TIM?좢쐓? */
static TIMEVAL last_counter_val = 0;
static TIMEVAL elapsed_time = 0;
void setTimer(TIMEVAL value)
{
uint32_t timer = __HAL_TIM_GET_COUNTER(&htim6); // Copy the value of the running timer
elapsed_time += timer - last_counter_val;
last_counter_val = CANOPEN_TIM_PERIOD - value;
__HAL_TIM_SET_COUNTER(&htim6, CANOPEN_TIM_PERIOD - value);
HAL_TIM_Base_Start_IT(&htim6);
}
TIMEVAL getElapsedTime(void)
{
uint32_t timer = __HAL_TIM_GET_COUNTER(&htim6); // Copy the value of the running timer
if(timer < last_counter_val)
{
timer += CANOPEN_TIM_PERIOD;
}
TIMEVAL elapsed = timer - last_counter_val + elapsed_time;
return elapsed;
}
u8 CAN1_Send_Msg(Message *msg)
{
uint32_t txmailbox = 0;
uint32_t offset = 0;
CAN_TxHeaderTypeDef hdr;
u16 i=0;
hdr.IDE = CAN_ID_STD; // 멜D밐쐙쩄?
hdr.RTR = CAN_RTR_DATA; // ?豈폮줽쮛?
hdr.StdId = msg->cob_id;; // 쐙쩄멜D,榮靜1풭밃?쮌퉪0x7FF
hdr.ExtId = 0; // 챨좠멜D,榮頂9풭밃?쮌퉪0x1FFF
hdr.TransmitGlobalTime = DISABLE;
if(msg->rtr)
hdr.RTR = CAN_RTR_REMOTE;
else
hdr.RTR= CAN_RTR_DATA;
tCAN.TxHeader.DLC = msg->len;
for(i=0; i<msg->len; i++)
{
tCAN.TxData[i] = msg->data[i];
}
while(tCAN.TxHeader.DLC != 0)
{
hdr.DLC = tCAN.TxHeader.DLC > 8 ? 8 : tCAN.TxHeader.DLC; // 튛쮛씫웯
if(HAL_CAN_AddTxMessage(&hcan, &hdr, ((uint8_t *)tCAN.TxData) + offset, &txmailbox) != HAL_OK)
return 1;
offset += hdr.DLC;
tCAN.TxHeader.DLC -= hdr.DLC;
}
return 0;
}
unsigned char canSend(CAN_PORT notused, Message *m)
{
return CAN1_Send_Msg((Message *) m);;
}
/************************************************
줦튛?? 밐 TIMx_DispatchFromISR
졵 컢 밐 웓퉘왱웯(얩웓퉘큉햤?
쒩 튛 밐 ?
잇 ? ?밐 ?
? 밐 strongerHuang
*************************************************/
void TIMx_DispatchFromISR(void)
{
last_counter_val = 0;
elapsed_time = 0;
TimeDispatch();
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
// static tag_CanRxMsg RxMsg;
Message RxMsg;
u8 i ;
/* Get RX message */
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &tCAN.RxHeader, tCAN.RxData) != HAL_OK)
{
/* Reception Error */
Error_Handler();
}
RxMsg.cob_id = tCAN.RxHeader.StdId;
RxMsg.rtr = tCAN.RxHeader.RTR;
RxMsg.len = tCAN.RxHeader.DLC;
for(i = 0; i < tCAN.RxHeader.DLC; i++)
{
RxMsg.data[i] = (u8)tCAN.RxData[i];
}
canDispatch(&TestSlave_Data, &RxMsg);
}
7. 初始化文件添加
```c
unsigned char nodeID = 0x01; //쫰왞ID
setNodeId(&TestSlave_Data, nodeID);
setState(&TestSlave_Data, Initialisation);
setState(&TestSlave_Data, Operational);
备注:历经几周的CANOpen 学习,终于完成初步调试,本人确定可用 ,上图可证,具体的NMT,SDO,PDO相关参数还会继续添加调试,毕竟是要上项目的