初级会员

- 积分
- 56
- 金钱
- 56
- 注册时间
- 2022-5-11
- 在线时间
- 6 小时
|
1金钱
我调用的CAN1是PA11(rx)和PA12(tx),其他代码照抄原子例程,发现can1初始化只能使用回环模式,不能用正常模式。求大佬指点!!! 以下是例程:
//CAN初始化
u8 CAN1_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
//使能相关时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能PORTA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟
//引脚复用映射配置
GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1); //GPIOA11复用为CAN1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1); //GPIOA12复用为CAN1
//初始化GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11| GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA11,PA12
//CAN单元设置
CAN_InitStructure.CAN_TTCM=DISABLE; //非时间触发通信模式
CAN_InitStructure.CAN_ABOM=DISABLE; //软件自动离线管理
CAN_InitStructure.CAN_AWUM=DISABLE;//睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
CAN_InitStructure.CAN_NART=ENABLE; //禁止报文自动传送
CAN_InitStructure.CAN_RFLM=DISABLE; //报文不锁定,新的覆盖旧的
CAN_InitStructure.CAN_TXFP=DISABLE; //优先级由报文标识符决定
CAN_InitStructure.CAN_Mode= mode; //模式设置
CAN_InitStructure.CAN_SJW=tsjw; //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq
CAN_InitStructure.CAN_BS1=tbs1; //Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
CAN_InitStructure.CAN_BS2=tbs2;//Tbs2范围CAN_BS2_1tq ~ CAN_BS2_8tq
CAN_InitStructure.CAN_Prescaler=brp; //分频系数(Fdiv)为brp+1
CAN_Init(CAN1, &CAN_InitStructure); // 初始化CAN1
//配置过滤器
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;////32位ID
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0
CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化
return 0;
}
//*****************************************************************************
//功能:can发送试验.
//*****************************************************************************
u8 CAN1_Send_Msg(u32 ID,u8* msg,u8 len)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
TxMessage.StdId=0x12; // 标准标识符为0
TxMessage.ExtId=ID; // 设置扩展标示符(29位)
TxMessage.IDE=CAN_Id_Extended; // 使用扩展标识符
TxMessage.RTR=CAN_RTR_Data; // 消息类型为数据帧,一帧8位
TxMessage.DLC=len; // 发送两帧信息
for(i=0;i<len;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数据.
//*****************************************************************************
u8 CAN1_RX(u8 *Buf)
{
CanRxMsg RxMe;
u8 i;
if (CAN_MessagePending(CAN1,CAN_FIFO0)==0)
{
return(0);
}
CAN_Receive(CAN1,CAN_FIFO0,&RxMe);
for(i=0;i<RxMe.DLC;i++)
{
*Buf=RxMe.Data[i];
Buf++;
}
return(RxMe.DLC);
}
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
a1=1;
a1=CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,CAN_Mode_Normal);//CAN初始化正常模式,波特率500Kbps
// a2=CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,CAN_Mode_LoopBack);//CAN初始化环回模式,波特率500Kbps
// 注释a1,不注释a2.环回模式下CAN1正常发送数据,但无法接收;注释a2,正常模式下CAN1发送16次8位的单个字节以后直接摆烂,仿真里面怎么跑,逻辑分析仪也没反应了
while(1)
{
a1=CAN1_Send_Msg(1,da,8);
delay_ms(10);
a1=CAN1_RX(db);
delay_ms(10);
a1=1;
delay_ms(10);
}
}
//end
|
最佳答案
查看完整内容[请看2#楼]
行了,已解决。
答案是在我不熟悉407的io口工作模式。这是407的io口设置和103的不同之处。
stm32f103xx的io口,只能在“推挽”“浮空”“开漏”“复用推挽”等等8个中选一个。
stm32f407xx的io口,却能在选择“复用”和“普通模式下”,再选择“推挽”/“开漏”和“浮空”/“上拉”/“下拉”里面选2个。也就是可以既选“推挽”又选“上拉”。
也就是407代码里面的:
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
...
|