2024年3月13日发(作者:错元)
//stm32f407程序:
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "can.h"
int main(void)
{
u8 i=0;
u8 canbuf[8];
u8 Can_Send_Flag;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(168);
uart_init(115200);
CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,3,CAN_Mode_No
rmal);
for(i=0;i<8;i++)
canbuf[i]=i;
Can_Send_Flag=CAN1_Send_Msg(canbuf,8);//发送8个字节
Can_Send_Flag=CAN1_Send_Msg(canbuf,8);//发送8个字节
if(Can_Send_Flag) printf("data Send failed");
else printf("data Send ok");
while(1);
}
//can.c
#include "can.h"
#include "delay.h"
#include "usart.h"
//CAN初始化
//tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1tq~ CAN_SJW_4tq
//tbs2:时间段2的时间单元. 范围:CAN_BS2_1tq~CAN_BS2_8tq;
//tbs1:时间段1的时间单元. 范围:CAN_BS1_1tq ~CAN_BS1_16tq
//brp :波特率分频器.范围:1~1024; tq=(brp)*tpclk1
//波特率=Fpclk1/((tbs1+1+tbs2+1+1)*brp);
//mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式;
//Fpclk1的时钟在初始化的时候设置为42M,如果设置
CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,CAN_Mode_LoopBa
ck);
//则波特率为:42M/((6+7+1)*6)=500Kbps
//返回值:0,初始化OK;
// 其他,初始化失败;
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;
#if CAN1_RX0_INT_ENABLE
NVIC_InitTypeDef NVIC_InitStructure;
#endif
//使能相关时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能PORTA
时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时
钟
//初始化GPIO
GPIO__Pin = GPIO_Pin_11| GPIO_Pin_12;
GPIO__Mode = GPIO_Mode_AF;//复用功能
GPIO__OType = GPIO_OType_PP;//推挽输出
GPIO__Speed = GPIO_Speed_100MHz;//100MHz
GPIO__PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA11,PA12
//引脚复用映射配置
GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1); //GPIOA11复
用为CAN1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1); //GPIOA12复
用为CAN1
//CAN单元设置
CAN__TTCM=DISABLE; //非时间触发通信模式
CAN__ABOM=DISABLE; //软件自动离线管理
CAN__AWUM=DISABLE;//睡眠模式通过软件唤醒(清除CAN-
>MCR的SLEEP位)
CAN__NART=ENABLE; //禁止报文自动传送
CAN__RFLM=DISABLE; //报文不锁定,新的覆盖旧的
CAN__TXFP=DISABLE; //优先级由报文标识符决定
CAN__Mode= mode; //模式设置
CAN__SJW=tsjw; //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单
位 CAN_SJW_1tq~CAN_SJW_4tq
CAN__BS1=tbs1; //Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
CAN__BS2=tbs2;//Tbs2范围CAN_BS2_1tq ~ CAN_BS2_8tq
CAN__Prescaler=brp; //分频系数(Fdiv)为brp+1
CAN_Init(CAN1, &CAN_InitStructure); // 初始化CAN1
//配置过滤器
CAN__FilterNumber=0; //过滤器0
CAN__FilterMode=CAN_FilterMode_IdMask;
CAN__FilterScale=CAN_FilterScale_32bit; //32位
CAN__FilterIdHigh=0x0000;////32位ID
CAN__FilterIdLow=0x0000;
CAN__FilterMaskIdHigh=0x0000;//32位MASK
CAN__FilterMaskIdLow=0x0000;
CAN__FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器
0关联到FIFO0
CAN__FilterActivation=ENABLE; //激活过滤器0
CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化
#if CAN1_RX0_INT_ENABLE
CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.
NVIC__IRQChannel = CAN1_RX0_IRQn;
NVIC__IRQChannelPreemptionPriority = 1; // 主优先级为
1
NVIC__IRQChannelSubPriority = 0; // 次优先级为0
NVIC__IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif
return 0;
}
#if CAN1_RX0_INT_ENABLE //使能RX0中断
//中断服务函数
void CAN1_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
int i=0;
CAN_Receive(CAN1, 0, &RxMessage);
for(i=0;i<8;i++)
printf("rxbuf[%d]:%drn",i,[i]);
}
#endif
//can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)
//len:数据长度(最大为8)
//msg:数据指针,最大为8个字节.
//返回值:0,成功;
// 其他,失败;
u8 CAN1_Send_Msg(u8* msg,u8 len)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
=0x12; // 标准标识符为0
=0x12; // 设置扩展标示符(29位)
=0; // 使用扩展标识符
=0; // 消息类型为数据帧,一帧8位
=len; // 发送两帧信息
for(i=0;i [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 CAN1_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<;i++) buf[i]=[i]; return ; //没有接 } #ifndef __CAN_H #define __CAN_H #include "sys.h" //CAN1接收RX0中断使能 #define CAN1_RX0_INT_ENABLE 0 //0,不使能;1,使能. u8 CAN1_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode);//CAN初始化 u8 CAN1_Send_Msg(u8* msg,u8 len); 据 //发送数 u8 CAN1_Receive_Msg(u8 *buf); 据 //接收数 #endif //stm32f103程序: #include "led.h" #include "delay.h" #include "sys.h" #include "usart.h" #include "can.h" int main(void) { delay_init(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); uart_init(115200); //串口初始化为115200 CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_3tq,CAN_BS1_8tq,3,CAN_Mode_Nor mal);//CAN普通模式初始化, 波特率500Kbps while(1); } //can.c #include "can.h" #include "led.h" #include "delay.h" #include "usart.h" //CAN初始化 //tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1tq~ CAN_SJW_4tq //tbs2:时间段2的时间单元. 范围:CAN_BS2_1tq~CAN_BS2_8tq; //tbs1:时间段1的时间单元. 范围:CAN_BS1_1tq ~CAN_BS1_16tq //brp :波特率分频器.范围:1~1024; tq=(brp)*tpclk1 //波特率=Fpclk1/((tbs1+1+tbs2+1+1)*brp); //mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式; //Fpclk1的时钟在初始化的时候设置为36M,如果设置 CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_LoopBac k); //则波特率为:36M/((8+9+1)*4)=500Kbps //返回值:0,初始化OK; // 其他,初始化失败; u8 CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode) { GPIO_InitTypeDef GPIO_InitStructure; CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure; #if CAN_RX0_INT_ENABLE NVIC_InitTypeDef NVIC_InitStructure; #endif RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PORTA 时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时 钟 GPIO__Pin = GPIO_Pin_12; GPIO__Speed = GPIO_Speed_50MHz; GPIO__Mode = GPIO_Mode_AF_PP; //复用推挽 GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化IO GPIO__Pin = GPIO_Pin_11; GPIO__Mode = GPIO_Mode_IPU; //上拉输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化IO //CAN单元设置 CAN__TTCM=DISABLE; //非时间触发通信模式 CAN__ABOM=DISABLE; //软件自动离线管理 CAN__AWUM=DISABLE; 唤醒(清除CAN->MCR的SLEEP位) //睡眠模式通过软件 CAN__NART=ENABLE; //禁止报文自动传送 CAN__RFLM=DISABLE; //报文不锁定,新的覆盖旧的 CAN__TXFP=DISABLE; //优先级由报文标识符决定 CAN__Mode= mode; //模式设置: mode:0,普通模式;1, 回环模式; //设置波特率 CAN__SJW=tsjw; 为tsjw+1个时间单位 CAN_SJW_1tq CAN_SJW_4tq //重新同步跳跃宽度(Tsjw) CAN_SJW_3tq CAN_SJW_2tq CAN__BS1=tbs1; CAN_BS1_1tq ~CAN_BS1_16tq //Tbs1=tbs1+1个时间单位 CAN__BS2=tbs2; CAN_BS2_1tq ~ CAN_BS2_8tq //Tbs2=tbs2+1个时间单位 CAN__Prescaler=brp; //分频系数(Fdiv)为brp+1 CAN_Init(CAN1, &CAN_InitStructure); //初始化CAN1 CAN__FilterNumber=0; //过滤器0 CAN__FilterMode=CAN_FilterMode_IdMask; //屏蔽位 模式 CAN__FilterScale=CAN_FilterScale_32bit; //32位宽 CAN__FilterIdHigh=0x0000; //32位ID CAN__FilterIdLow=0x0000; CAN__FilterMaskIdHigh=0x0000;//32位MASK CAN__FilterMaskIdLow=0x0000; CAN__FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器 0关联到FIFO0 CAN__FilterActivation=ENABLE;//激活过滤器0 CAN_FilterInit(&CAN_FilterInitStructure); //滤波器初始化 #if CAN_RX0_INT_ENABLE CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE); 号中断允许. //FIFO0消息挂 NVIC__IRQChannel = USB_LP_CAN1_RX0_IRQn; NVIC__IRQChannelPreemptionPriority = 1; // 主优先级为 1 NVIC__IRQChannelSubPriority = 0; // 次优先级为0 NVIC__IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #endif return 0; } #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]:%drn",i,[i]); printf("data Receive Successedrn"); } #endif //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧) //len:数据长度(最大为8) //msg:数据指针,最大为8个字节. //返回值:0,成功; // 其他,失败; u8 Can_Send_Msg(u8* msg,u8 len) { u8 mbox; u16 i=0; CanTxMsg TxMessage; =0x12; // 标准标识符 =0x12; // 设置扩展标示符 =CAN_Id_Standard; // 标准帧 =CAN_RTR_Data; // 数据帧 =len; // 要发送的数据长度 for(i=0;i [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]=[i]; return ; } #ifndef __CAN_H #define __CAN_H #include "sys.h" //CAN接收RX0中断使能 #define CAN_RX0_INT_ENABLE 1 //0,不使能;1,使能. u8 CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode);//CAN初始化 u8 Can_Send_Msg(u8* msg,u8 len); //发送数据 u8 Can_Receive_Msg(u8 *buf); //接收数据 #endif
2024年3月13日发(作者:错元)
//stm32f407程序:
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "can.h"
int main(void)
{
u8 i=0;
u8 canbuf[8];
u8 Can_Send_Flag;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(168);
uart_init(115200);
CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,3,CAN_Mode_No
rmal);
for(i=0;i<8;i++)
canbuf[i]=i;
Can_Send_Flag=CAN1_Send_Msg(canbuf,8);//发送8个字节
Can_Send_Flag=CAN1_Send_Msg(canbuf,8);//发送8个字节
if(Can_Send_Flag) printf("data Send failed");
else printf("data Send ok");
while(1);
}
//can.c
#include "can.h"
#include "delay.h"
#include "usart.h"
//CAN初始化
//tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1tq~ CAN_SJW_4tq
//tbs2:时间段2的时间单元. 范围:CAN_BS2_1tq~CAN_BS2_8tq;
//tbs1:时间段1的时间单元. 范围:CAN_BS1_1tq ~CAN_BS1_16tq
//brp :波特率分频器.范围:1~1024; tq=(brp)*tpclk1
//波特率=Fpclk1/((tbs1+1+tbs2+1+1)*brp);
//mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式;
//Fpclk1的时钟在初始化的时候设置为42M,如果设置
CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,CAN_Mode_LoopBa
ck);
//则波特率为:42M/((6+7+1)*6)=500Kbps
//返回值:0,初始化OK;
// 其他,初始化失败;
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;
#if CAN1_RX0_INT_ENABLE
NVIC_InitTypeDef NVIC_InitStructure;
#endif
//使能相关时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能PORTA
时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时
钟
//初始化GPIO
GPIO__Pin = GPIO_Pin_11| GPIO_Pin_12;
GPIO__Mode = GPIO_Mode_AF;//复用功能
GPIO__OType = GPIO_OType_PP;//推挽输出
GPIO__Speed = GPIO_Speed_100MHz;//100MHz
GPIO__PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA11,PA12
//引脚复用映射配置
GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1); //GPIOA11复
用为CAN1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1); //GPIOA12复
用为CAN1
//CAN单元设置
CAN__TTCM=DISABLE; //非时间触发通信模式
CAN__ABOM=DISABLE; //软件自动离线管理
CAN__AWUM=DISABLE;//睡眠模式通过软件唤醒(清除CAN-
>MCR的SLEEP位)
CAN__NART=ENABLE; //禁止报文自动传送
CAN__RFLM=DISABLE; //报文不锁定,新的覆盖旧的
CAN__TXFP=DISABLE; //优先级由报文标识符决定
CAN__Mode= mode; //模式设置
CAN__SJW=tsjw; //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单
位 CAN_SJW_1tq~CAN_SJW_4tq
CAN__BS1=tbs1; //Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
CAN__BS2=tbs2;//Tbs2范围CAN_BS2_1tq ~ CAN_BS2_8tq
CAN__Prescaler=brp; //分频系数(Fdiv)为brp+1
CAN_Init(CAN1, &CAN_InitStructure); // 初始化CAN1
//配置过滤器
CAN__FilterNumber=0; //过滤器0
CAN__FilterMode=CAN_FilterMode_IdMask;
CAN__FilterScale=CAN_FilterScale_32bit; //32位
CAN__FilterIdHigh=0x0000;////32位ID
CAN__FilterIdLow=0x0000;
CAN__FilterMaskIdHigh=0x0000;//32位MASK
CAN__FilterMaskIdLow=0x0000;
CAN__FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器
0关联到FIFO0
CAN__FilterActivation=ENABLE; //激活过滤器0
CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化
#if CAN1_RX0_INT_ENABLE
CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.
NVIC__IRQChannel = CAN1_RX0_IRQn;
NVIC__IRQChannelPreemptionPriority = 1; // 主优先级为
1
NVIC__IRQChannelSubPriority = 0; // 次优先级为0
NVIC__IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif
return 0;
}
#if CAN1_RX0_INT_ENABLE //使能RX0中断
//中断服务函数
void CAN1_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
int i=0;
CAN_Receive(CAN1, 0, &RxMessage);
for(i=0;i<8;i++)
printf("rxbuf[%d]:%drn",i,[i]);
}
#endif
//can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)
//len:数据长度(最大为8)
//msg:数据指针,最大为8个字节.
//返回值:0,成功;
// 其他,失败;
u8 CAN1_Send_Msg(u8* msg,u8 len)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
=0x12; // 标准标识符为0
=0x12; // 设置扩展标示符(29位)
=0; // 使用扩展标识符
=0; // 消息类型为数据帧,一帧8位
=len; // 发送两帧信息
for(i=0;i [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 CAN1_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<;i++) buf[i]=[i]; return ; //没有接 } #ifndef __CAN_H #define __CAN_H #include "sys.h" //CAN1接收RX0中断使能 #define CAN1_RX0_INT_ENABLE 0 //0,不使能;1,使能. u8 CAN1_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode);//CAN初始化 u8 CAN1_Send_Msg(u8* msg,u8 len); 据 //发送数 u8 CAN1_Receive_Msg(u8 *buf); 据 //接收数 #endif //stm32f103程序: #include "led.h" #include "delay.h" #include "sys.h" #include "usart.h" #include "can.h" int main(void) { delay_init(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); uart_init(115200); //串口初始化为115200 CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_3tq,CAN_BS1_8tq,3,CAN_Mode_Nor mal);//CAN普通模式初始化, 波特率500Kbps while(1); } //can.c #include "can.h" #include "led.h" #include "delay.h" #include "usart.h" //CAN初始化 //tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1tq~ CAN_SJW_4tq //tbs2:时间段2的时间单元. 范围:CAN_BS2_1tq~CAN_BS2_8tq; //tbs1:时间段1的时间单元. 范围:CAN_BS1_1tq ~CAN_BS1_16tq //brp :波特率分频器.范围:1~1024; tq=(brp)*tpclk1 //波特率=Fpclk1/((tbs1+1+tbs2+1+1)*brp); //mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式; //Fpclk1的时钟在初始化的时候设置为36M,如果设置 CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_LoopBac k); //则波特率为:36M/((8+9+1)*4)=500Kbps //返回值:0,初始化OK; // 其他,初始化失败; u8 CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode) { GPIO_InitTypeDef GPIO_InitStructure; CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure; #if CAN_RX0_INT_ENABLE NVIC_InitTypeDef NVIC_InitStructure; #endif RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PORTA 时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时 钟 GPIO__Pin = GPIO_Pin_12; GPIO__Speed = GPIO_Speed_50MHz; GPIO__Mode = GPIO_Mode_AF_PP; //复用推挽 GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化IO GPIO__Pin = GPIO_Pin_11; GPIO__Mode = GPIO_Mode_IPU; //上拉输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化IO //CAN单元设置 CAN__TTCM=DISABLE; //非时间触发通信模式 CAN__ABOM=DISABLE; //软件自动离线管理 CAN__AWUM=DISABLE; 唤醒(清除CAN->MCR的SLEEP位) //睡眠模式通过软件 CAN__NART=ENABLE; //禁止报文自动传送 CAN__RFLM=DISABLE; //报文不锁定,新的覆盖旧的 CAN__TXFP=DISABLE; //优先级由报文标识符决定 CAN__Mode= mode; //模式设置: mode:0,普通模式;1, 回环模式; //设置波特率 CAN__SJW=tsjw; 为tsjw+1个时间单位 CAN_SJW_1tq CAN_SJW_4tq //重新同步跳跃宽度(Tsjw) CAN_SJW_3tq CAN_SJW_2tq CAN__BS1=tbs1; CAN_BS1_1tq ~CAN_BS1_16tq //Tbs1=tbs1+1个时间单位 CAN__BS2=tbs2; CAN_BS2_1tq ~ CAN_BS2_8tq //Tbs2=tbs2+1个时间单位 CAN__Prescaler=brp; //分频系数(Fdiv)为brp+1 CAN_Init(CAN1, &CAN_InitStructure); //初始化CAN1 CAN__FilterNumber=0; //过滤器0 CAN__FilterMode=CAN_FilterMode_IdMask; //屏蔽位 模式 CAN__FilterScale=CAN_FilterScale_32bit; //32位宽 CAN__FilterIdHigh=0x0000; //32位ID CAN__FilterIdLow=0x0000; CAN__FilterMaskIdHigh=0x0000;//32位MASK CAN__FilterMaskIdLow=0x0000; CAN__FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器 0关联到FIFO0 CAN__FilterActivation=ENABLE;//激活过滤器0 CAN_FilterInit(&CAN_FilterInitStructure); //滤波器初始化 #if CAN_RX0_INT_ENABLE CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE); 号中断允许. //FIFO0消息挂 NVIC__IRQChannel = USB_LP_CAN1_RX0_IRQn; NVIC__IRQChannelPreemptionPriority = 1; // 主优先级为 1 NVIC__IRQChannelSubPriority = 0; // 次优先级为0 NVIC__IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #endif return 0; } #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]:%drn",i,[i]); printf("data Receive Successedrn"); } #endif //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧) //len:数据长度(最大为8) //msg:数据指针,最大为8个字节. //返回值:0,成功; // 其他,失败; u8 Can_Send_Msg(u8* msg,u8 len) { u8 mbox; u16 i=0; CanTxMsg TxMessage; =0x12; // 标准标识符 =0x12; // 设置扩展标示符 =CAN_Id_Standard; // 标准帧 =CAN_RTR_Data; // 数据帧 =len; // 要发送的数据长度 for(i=0;i [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]=[i]; return ; } #ifndef __CAN_H #define __CAN_H #include "sys.h" //CAN接收RX0中断使能 #define CAN_RX0_INT_ENABLE 1 //0,不使能;1,使能. u8 CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode);//CAN初始化 u8 Can_Send_Msg(u8* msg,u8 len); //发送数据 u8 Can_Receive_Msg(u8 *buf); //接收数据 #endif