STM 32 之can 实例+代码解析
来源:互联网 发布:韩国直播软件app 编辑:程序博客网 时间:2024/06/01 23:27
#include "sysdef.h" #define MAX_MAIL_NUM 3//CAN总线调试:0=运行 1=自环调试#define CAN_DEBUG 0//CAN总线波特率:0=250kbps,1=500kbps,2=1Mbps#define CAN1_BPS 0 unsigned char can1_addr = 0; unsigned short Can1_Tx_Count =0;unsigned short Can1_Rx_Count =0; unsigned short Can1_Send_Delay =0; unsigned char Can1_Send_Buf[10]={0xeb,0x90,0x01,0x55,0xAA};unsigned char Can1_Recv_Buf[10]={0};extern int angle_num ;extern unsigned int angle_data ; static u8 CAN_msg_num[MAX_MAIL_NUM]; // 发送邮箱标记 void CAN1_Config_init(void){ CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure; /* CAN register init */ CAN_DeInit(CAN1); CAN_StructInit(&CAN_InitStructure); /* CAN cell init */ //36MHz 500Kbps CAN_InitStructure.CAN_TTCM=DISABLE;//禁止时间触发通信模式 CAN_InitStructure.CAN_ABOM=DISABLE;//软件对CAN_MCR寄存器的INRQ位进行置1随后清0后,一旦硬件检测 //到128次11位连续的隐性位,就退出离线状态 CAN_InitStructure.CAN_AWUM=DISABLE;//睡眠模式通过清除CAN_MCR寄存器的SLEEP位,由软件唤醒 CAN_InitStructure.CAN_NART=DISABLE;//CAN报文是否只发1次,不管发送的结果如何(成功/出错或仲裁丢失) CAN_InitStructure.CAN_RFLM=DISABLE;//在接收到溢出时FIFO未被锁定,当接收到FIFO报文未被读出,下一个收到的报文会覆盖原有的报文 CAN_InitStructure.CAN_TXFP=DISABLE;//发送的FIFO优先级由报文的标识符来决定 #if CAN_DEBUG CAN_InitStructure.CAN_Mode= CAN_Mode_LoopBack;#else CAN_InitStructure.CAN_Mode= CAN_Mode_Normal; #endif //传输波特率 if(CAN1_BPS == 0) { CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;//重新同步跳跃宽度1个时间单位 CAN_InitStructure.CAN_BS1=CAN_BS1_12tq;//时间段1为9个时间单位 CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;//时间段2为8个时间单位 CAN_InitStructure.CAN_Prescaler= 9;//36M/(1+12+3)/9= 250kbps //36M/(1+5+2)/9 = 500kbps //36M(1+2+1)/9 = 1M } else if(CAN1_BPS == 1) { CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;//重新同步跳跃宽度1个时间单位 CAN_InitStructure.CAN_BS1=CAN_BS1_5tq;//时间段1为9个时间单位 CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;//时间段2为8个时间单位 CAN_InitStructure.CAN_Prescaler= 9;//36M/(1+12+3)/9= 250kbps } else { CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;//重新同步跳跃宽度1个时间单位 CAN_InitStructure.CAN_BS1=CAN_BS1_2tq;//时间段1为9个时间单位 CAN_InitStructure.CAN_BS2=CAN_BS2_1tq;//时间段2为8个时间单位 CAN_InitStructure.CAN_Prescaler= 9;//36M/(1+12+3)/9= 250kbps } CAN_Init(CAN1,&CAN_InitStructure); /* CAN filter init */ CAN_FilterInitStructure.CAN_FilterNumber=0; //指定了待初始化的过滤器0 CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//指定了过滤器将被初始化到的模式为标识符屏蔽位模式 CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;;//给出了过滤器位宽1个32位过滤器 CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;//用来设定过滤器标识符(32位位宽时为其高段位,16位位宽时为第一个) CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;;//用来设定过滤器标识符(32位位宽时为其低段位,16位位宽时为第二个) CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//用来设定过滤器屏蔽标识符或者过滤器标识符(32位位宽时为其高段位,16位位宽时为第一个) CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;//用来设定过滤器屏蔽标识符或者过滤器标识符(32位位宽时为其低段位,16位位宽时为第二个) CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;;//设定了指向过滤器的FIFO0 CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//使能过滤器 CAN_FilterInit(&CAN_FilterInitStructure); } // ***************************************************************// BaudRate = 1 / NominalBitTime// NominalBitTime = 1tq + tBS1 + tBS2// tq = (BRP[9:0] + 1) x tPCLK// tPCLK = CAN's clock = APB1's clock// 1Mbps 速率下,采用点的位置在6tq位置处,BS1=5, BS2=2// 500kbps 速率下,采用点的位置在8tq位置处,BS1=7, BS2=3// 250kbps 速率下,采用点的位置在14tq位置处,BS1=13, BS2=2// 125k, 100k, 50k, 20k, 10k 的采用点位置与 250K 相同// **************************************************************** void CAN1_Com_init(void){ GPIO_InitTypeDef GPIO_InitStruct; NVIC_InitTypeDef NVIC_InitStructure; /* Enable CAN RX0 interrupt IRQ channel */ NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); //Can Rx GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA,&GPIO_InitStruct); //Can Tx GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA,&GPIO_InitStruct); CAN1_Config_init(); CAN_ITConfig(CAN1,CAN_IT_FMP0 | CAN_IT_FF0 | CAN_IT_FOV0, ENABLE); // fifo0中断 CAN_ITConfig(CAN1,CAN_IT_FMP1 | CAN_IT_FF1 | CAN_IT_FOV1, ENABLE); // fifo1中断 CAN_ITConfig(CAN1,CAN_IT_TME, DISABLE); // 发送中断 CAN_ITConfig(CAN1,CAN_IT_EWG | CAN_IT_EPV | CAN_IT_BOF | CAN_IT_LEC | CAN_IT_ERR | CAN_IT_WKU | CAN_IT_SLK, ENABLE); // ERR中断 // CAN缓存初始化 memset(CAN_msg_num,0,MAX_MAIL_NUM); } int CAN1_Tx_msg(CanTxMsg TxMessage){ u8 TransmitMailbox = 0; TransmitMailbox = CAN_Transmit(CAN1,&TxMessage); if(CAN_NO_MB == TransmitMailbox) { //发送失败 return 0; } else { CAN_msg_num[TransmitMailbox] = 1; } CAN_ITConfig(CAN1,CAN_IT_TME, ENABLE); return 1;} u16 angle=0,angle_h=0,angle_l=0; extern unsigned char angle_dir;int CAN1_Tx_data(void){ CanTxMsg TxMessage; u8 TransmitMailbox = 0,i=0; /* transmit */ TxMessage.StdId=0x6f1;//设定标准标识符 TxMessage.ExtId=0x1234;//设置扩展标识符 TxMessage.RTR=CAN_RTR_DATA;//设定待传输消息的帧类型 TxMessage.IDE=CAN_ID_STD;//设定消息标识符的类型 TxMessage.DLC=6; //数据长度 angle=angle_data/10; if(angle>9999) angle=9999; angle_h=angle/100; angle_h=angle_h/10*16+angle_h%10; angle_l=angle%100; angle_l=angle_l/10*16+angle_l%10; Can1_Send_Buf[0]=angle_num; //圈数 Can1_Send_Buf[1]=angle_h; //总角度 Can1_Send_Buf[2]=angle_l; Can1_Send_Buf[3]=0; Can1_Send_Buf[4]=0; Can1_Send_Buf[5]=angle_dir; for(i=0;i < TxMessage.DLC;i++) { TxMessage.Data[i] = Can1_Send_Buf[i]; } TransmitMailbox = CAN_Transmit(CAN1,&TxMessage); if(CAN_NO_MB == TransmitMailbox) { //发送失败,没有空邮箱 return 0; } else { CAN_msg_num[TransmitMailbox] = 1; } CAN_ITConfig(CAN1,CAN_IT_TME, ENABLE); Can1_Tx_Count++; if(Can1_Tx_Count > 10000) Can1_Tx_Count =0; Can1_Send_Delay =200; return 1;} //解析数据void CAN1_Rx_Data(CanRxMsg RxMessage){ u8 i =0; if((RxMessage.StdId==0x6f1) && (RxMessage.IDE==CAN_ID_STD) && ((RxMessage.Data[1]|RxMessage.Data[0]<<8)==0xEB90)) { for(i=0;i < RxMessage.DLC;i++) { Can1_Recv_Buf[i] = RxMessage.Data[i]; } Can1_Rx_Count++; if(Can1_Rx_Count > 10000) Can1_Rx_Count =0; }}//发送完中断函数void CAN1_Send(void){ if(CAN_msg_num[0]) { if(CAN_GetITStatus(CAN1,CAN_IT_RQCP0)) { CAN_ClearITPendingBit(CAN1,CAN_IT_RQCP0); CAN_ITConfig(CAN1,CAN_IT_TME, DISABLE); CAN_msg_num[0] = 0; } } if(CAN_msg_num[1]) { if(CAN_GetITStatus(CAN1,CAN_IT_RQCP1)) { CAN_ClearITPendingBit(CAN1,CAN_IT_RQCP1); CAN_ITConfig(CAN1,CAN_IT_TME, DISABLE); CAN_msg_num[1] = 0; } } if(CAN_msg_num[2]) { if(CAN_GetITStatus(CAN1,CAN_IT_RQCP2)) { CAN_ClearITPendingBit(CAN1,CAN_IT_RQCP2); CAN_ITConfig(CAN1,CAN_IT_TME, DISABLE); CAN_msg_num[2] = 0; } }}//接收中断函数void CAN1_Recv(unsigned char num){ CanRxMsg RxMessage; switch(num) { case 0: if(CAN_GetITStatus(CAN1,CAN_IT_FF0)) { CAN_ClearITPendingBit(CAN1,CAN_IT_FF0); } else if(CAN_GetITStatus(CAN1,CAN_IT_FOV0)) { CAN_ClearITPendingBit(CAN1,CAN_IT_FOV0); } else { CAN_Receive(CAN1,CAN_FIFO0, &RxMessage); //解析数据: CAN1_Rx_Data(RxMessage); } break; case 1: if(CAN_GetITStatus(CAN1,CAN_IT_FF1)) { CAN_ClearITPendingBit(CAN1,CAN_IT_FF1); } else if(CAN_GetITStatus(CAN1,CAN_IT_FOV1)) { CAN_ClearITPendingBit(CAN1,CAN_IT_FOV1); } else { CAN_Receive(CAN1,CAN_FIFO1, &RxMessage); //解析数据 CAN1_Rx_Data(RxMessage); } break; } } void CAN1_Main(unsigned char flg ){ if(flg) { if(Can1_Send_Delay == 0) CAN1_Tx_data(); }}
0 0
- STM 32 之can 实例+代码解析
- STM 32 之can 实例+代码解析
- STM 32 之can 实例+代码解析
- STM 32 can 波特率的 确定
- STM 32之智能温控器
- STM CAN filter配置纪要
- 实例分析:STM LDM
- STM之SD卡
- arm ldm stm指令解析
- arm--ldm、stm指令解析
- arm ldm stm指令解析
- arm ldm stm指令解析
- arm ldm stm指令解析
- STM 32 SPI调试之HAL库的调试
- STM-32中的中断
- STM 32 EXTI
- STM 32 窗口看门狗
- stm 32 在线升级
- MFC ListControl控件使用InsertItem()函数插入新的列表项后不能显示列表项名称
- Maven项目中遇到的奇葩问题(续)
- java.util.NoSuchElementException
- caffe源码解析之blob.hpp或blob.cpp
- MyBatis自动生成代码
- STM 32 之can 实例+代码解析
- Java synchronized详解
- 实现沉浸式actionbar的非常规方法
- 记一次foxmailQQ邮箱创建失败到解决方法
- VS2015 使用IIS Express 支持非localhost访问
- Samba
- Json数据格式
- Android 开源项目及库
- Java内存和垃圾回收