CAN单设备环回模式代码

1.CAN设备时钟赋能和GPIO口时钟赋能

	GPIO_InitTypeDef GPIO_InitStrcture;
	CAN_InitTypeDef CAN_InitStrcture;
	CAN_FilterInitTypeDef CAN_FilterInitStrcture;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);

2.GPIO口初始化,PA12为TX设置为复用推挽输出,PA11为RX设置为上拉输入。

	GPIO_InitStrcture.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStrcture.GPIO_Pin=GPIO_Pin_12;
	GPIO_InitStrcture.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStrcture);
	
	GPIO_InitStrcture.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStrcture.GPIO_Pin=GPIO_Pin_11;
	GPIO_InitStrcture.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStrcture);

3.CAN设备的初始化,CAN设备和其他设备的区别是没有CMD函数来驱动CAN设备,只需要初始化即可

//配置CAN设备
	//CAN_InitTypeDef CAN_InitStrcture;
	CAN_InitStrcture.CAN_Mode=CAN_Mode_LoopBack;//环回模式,CAN发出的报文自己接收且发送到主线上
	CAN_InitStrcture.CAN_Prescaler=48;    //波特率=36M/48/(1+2+3)=125k
	CAN_InitStrcture.CAN_BS1=CAN_BS1_2tq;
	CAN_InitStrcture.CAN_BS2=CAN_BS2_3tq;
	CAN_InitStrcture.CAN_SJW=CAN_SJW_2tq;
	CAN_InitStrcture.CAN_NART=DISABLE;//置1,关闭自动重传,CAN报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失);置0,自动重传,CAN硬件在发送报文失败时会一直自动重传直到发送成功
	CAN_InitStrcture.CAN_TXFP=DISABLE;//置1,优先级由发送请求的顺序来决定,先请求的先发送;置0,优先级由报文标识符来决定,标识符值小的先发送(标识符值相等时,邮箱号小的报文先发送)
	CAN_InitStrcture.CAN_RFLM=DISABLE;//置1,接收FIFO锁定,FIFO溢出时,新收到的报文会被丢弃;置0,禁用FIFO锁定,FIFO溢出时,FIFO中最后收到的报文被新报文覆盖
 	CAN_InitStrcture.CAN_AWUM=DISABLE;//置1,自动唤醒,一旦检测到CAN总线活动,硬件就自动清零SLEEP,唤醒CAN外设;置0,手动唤醒,软件清零SLEEP,唤醒CAN外设
	CAN_InitStrcture.CAN_TTCM=DISABLE;
	CAN_InitStrcture.CAN_ABOM=DISABLE;
	CAN_Init(CAN1,&CAN_InitStrcture);
	

4.配置CAN的过滤器

//配置CAN的过滤器
	//CAN_FilterInitTypeDef CAN_FilterInitStrcture;
	CAN_FilterInitStrcture.CAN_FilterNumber=0;//选择使用哪一个过滤器
	CAN_FilterInitStrcture.CAN_FilterIdHigh=0x0000;//R1高16位,这里选择屏蔽模式,全ID通过
	CAN_FilterInitStrcture.CAN_FilterIdLow=0x0000;//R1低16位
	CAN_FilterInitStrcture.CAN_FilterMaskIdHigh=0x0000;//R2高16位
	CAN_FilterInitStrcture.CAN_FilterMaskIdLow=0x0000;//R2低16位
	CAN_FilterInitStrcture.CAN_FilterScale=CAN_FilterScale_32bit;//过滤器位宽
	CAN_FilterInitStrcture.CAN_FilterMode=CAN_FilterMode_IdMask;//屏蔽模式
	CAN_FilterInitStrcture.CAN_FilterActivation=ENABLE;//激活过滤器
	CAN_FilterInitStrcture.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//选择报文存入哪一个FIFO中
	CAN_FilterInit(&CAN_FilterInitStrcture);

5.CAN设备发送函数

使用函数传递结构体数值

void MyCAN_Transmit(uint32_t ID,uint8_t Length,uint8_t *Data)
{
	uint8_t i;
	uint8_t TransmitMailbox;
	uint32_t time;
	CanTxMsg TxMessage;
	TxMessage.StdId=ID;//标准模式时有用
	TxMessage.ExtId=ID;//扩展模式时有用
	TxMessage.IDE=CAN_Id_Standard;//标准模式
	TxMessage.RTR=CAN_RTR_Data;//数据报文
	TxMessage.DLC=Length;
	for(i=0;i<Length;i++)
	{
		TxMessage.Data[i]=Data[i];
	}
	TransmitMailbox =CAN_Transmit(CAN1,&TxMessage);//接收CAN_Transmit此方法返回的值,代表哪个邮箱接收数据
	while(CAN_TransmitStatus(CAN1,TransmitMailbox) !=CAN_TxStatus_Ok)//等待发送成功
	{
		time++;
		if(time>100000)
		{
			break;
		}
	}
}

6.判断FIFO 0 是否接收到数据报文

CAN_MessagePending此函数返回0表示FIFO 0 和1 都没收到报文

uint8_t MyCAN_ReceiveFlag(void)//判断FIFO 0是否接收到报文
{
	if(CAN_MessagePending(CAN1,CAN_FIFO0)>0)
	{
		return 1;
	}
	return 0;
}

7.CAN设备接收函数

void MyCAN_Receive(uint32_t *ID,uint8_t *Length,uint8_t *Data)
{
	CanRxMsg RxMessage;
	CAN_Receive(CAN1,CAN_FIFO0,&RxMessage);//将CAN1中FIFO 0接收到的报文数据读出到RxMessage
	
	if(RxMessage.IDE == CAN_Id_Standard)//判断是否是标准模式
	{
		*ID=RxMessage.StdId;
	}
	else
	{
		*ID=RxMessage.ExtId;
	}
	
	if(RxMessage.RTR == CAN_RTR_Data)//判断是否是数据报文,如果是数据报文则接收数据
	{
		uint8_t i;
		*Length=RxMessage.DLC;
		for(i=0;i<*Length;i++)
		{
			Data[i]=RxMessage.Data[i];
		}
	}
}

8.主函数

uint8_t KeyNum;

uint32_t TxID=0x55;
uint8_t TxLength=4;
uint8_t TxData[8]={0x11,0x22,0x33,0x44};

uint32_t RxID;
uint8_t RxLength;
uint8_t RxData[8];

int main(void)
{
	OLED_ShowString(1,1,"TxID:");
	OLED_ShowHexNum(2,6,TxID,3);
	OLED_ShowString(2,1,"RxID:");
	OLED_ShowString(3,1,"Length:");
	OLED_ShowString(4,1,"Data:");
	while(1)
	{
		KeyNum = Key_Number();
		
		if(KeyNum == 1)
		{
			TxData[0]++;
			TxData[1]++;
			TxData[2]++;
			TxData[3]++;
			MyCAN_Transmit(TxID,TxLength,TxData);
		}
		
		if(MyCAN_ReceiveFlag()==1)//判断是否接收到数据
		{
			MyCAN_Receive(&RxID,&RxLength,RxData);
			
			OLED_ShowHexNum(2,6,RxID,3);
			OLED_ShowHexNum(3,6,RxLength,1);
			OLED_ShowHexNum(4,6,RxData[0],2);
			OLED_ShowHexNum(4,9,RxData[1],2);
			OLED_ShowHexNum(4,12,RxData[2],2);
			OLED_ShowHexNum(4,15,RxData[3],2);
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值