一、 简介
CAN的基础知识在这里不做过多介绍,其他网站上讲解的很基础,因为CAN一次性只能接收1字节8位,所以在这里只介绍怎样让CAN能像串口那样一次性接收非常多的位。亲测有效,具体先看效果图。
在这里我的实现是通过两块STM32板子(可以是任何两块STM32F1和F4都行,为了兼容性我分别用的F1和F4),然后互相连接好硬件,通过CAN口,可以实现接收多字节数据保存到数组,以及多字节数据发送到另一块板子上。
二、效果图
1.CAN接收多字节保存到数组
2.can发送多字节函数查看
三、主要代码
3.F4_CAN多字节发送函数
/*********************************************************************
==========CAN1_Tx()函数========================
功能:CAN1口发送
输入:无;
输出:无。
*********************************************************************/
#if EN_CAN1_USE
void CAN1_Tx(void)
{
u8 i, j, k;
if(flagCan1Tx == TxStart)
{
for(j = 0; j < iCan1Tx/8; j ++)
{
for(i = 0; i < 8; i++)
{
Can1TxMsg.Data[i] = *pBufCan1Tx;
pBufCan1Tx ++;
}
if(CAN_Transmit(CAN1, &Can1TxMsg) == CAN_TxStatus_NoMailBox)
{
iCan1Tx = iCan1Tx -( 8*j + i);
flagCan1Tx = TxBusy;
return;
}
}
for(k = 0; k < iCan1Tx%8; k++)
{
Can1TxMsg.Data[k] = *pBufCan1Tx;
pBufCan1Tx++;
}
iCan1Tx = 0;
if(CAN_Transmit(CAN1, &Can1TxMsg) != CAN_TxStatus_NoMailBox)
{
flagCan1Tx = TxIdle;
}
else
{
flagCan1Tx = TxBusy;
}
}
if(flagCan1Tx == TxBusy)
{
if(CAN_Transmit(CAN1, &Can1TxMsg) != CAN_TxStatus_NoMailBox)
{
if(iCan1Tx == 0)
flagCan1Tx = TxIdle;
else
flagCan1Tx = TxStart;
}
}
if(flagCan1Tx == TxReady) //在定时器3中断函数里面调用
{
CAN1_Tx_Ready();
pBufCan1Tx = (u8*)bufCan1Tx;
flagCan1Tx = TxStart;
}
}
#endif
3.1 发送数组准备函数
/********CAN1发送数据准备************************/
void CAN1_Tx_Ready(void)
{
u8 i,checksum;
iCan1Tx = 0;
bufCan1Tx[iCan1Tx++] = 0xEB;
bufCan1Tx[iCan1Tx++] = 0xA5;
iCan1Tx++;
bufCan1Tx[iCan1Tx++] = 0x03; //接收数据完毕标志位 1接受完
//ReceiveFlag = 0;
bufCan1Tx[iCan1Tx++] = 0x03; //小车方向
bufCan1Tx[iCan1Tx++] = 0x07;
bufCan1Tx[iCan1Tx++] = 0x03;
bufCan1Tx[iCan1Tx++] = 0x04;
bufCan1Tx[iCan1Tx++] = 0x05;
bufCan1Tx[iCan1Tx++] = 0x06;
bufCan1Tx[iCan1Tx++] = 0x06;
bufCan1Tx[iCan1Tx++] = 0x07;
bufCan1Tx[iCan1Tx++] = 0x08;
bufCan1Tx[iCan1Tx++] = 0x09;
bufCan1Tx[iCan1Tx++] = 0x10;
bufCan1Tx[2] = iCan1Tx+1; //帧长
checksum = 0;
for(i = 2; i < iCan1Rx; i++ )
checksum ^= bufCan1Tx[i];
bufCan1Tx[iCan1Tx++] = checksum;
}
```c
//定时器3中断服务函数
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
{
if(flagCan1Tx == TxIdle)
flagCan1Tx = TxReady;
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位
}
主要代码如上!!!!F1和F4代码差不多一样的。
四、整体工程提供(F4和F1整体)
整体代码点击链接