根据网上前辈们的指示,现在已经能用CAN1发送,CAN2接收中断处理,可以实现了CAN互发通信了。但是当连续发送3个以上报文时,接收到的后面的报文将会丢失。但是在调试的时候又不会丢失,直接运行就会丢失。
我觉得是FIFO只有3级,只能储存3个报文的原因,但是现实情况需要连续发送很多报文,请教各位前辈如何实现好。
下面是我的程序主要代码:
//main.c文件
#include "stm32f10x.h"
#include "GLCD.h"
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
volatile TestStatus TestRx;
vu32 ret; /* for return of the interrupt handling */
u8 Row = 0;
TestStatus CAN_Interrupt(void);
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure PD.02, PD.03, PD.04 and PD.07 as Output push-pull */
// For STM3210B-LK1 use PD.02 -PC.07
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Configure CAN pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Configure CAN pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_Remap2_CAN1, ENABLE ); //重影射CAN IO脚到 PD0,PD1
/* Configure CAN2 pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure CAN2 pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_Remap_CAN2, ENABLE ); //重影射CAN2 IO脚到 PB5,PB6
}
//系统中断管理
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
/* enabling interrupt */
NVIC_InitStructure.NVIC_IRQChannel=CAN2_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//配置系统时钟,使能各外设时钟
void RCC_Configuration(void)
{
SystemInit();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOD
| RCC_APB2Periph_AFIO , ENABLE );
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1 | RCC_APB1Periph_CAN2, ENABLE);
}
//LCD上显示工程标题
void LCD_Configuration(void)
{
GLCD_init();
GLCD_clear(White);
GLCD_setTextColor(Blue);
GLCD_displayStringLn(Line1, " GoldBull");//在液晶上显示字符串
GLCD_displayStringLn(Line2, " CAN1 send");
GLCD_setTextColor(Red);
GLCD_displayStringLn(Line3, " CAN2 receive");
}
//配置所有外设
void Init_All_Periph(void)
{
RCC_Configuration();
LCD_Configuration();
GPIO_Configuration();
NVIC_Configuration();
}
int main(void)
{
Init_All_Periph();
TestRx = CAN_Interrupt();
if (TestRx == FAILED)
{
GPIO_SetBits(GPIOD, GPIO_Pin_7); //LED4
}
else
{
GPIO_SetBits(GPIOD, GPIO_Pin_3); //LED2
}
while(1)
{
}
}
/* 中断收发函数 */
TestStatus CAN_Interrupt(void)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CanTxMsg TxMessage;
u32 i = 0;
/* CAN register init */
CAN_DeInit(CAN1);
CAN_DeInit(CAN2);
CAN_StructInit(&CAN_InitStructure);
/* CAN cell init */
CAN_InitStructure.CAN_TTCM=DISABLE;
CAN_InitStructure.CAN_ABOM=DISABLE;
CAN_InitStructure.CAN_AWUM=DISABLE;
CAN_InitStructure.CAN_NART=DISABLE;
CAN_InitStructure.CAN_RFLM=DISABLE;
CAN_InitStructure.CAN_TXFP=DISABLE;
CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;
CAN_InitStructure.CAN_Prescaler=9;
CAN_Init(CAN1,&CAN_InitStructure);
CAN_Init(CAN2,&CAN_InitStructure);
/* CAN filter init */
CAN_FilterInitStructure.CAN_FilterNumber=14;
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0220;
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
/* CAN FIFO0 message pending interrupt enable */
CAN_ITConfig(CAN2,CAN_IT_FMP0, ENABLE);
CAN_ITConfig(CAN2,CAN_IT_FOV0, ENABLE);
/* transmit 1 message */
TxMessage.StdId=0x11;
TxMessage.ExtId=0;
TxMessage.IDE=CAN_ID_STD;
TxMessage.RTR=CAN_RTR_DATA;
TxMessage.DLC=8;
TxMessage.Data[0]=0x30;
TxMessage.Data[1]=0x31;
TxMessage.Data[2]=0x32;
TxMessage.Data[3]=0x33;
TxMessage.Data[4]=0x34;
TxMessage.Data[5]=0x35;
TxMessage.Data[6]=0x36;
TxMessage.Data[7]=0x37;
CAN_Transmit(CAN1,&TxMessage);
TxMessage.Data[0]=0x31;
CAN_Transmit(CAN1,&TxMessage);
TxMessage.Data[0]=0x32;
CAN_Transmit(CAN1,&TxMessage);
/*
ret = 0xFF;
i=0;
while((ret == 0xFF) && (i < 0xFFF))
{
i++;
}
//加上这一段代码就能接收到6条报文,但我不能每各3个报文就加一段这个吧
*/
TxMessage.Data[0]=0x33;
CAN_Transmit(CAN1,&TxMessage);
TxMessage.Data[0]=0x34;
CAN_Transmit(CAN1,&TxMessage);
TxMessage.Data[0]=0x35;
CAN_Transmit(CAN1,&TxMessage);
ret = 0xFF;
i=0;
while((ret == 0xFF) && (i < 0xFFF))
{
i++;
}
if (i == 0xFFF)
{
ret=0;
}
/* disable interrupt handling */
CAN_ITConfig(CAN2,CAN_IT_FMP0, DISABLE);
return (TestStatus)ret;
}
/* 中断响应函数 */
void CAN2_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
RxMessage.StdId=0x00;
RxMessage.ExtId=0x00;
CAN_Receive(CAN2,CAN_FIFO0, &RxMessage);
if((RxMessage.StdId==0x11) && (RxMessage.IDE==CAN_ID_STD)
&& (RxMessage.DLC==8))
{
ret = 1;
Row += 24;//液晶里每一行高度为24
GLCD_displayStringLn(Line3 + Row, RxMessage.Data);
}
else
{
ret = 0;
}
}
//can.c里
uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage)
{
uint8_t transmit_mailbox = 0;
/* Check the parameters */
assert_param(IS_CAN_ALL_PERIPH(CANx));
assert_param(IS_CAN_IDTYPE(TxMessage->IDE));
assert_param(IS_CAN_RTR(TxMessage->RTR));
assert_param(IS_CAN_DLC(TxMessage->DLC));
/* Select one empty transmit mailbox */
if ((CANx->TSR&TSR_TME0) == TSR_TME0)
{
transmit_mailbox = 0;
}
else if ((CANx->TSR&TSR_TME1) == TSR_TME1)
{
transmit_mailbox = 1;
}
else if ((CANx->TSR&TSR_TME2) == TSR_TME2)
{
transmit_mailbox = 2;
}
else
{
transmit_mailbox = CAN_NO_MB;
}
if (transmit_mailbox != CAN_NO_MB)
{
/* Set up the Id */
CANx->sTxMailBox[transmit_mailbox].TIR &= TMIDxR_TXRQ; //TIR清空
if (TxMessage->IDE == CAN_ID_STD)
{
assert_param(IS_CAN_STDID(TxMessage->StdId));
CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->StdId << 21) | TxMessage->RTR);
}
else
{
assert_param(IS_CAN_EXTID(TxMessage->ExtId));
CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->ExtId<<3) | TxMessage->IDE |
TxMessage->RTR);
}
/* Set up the DLC */
TxMessage->DLC &= (uint8_t)0x0000000F;
CANx->sTxMailBox[transmit_mailbox].TDTR &= (uint32_t)0xFFFFFFF0;
CANx->sTxMailBox[transmit_mailbox].TDTR |= TxMessage->DLC;
/* Set up the data field */
CANx->sTxMailBox[transmit_mailbox].TDLR = (((uint32_t)TxMessage->Data[3] << 24) |
((uint32_t)TxMessage->Data[2] << 16) |
((uint32_t)TxMessage->Data[1] << 8) |
((uint32_t)TxMessage->Data[0]));
CANx->sTxMailBox[transmit_mailbox].TDHR = (((uint32_t)TxMessage->Data[7] << 24) |
((uint32_t)TxMessage->Data[6] << 16) |
((uint32_t)TxMessage->Data[5] << 8) |
((uint32_t)TxMessage->Data[4]));
/* Request transmission */
CANx->sTxMailBox[transmit_mailbox].TIR |= TMIDxR_TXRQ; //TIR的TXRQ(最低位)为1则请求发送邮箱数据
}
return transmit_mailbox;
}
void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage)
{
/* Check the parameters */
assert_param(IS_CAN_ALL_PERIPH(CANx));
assert_param(IS_CAN_FIFO(FIFONumber));
/* Get the Id */
RxMessage->IDE = (uint8_t)0x04 & CANx->sFIFOMailBox[FIFONumber].RIR;
if (RxMessage->IDE == CAN_ID_STD)
{
RxMessage->StdId = (uint32_t)0x000007FF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 21);
}
else
{
RxMessage->ExtId = (uint32_t)0x1FFFFFFF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 3);
}
RxMessage->RTR = (uint8_t)0x02 & CANx->sFIFOMailBox[FIFONumber].RIR;
/* Get the DLC */
RxMessage->DLC = (uint8_t)0x0F & CANx->sFIFOMailBox[FIFONumber].RDTR;
/* Get the FMI */
RxMessage->FMI = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDTR >> 8);
/* Get the data field */
RxMessage->Data[0] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDLR;
RxMessage->Data[1] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 8);
RxMessage->Data[2] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 16);
RxMessage->Data[3] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 24);
RxMessage->Data[4] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDHR;
RxMessage->Data[5] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 8);
RxMessage->Data[6] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 16);
RxMessage->Data[7] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 24);
/* Release the FIFO */
CAN_FIFORelease(CANx, FIFONumber);
}
|
|