历史上的今天
今天是:2024年09月30日(星期一)
2019年09月30日 | STM32-F407 CAN的双机通讯
2019-09-30 来源:eefocus
直奔主题,我是在原子哥F407例程的基础上想实现双机CAN通讯

我用的核心板为STM32-F407ZGT6,原理图上看到PA11、PA12引脚可以复用为CAN1_RX和CAN1_TX,在与CAN收发器接线时不要接错,PA11与收发器TXD相连,PA12与收发器RXD相连。收发器建议用HVP230,可以用板子3.3V供电;TJA1050也可以,不过需要5V供电,这点需要注意。
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初始化
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_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA11,PA12
//CAN引脚复用
GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1);
//CAN单元设置
CAN_InitStructure.CAN_TTCM=DISABLE;
CAN_InitStructure.CAN_ABOM=DISABLE;
CAN_InitStructure.CAN_AWUM=DISABLE;
CAN_InitStructure.CAN_NART=ENABLE;
CAN_InitStructure.CAN_RFLM=DISABLE;
CAN_InitStructure.CAN_TXFP=DISABLE;
CAN_InitStructure.CAN_Mode= mode; //CAN模式设置
CAN_InitStructure.CAN_SJW=tsjw;
CAN_InitStructure.CAN_BS1=tbs1;
CAN_InitStructure.CAN_BS2=tbs2;
CAN_InitStructure.CAN_Prescaler=brp;
CAN_Init(CAN1, &CAN_InitStructure); // 初始化CAN1
//配置过滤器
CAN_FilterInitStructure.CAN_FilterNumber=0;
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器
CAN_FilterInit(&CAN_FilterInitStructure);//过滤器初始化,此处设置接收所有报文
CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 主优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 次优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
return 0;
}
中断处理函数为:
void CAN1_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
int i=0;
CAN_Receive(CAN1, 0, &RxMessage);
for(i=0;i<8;i++)
printf("DATA[%d]:%drn",i,RxMessage.Data[i]);
LED1=!LED1;
}
发送函数就根据自己的需求设置ID,数据等,此处不表,例程里都有。
重点:主函数中两个板子的模式初始化不同!!!
CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,Mode);
CAN1模式初始化中,前4位设置总线波特率为500Kbps,重点在于最后的Mode。原子哥例程和我看到的其他例程相同,都是可以选择自发自收或者普通模式。实际操作程序下到两块板子里,检查各自报文的自发自收也确实没有问题,但就是不能互相通讯。
查看STM32F4中文参考手册,CAN_Mode可以设置为静默、环回、环回与静默组合、正常模式。于是试着将其中一块板子的CAN模式改为静默模式(即只接收而不发送),另一块仍然是正常模式,结果接收消息没有问题!
泪流满面,仰天长啸啊,折腾了几天的问题原来这么简单。细细思考,自己一开始就没有仔细想过CAN报文ID冲突的问题,一套例程下到两块板子里,同时发送相同ID的CAN报文,总线上的仲裁机制失效,当然就不能够正常通讯了。如果想要实现两块板子的互发互收,就要设置不同ID的CAN报文。
以此为鉴,以后对待别人的东西,不仅要会用,还要能懂,最重要的是实践。否则就会像上文这样,因为小细节耽误很长时间。
史海拾趣
|
int MAX_SIZE = 256; HKEY hKey1; wchar_t *key1Value = L\"abc\";//这里写成中文结果也相同 char *key1buf = new char[MAX_SIZE]; &nb ...… 查看全部问答> |
|
基于FSSDC-9B506-EK Easy Kit的作品(1) 去年暑假期间,富士通公司举办了“2010-2011富士通半导体杯创意未来电子竞赛”,我有两个学生参加这个比赛。做了点东西,应该说还行吧。现在富士通在论坛征集建议,刚好他们使用的开发板就是Cortex-M3 Easy Kit,作为响应吧,我就把他们 ...… 查看全部问答> |
|
因为我们省的电子设计比赛里希望我们用TI的单片机,所以我学了一下LM3S,发现这个单片机没什么优点……(也许是我太菜了,说错请喷)AD不能当IO,一组IO最多8个口,还有4个的(为什么不把4个的合成8个?),定时器少而且PWM不能分频(WHY?),100 ...… 查看全部问答> |
|
13590358478 王萍QQ2454614355 宇飞电子大量回收iphone4、iphone4s、iphone5、iphone5s、iPhone5C数据线.液晶屏.WIFI模块.玻璃镜面.CPU.充电器.电池.字库.功放.蓝牙.手机排线.按键.手机壳.触摸盖板.收购三星、HTC、摩托罗拉手机摄像头.液晶屏,触 ...… 查看全部问答> |
|
如题所述,采用一片STC12C2052AD单片机AD采集口测量一节锂电池电压,发现电池电压会对其他IO口的电压产生一定影响,比如说单片机未上电时,就已经可以测出其他IO口产生3V多的电压,这种情况有没有什么办法进行处理,或者隔离!比如说既让单片机可以 ...… 查看全部问答> |




