首页资源分类嵌入式处理器ARM MCU > stm32CAN源程序

stm32CAN源程序

已有 445025个资源

下载专区

上传者其他资源

    文档信息举报收藏

    标    签:stm32CANSTM32

    分    享:

    文档简介

    CAN总线详细资料非常全面

    文档预览

    /********************************************************************************** * 工程名 :泥人CAN模块 -- 环回模式例程 * 描述 :在环回模式下,bxCAN把发送的报文当接收的报文并保存(如果可以通过接收过滤) 在接收邮箱里 。也是就是环回模式是一个自发自收的模式 。 程序依次采用循环查询和中断的方式进行测试。测试结果可以通过串口查看 在此模式下,可以不接CAN收发器也能进行测试,这个只与STM32的CAN控制器有关, 只要配置正确就可以测试通过。 * 实验平台:NiRen_STM32mini板(或用户STM32开发板) + NiRen_CAN模块 * 硬件连接: VCC -> VCC CAN模块电源引脚,3.3还是5V需要根据CAN模块的芯片电压选择 * GND -> GND CAN模块公共地引脚 * PA11 -> RXD CAN模块接收引脚 * PA12 -> TXD CAN模块发送引脚 * 作者 :泥人通信模块开发团队 * 博客 :http://nirenelec.blog.163.com * 淘宝 :http://nirenelec.taobao.com **********************************************************************************/ #include "stm32f10x.h" #include //配置格式化输出函数“printf” #ifdef __GNUC__ /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf set to 'Yes') calls __io_putchar() */ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif /* __GNUC__ */ /* 变量列表 */ __IO uint32_t Result = 0; /* CAN接收中断返回值 */ /* 函数原型列表 */ void GPIO_Configuration(void); //GPIO初始化 void USART_Configuration(void); //串口1初始化 void NVIC_Configuration(void); //配置中断向量表 int CAN_Polling(void); //CAN配置为环回模式,接收采用查询方式 int CAN_Interrupt(void); //CAN配置为环回模式,接收采用中断方式 /******************************************************************************* * 函数名 : Delay * 描述 : 延时 * 输入 : - nCount: 延时时间 * 输出 : None * 返回 : None * 注意 : None *******************************************************************************/ void Delay (uint32_t nCount) { for(; nCount != 0; nCount--); } /******************************************************************************* * 函数名 : main * 描述 : 主函数 * 输入 : None * 输出 : None * 返回 : None * 注意 : None *******************************************************************************/ int main(void) { int TestRx;//接收测试状态 NVIC_Configuration(); //配置中断向量表 GPIO_Configuration(); //GPIO初始化 USART_Configuration();//串口1初始化 printf("\r\n****************************************************************\r\n"); printf("CAN-Bus 环回模式测试\r\n"); /*在环回模式下,标准帧发送,接收采用查询方式*/ TestRx = CAN_Polling(); if (TestRx == DISABLE) { printf("CAN-Bus 环回模式采用查询方式测试失败 \r\n"); } else { printf("CAN-Bus 环回模式采用查询方式测试成功 \r\n"); } /*在环回模式下,拓展帧发送,接收采用中断方式*/ TestRx = CAN_Interrupt(); if (TestRx == DISABLE) { printf("CAN-Bus 环回模式采用中断方式测试失败 \r\n"); } else { printf("CAN-Bus 环回模式采用中断方式测试成功 \r\n"); } while (1) { /*====LED-OFF=======*/ GPIO_SetBits(GPIOA , GPIO_Pin_8); Delay(0xfffff); Delay(0xfffff); Delay(0x5ffff); /*====LED-ON=======*/ GPIO_ResetBits(GPIOA , GPIO_Pin_8); Delay(0xfffff); Delay(0xfffff); Delay(0x5ffff); } } /******************************************************************************* * 函数名 : GPIO_Configuration * 描述 : 配置GPIO端口 * 输入 : None * 输出 : None * 返回 : None * 注意 : None *******************************************************************************/ void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; /*GPIOA时钟使能*/ RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA , ENABLE); /*CAN1时钟使能*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); /* 配置CAN.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); /* 配置CAN.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); /* 配置LED->PA8引脚(以NiRen-STM32mini板为例)*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); } /******************************************************************************* * 函数名 : NVIC_Configuration * 描述 : 配置中断向量表 * 输入 : None * 输出 : None * 返回 : None * 注意 : None *******************************************************************************/ void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* 使能CAN1的接收中断 */ NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /******************************************************************************* * 函数名 : CAN_Polling * 描述 : 配置CAN控制器工作在环回标准帧模式,并启动一次发送,接收通过查询方式 * 输入 : None * 输出 : None * 返回 : 测试是否通过 * 注意 : None *******************************************************************************/ int CAN_Polling(void) { CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure; CanTxMsg TxMessage; CanRxMsg RxMessage; uint32_t i = 0; uint8_t TransmitMailbox = 0; /* CAN 寄存器初始化 */ CAN_DeInit(CAN1);//将CAN1所有寄存器设置为缺省值 CAN_StructInit(&CAN_InitStructure);//将结构体参数按缺省值填入 /* CAN 寄存器初始化 关于CAN通信波特率的计算可以查看STM32中文参考手册*/ 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_LoopBack;//CAN工作在环回模式 CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;//重新同步跳跃宽度1个时间单位 CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;//时间段1为8个时间单位 CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;//时间段2为7个时间单位 CAN_InitStructure.CAN_Prescaler=5; //一个时间单位为5 CAN_Init(CAN1, &CAN_InitStructure); //根据参数初始化CAN /* 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;//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 CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//激活过滤器 CAN_FilterInit(&CAN_FilterInitStructure);//根据参数初始化CAN过滤器 /* 发送处理 */ TxMessage.StdId=0x11; //标准帧标识符 TxMessage.RTR=CAN_RTR_DATA; //数据帧 TxMessage.IDE=CAN_ID_STD; //使用标准帧 TxMessage.DLC=2; //数据长度 TxMessage.Data[0]=0xCA; //数据内容 TxMessage.Data[1]=0xFE; TransmitMailbox=CAN_Transmit(CAN1, &TxMessage);//发送一帧数据 i = 0; while((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK) && (i != 0xFF))//等待发送完成 { i++; } i = 0; while((CAN_MessagePending(CAN1, CAN_FIFO0) < 1) && (i != 0xFF)) //查询邮箱0是否接收到数据 { i++; } /* 接收处理 */ RxMessage.StdId=0x00; RxMessage.IDE=CAN_ID_STD; RxMessage.DLC=0; RxMessage.Data[0]=0x00; RxMessage.Data[1]=0x00; CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//读取邮箱0 数据 if (RxMessage.StdId!=0x11)//判断标示符是否正确 { return DISABLE; } if (RxMessage.IDE!=CAN_ID_STD) //判断是否是标准帧 { return DISABLE; } if (RxMessage.DLC!=2) //数据长度是否正确 { return DISABLE; } if ((RxMessage.Data[0]<<8|RxMessage.Data[1])!=0xCAFE) //数据内容是否正确 { return DISABLE; } return ENABLE; /* 测试通过 */ } /******************************************************************************* * 函数名 : CAN_Interrupt * 描述 : 配置CAN控制器工作在环回拓展帧模式,并启动一次发送,接收通过中断方式 * 输入 : None * 输出 : None * 返回 : 测试是否通过 * 注意 : None *******************************************************************************/ int CAN_Interrupt(void) { CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure; CanTxMsg TxMessage; uint32_t i = 0; /* CAN 寄存器初始化 */ CAN_DeInit(CAN1); CAN_StructInit(&CAN_InitStructure); /* CAN 寄存器初始化 关于CAN通信波特率的计算可以查看STM32中文参考手册*/ 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; CAN_InitStructure.CAN_TXFP=DISABLE; CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack; CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; CAN_InitStructure.CAN_BS1=CAN_BS1_8tq; CAN_InitStructure.CAN_BS2=CAN_BS2_7tq; CAN_InitStructure.CAN_Prescaler=1; CAN_Init(CAN1, &CAN_InitStructure); /* CAN 过滤器组初始化 */ CAN_FilterInitStructure.CAN_FilterNumber=1; 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; CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000; CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0; CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; CAN_FilterInit(&CAN_FilterInitStructure); /*CAN FIFO0信息挂号中断使能*/ CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); /* 发送一帧数据 */ TxMessage.StdId=0x00; TxMessage.ExtId=0x1234; //拓展帧标识符 TxMessage.IDE=CAN_ID_EXT; //拓展帧 TxMessage.RTR=CAN_RTR_DATA;//数据帧 TxMessage.DLC=2; //发送数据长度 TxMessage.Data[0]=0xDE; //发送数据内容 TxMessage.Data[1]=0xCA; CAN_Transmit(CAN1, &TxMessage);//启动一次发送 /* 初始化中间变量 */ Result = 0xFF; //CAN接收中断中接收到正确数据Result=1否则为0 /* 等待接收中断返回 */ i=0; while((Result == 0xFF) && (i < 0xFFF)) { i++; } /*接收超时,返回0*/ if (i == 0xFFF) { Result=0; } /* 失能接收中断 */ CAN_ITConfig(CAN1, CAN_IT_FMP0, DISABLE); return (FunctionalState)Result; } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) { } } #endif /********************************************************************************************************* END FILE *********************************************************************************************************/

    Top_arrow
    回到顶部
    EEWORLD下载中心所有资源均来自网友分享,如有侵权,请发送举报邮件到客服邮箱bbs_service@eeworld.com.cn 或通过站内短信息或QQ:273568022联系管理员 高员外,我们会尽快处理。