有时硬件问题真真害死人,这代码调试了3天怎样弄都不行,回环模式测试成功,后来发现是vs230坏了,换了个开发板通信成功!
本程序基于3.5库编写,在ST官方开发板上调试通过,成功和51单片机通信。整个工程源码见附件,51源码稍后公开。
void CAN_Mode_Init(void):CAN初始化函数
u8 Can_Send_Msg(u8* msg,u8 len):向CAN总线写数据
u8 Can_Receive_Msg(u8 *buf):从CAN总线读数据
下面是can.h源码
#ifndef __CAN_H
#define __CAN_H
#include "stm32f10x.h"
//CAN接收RX0中断使能
#define CAN_RX0_INT_ENABLE 0 //0,不使能;1,使能.
void CAN_Mode_Init(void);//CAN初始化
u8 Can_Send_Msg(u8* msg,u8 len); //发送数据
u8 Can_Receive_Msg(u8 *buf); //接收数据
#endif
下面是can.c源码
void CAN_Mode_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
#if CAN_RX0_INT_ENABLE
NVIC_InitTypeDef NVIC_InitStructure;
#endif
/* PB8,PB9口线设置为AFIO模式, 切换到CAN功能 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
/* 使能GPIO时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* 配置CAN信号接收引脚: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; /* GPIO配置为上拉输入模式 */
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* 配置CAN信号发送引脚: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; /* 配置为复用推挽输出 */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* 设置GPIO最大速度 */
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* 原生的CAN引脚和USB引脚是相同的口线,安富莱开发板使用引脚的重映射功能将CAN引脚切换到PB8,PB9 */
GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE); /* 使能CAN1的重映射 */
/* 使能CAN外设时钟 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
CAN_DeInit(CAN1); /* 复位CAN寄存器 */
CAN_StructInit(&CAN_InitStructure); /* 填充CAN参数结构体成员为缺省值 */
//CAN单元设置
CAN_InitStructure.CAN_TTCM = DISABLE; /* 禁止时间触发模式(不生成时间戳), T */
CAN_InitStructure.CAN_ABOM = DISABLE; /* 禁止自动总线关闭管理 */
CAN_InitStructure.CAN_AWUM = DISABLE; /* 禁止自动唤醒模式 */
CAN_InitStructure.CAN_NART = DISABLE; /* 禁止仲裁丢失或出错后的自动重传功能 */
CAN_InitStructure.CAN_RFLM = DISABLE; /* 禁止接收FIFO加锁模式 */
CAN_InitStructure.CAN_TXFP = DISABLE; /* 禁止传输FIFO优先级 */
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; /* 设置CAN工作模式 */
//设置波特率
//CAN 波特率 = RCC_APB1Periph_CAN / Prescaler / (SJW + BS1 + BS2)
//CAN 波特率 = 360000000/6/(1+6+5)=500kHz \ 360000000/12/(1+2+3)=500khz
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
CAN_InitStructure.CAN_BS1=CAN_BS1_2tq; //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq
CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;//Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~ CAN_BS2_8tq
CAN_InitStructure.CAN_Prescaler=12; //分频系数(Fdiv)为brp+1 //
CAN_Init(CAN1, &CAN_InitStructure); // 初始化CAN1
/* 设置CAN滤波器0 */
CAN_FilterInitStructure.CAN_FilterNumber = 0; /* 滤波器序号,0-13,共14个滤波器 */
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; /* 滤波器模式,设置ID掩码模式 */
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; /* 32位滤波 */
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; /* 掩码后ID的高16bit */
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; /* 掩码后ID的低16bit */
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000; /* ID掩码值高16bit */
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000; /* ID掩码值低16bit */
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; /* 滤波器绑定FIFO 0 */
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; /* 使能滤波器 */
CAN_FilterInit(&CAN_FilterInitStructure);
#if CAN_RX0_INT_ENABLE
CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 主优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 次优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif
}
#if CAN_RX0_INT_ENABLE //使能RX0中断
//中断服务函数
void USB_LP_CAN1_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
int i=0;
CAN_Receive(CAN1, 0, &RxMessage);
for(i=0;i<8;i++)
printf("rxbuf[%d]:%d\r\n",i,RxMessage.Data[i]);
}
#endif
//can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)
//len:数据长度(最大为8)
//msg:数据指针,最大为8个字节.
//返回值:0,成功;
// 其他,失败;
u8 Can_Send_Msg(u8* msg,u8 len)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
TxMessage.StdId=0x12; // 标准标识符为0
TxMessage.ExtId=0x12; // 设置扩展标示符(29位)
TxMessage.IDE=0; // 使用扩展标识符
TxMessage.RTR=0; // 消息类型为数据帧,一帧8位
TxMessage.DLC=len; // 发送两帧信息
for(i=0;i<8;i++)
TxMessage.Data[i]=msg[i]; // 第一帧信息
mbox= CAN_Transmit(CAN1, &TxMessage);
i=0;
while((CAN_TransmitStatus(CAN1, mbox)!=CAN_TxStatus_Failed)&&(i<0XFFF))i++; //等待发送结束
if(i>=0XFFF)
return 1;
return 0;
}
//can口接收数据查询
//buf:数据缓存区;
//返回值:0,无数据被收到;
// 其他,接收的数据长度;
u8 Can_Receive_Msg(u8 *buf)
{
u32 i;
CanRxMsg RxMessage;
if( CAN_MessagePending(CAN1,CAN_FIFO0)==0)
return 0; //没有接收到数据,直接退出
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//读取数据
for(i=0;i<8;i++)
buf[i]=RxMessage.Data[i];
return RxMessage.DLC;
}