最近在做CAN的多节点实验,但是在使用STM32103和STM32F042做CAN通讯的时候无法通讯,两个STM32F103或者两个STM32F042可用正常通讯,现在用F103和F042就不能正常通讯了,初始化代码如下STM32F042初始化、中断及发送函数
[mw_shl_code=c,true]/**********************************************************
* 函数功能:CAN初始化配置
* 入口参数:CAN_ID 自身ID标识号
* 返回参数:无
* A_Z
* 20190410
* TX->PA12 RX->PA11
* 波特率 ->200kHz
* 采样点 ->87.50%
***********************************************************/
void CAN_Config(u16 CAN_ID)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);//重映射PA11、PA12之前必须打开SYSCFG时钟线
SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;//没有库函数,只能直接寄存器映射(TSSOP20封装的STM32F042F4P6必须映射)
GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_4);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_4);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;//CAN_Tx
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽型
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//无上下拉
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//高速模式
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//CAN_Rx
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//无上下拉
GPIO_Init(GPIOA,&GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn;//中断通道
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;//中断优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能
NVIC_Init(&NVIC_InitStructure);
CAN_DeInit(CAN);
CAN_StructInit(&CAN_InitStructure);//用默认值填充结构体成员
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;//启用或禁用接收FIFO锁定模式
CAN_InitStructure.CAN_TXFP = DISABLE;//启用或禁用传输FIFO优先级
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;//工作于正常模式(工作模式有:静音、环回、正常、环回静音)
CAN_InitStructure.CAN_SJW = CAN_SJW_2tq;//指定CAN硬件为执行重新同步跳跃宽度(容错率,不参与波特率计算)(0-3)
CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;//指定位段1中的时间量子数(0-15)
CAN_InitStructure.CAN_BS2 = CAN_BS2_1tq;//指定位段2中的时间量子数(0-7)
CAN_InitStructure.CAN_Prescaler = 23;//时间量长度(1-1024)
CAN_Init(CAN,&CAN_InitStructure);//初始化CAN
CAN_FilterInitStructure.CAN_FilterNumber = 0;//指定要初始化的FIFO
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;//模式为标识符掩码模式(另一种为标识符列表模式)
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;//FIFO为32位过滤器
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;//过滤器标识号高16位
CAN_FilterInitStructure.CAN_FilterIdLow = ((u16)CAN_ID<<3)|CAN_ID_EXT|CAN_RTR_DATA;//过滤器标志号低16位
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;//过滤掩码号高16位
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0FFE;//过滤掩码号低16位
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;//将参数分配给指定FIFO
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;//使能FIFO
CAN_FilterInit(&CAN_FilterInitStructure);
//FIFO消息挂起中断
CAN_ITConfig(CAN,CAN_IT_FMP0,ENABLE);
#ifdef FIFO1
//初始化过滤器FIFO1
CAN_FilterInitStructure.CAN_FilterNumber = 1;//指定要初始化的FIFO
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdList;//模式为标识符列表模式(另一种为标识符掩码模式)
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;//FIFO比例为单32位
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x2460;//过滤器标识号高16位
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;//过滤器标识号低16位
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;//过滤掩码号高16位
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;//过滤掩码号低16位
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 1;//将参数分配给指定FIFO
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;//使能FIFO
CAN_FilterInit(&CAN_FilterInitStructure);
//FIFO消息挂起中断
CAN_ITConfig(CAN,CAN_IT_FMP1,ENABLE);
#endif
}
/**********************************************************
* 函数功能:CAN发送数据函数
* 入口参数:u16 ID ->目标ID
* u8 *msg ->数据指针,最大为8字节
* u8 len ->数据长度,最大为8
* 返回参数:0 成功
* 其他 失败
* 作 者:A_Z
* 时 间:20190410
***********************************************************/
u8 CAN_Send(u16 ID,u8 *msg,u8 len)
{
u8 mbox;
u16 i;
CanTxMsg TxMessage;
WDT();//喂狗
TxMessage.StdId = 0;//标准标识符
TxMessage.ExtId = ID;//扩展标识符
TxMessage.IDE = CAN_ID_EXT;//扩展帧
TxMessage.RTR = CAN_RTR_DATA;//数据帧
TxMessage.DLC = len;//数据长度
for(i=0; i<len; i++) //写入数据
TxMessage.Data = msg;
mbox = CAN_Transmit(CAN,&TxMessage);//发送数据
while((CAN_TransmitStatus(CAN,mbox) != CAN_TxStatus_Ok)&&(i < 0xfff))i++;//等待发送完成
if(i >= 0xfff)return 1;
return 0;
}
/**********************************************************
* 函数功能:CAN中断接收函数
* 入口参数:无
* 返回参数:无
* A_Z
* 20190410
**********************************************************/
void CEC_CAN_IRQHandler(void)
{
u8 i;
CanRxMsg RxMessage0;
#ifdef FIFO1
CanRxMsg RxMessage1;
#endif
if(CAN_MessagePending(CAN, CAN_FIFO0) != 0) { //FIFO0有待处理消息
CAN_Receive(CAN,0,&RxMessage0);
for(i=0; i<RxMessage0.DLC; i++)
Can_Data0 = RxMessage0.Data;
}
#ifdef FIFO1
if(CAN_MessagePending(CAN, CAN_FIFO1) != 0) { //FIFO1有待处理消息
CAN_Receive(CAN,1,&RxMessage1);
for(i=0; i<8; i++)
Can_Data1 = RxMessage1.Data;
}
#endif
}[/mw_shl_code]
STM32F103初始化、发送及中断函数
[mw_shl_code=c,true]/*
* 函数名:CAN_GPIO_Config
* 描述 :CAN的所有配置和初始化
* 输入 :当前设备标识符ID
* 输出 : 无
波特率:200KHz 采样点:87.5%
*/
void CAN_Config(u16 CAN_ID)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
/*外设时钟设置*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
/*IO设置*/
/* Configure CAN pin: RX PA11*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure CAN pin: TX PA12 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*中断设置*/
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; //CAN1 RX0中断
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级为1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/************************CAN通信参数设置**********************************/
/*CAN寄存器初始化*/
CAN_DeInit(CAN1);
CAN_StructInit(&CAN_InitStructure);
/*CAN单元初始化*/
CAN_InitStructure.CAN_TTCM=DISABLE; //MCR-TTCM 关闭时间触发通信模式使能
CAN_InitStructure.CAN_ABOM=DISABLE; //MCR-ABOM 不自动离线管理
CAN_InitStructure.CAN_AWUM=DISABLE; //MCR-AWUM 不使用自动唤醒模式
CAN_InitStructure.CAN_NART=DISABLE; //MCR-NART 禁止报文自动重传 DISABLE-自动重传
CAN_InitStructure.CAN_RFLM=DISABLE; //MCR-RFLM 接收FIFO 锁定模式 DISABLE-溢出时新报文会覆盖原有报文
CAN_InitStructure.CAN_TXFP=DISABLE; //MCR-TXFP 发送FIFO优先级 DISABLE-优先级取决于报文标示符
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; //正常工作模式
CAN_InitStructure.CAN_SJW=CAN_SJW_2tq; //BTR-SJW 重新同步跳跃宽度 2个时间单元
CAN_InitStructure.CAN_BS1=CAN_BS1_6tq; //BTR-TS1 时间段1 占用了6个时间单元
CAN_InitStructure.CAN_BS2=CAN_BS2_1tq; //BTR-TS1 时间段2 占用了1个时间单元
CAN_InitStructure.CAN_Prescaler =3;
CAN_Init(CAN1, &CAN_InitStructure);
/*CAN过滤器初始化*/
CAN_FilterInitStructure.CAN_FilterNumber=0; //过滤器组0
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //工作在标识符屏蔽位模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //过滤器位宽为单个32位。
CAN_FilterInitStructure.CAN_FilterIdHigh= 0x0000; //要过滤的ID高位
CAN_FilterInitStructure.CAN_FilterIdLow= ((u16)CAN_ID<<3)|CAN_ID_EXT|CAN_RTR_DATA; //要过滤的ID低位
CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0x0000; //过滤器高16位每位必须匹配
CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0x0FFE; //过滤器低16位每位必须匹配
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FilterFIFO0 ; //过滤器被关联到FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure);
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
}
/**********************************************************
* 函数功能:CAN发送数据函数
* 入口参数:u16 ID ->目标ID
* u8 *msg ->数据指针,最大为8字节
* 返回参数:0 成功
* 其他 失败
* 作 者:A_Z
* 时 间:20190425
***********************************************************/
u8 CAN_Send(u16 ID,u8 *str)
{
CanTxMsg TxMessage; //发送缓冲区
u16 i,mbox;
TxMessage.StdId = 0;
TxMessage.ExtId = ID; //使用的扩展ID
TxMessage.IDE=CAN_ID_EXT; //扩展模式
TxMessage.RTR=CAN_RTR_DATA; //发送的是数据
TxMessage.DLC=8; //数据长度为5字节
for(i=0;i<8;i++)
TxMessage.Data= str;
mbox = CAN_Transmit(CAN1,&TxMessage);//发送数据
while((CAN_TransmitStatus(CAN1,mbox) != CANTXOK) && (i<0xfff))i++;//等待发送完成
if(i>0xfff)return 1;
return 0;
}
/**********************************************************
* 函数功能:CAN中断服务函数
* 入口参数:无
* 返回参数:无
* 作 者:A_Z
* 时 间:20190426
**********************************************************/
void USB_LP_CAN1_RX0_IRQHandler(void)
{
u8 i;
CanRxMsg RxMessage;
if(CAN_MessagePending(CAN1,CAN_FIFO0) != 0){//又待处理消息
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//接收消息
for(i=0;i<RxMessage.DLC;i++)
CAN_Data = RxMessage.Data;
}
}
[/mw_shl_code]
现在F103向F042定时发送CAN数据,现在调试F0,在寄存器内显示的是(位填充错误和格式错误),在F1调试又显示的是(隐性位错误),请问遇到过的朋友怎么解决这个问题啊
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>