stm32之CAN(二)

来源:互联网 发布:梦幻西游mac更新错误 编辑:程序博客网 时间:2024/05/23 14:34

下面这个例程是通过CAN接收中断来实现CAN的回环测试。当测试成功时,LED2点亮,并且通过串口打印。

如下代码:

main.c

#include "stm32f10x.h"#include "led.h"#include "usart1.h"void USART1_Configuration(void);void LED_GPIO_Configuration(void);void CAN_Configuration(void);void CAN_NVIC_Configuration(void);void CAN_Test(void);typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;volatile TestStatus TestRx;/* 在中断处理函数中返回 */__IO uint32_t ret = 0;int main(void){USART1_Configuration();//初始化串口LED_GPIO_Configuration();//初始化LEDCAN_NVIC_Configuration();CAN_Configuration();//初始化CANprintf( "\r\n CAN 中断测试初始化成功...... \r\n" );CAN_Test();printf( "\r\n CAN 中断测试成功...... \r\n" );while(1);}/*CAN GPIO 和时钟配置 以及CAN的控制器和过滤器配置*/void CAN_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure; CAN_InitTypeDef  CAN_InitStructure;CAN_FilterInitTypeDef  CAN_FilterInitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);                         /* CAN1 Periph clock enable */RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);/* Configure CAN pin: RX */               // PB8GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;             // 上拉输入GPIO_Init(GPIOB, &GPIO_InitStructure);/* Configure CAN pin: TX */               // PB9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         // 复用推挽输出GPIO_Init(GPIOB, &GPIO_InitStructure);/*CAN控制器初始化结构体*//* CAN register init */CAN_DeInit(CAN1);//can寄存器复位CAN_StructInit(&CAN_InitStructure);/* CAN cell init */CAN_InitStructure.CAN_TTCM=DISABLE;           // 时间触发通信禁止CAN_InitStructure.CAN_ABOM=DISABLE;          // 离线退出是在中断置位清0后退出CAN_InitStructure.CAN_AWUM=DISABLE;          // 自动唤醒模式:清零sleepCAN_InitStructure.CAN_NART=DISABLE;          // 自动重新传送报文,直到发送成功CAN_InitStructure.CAN_RFLM=DISABLE;          // FIFO没有锁定,新报文覆盖旧报文CAN_InitStructure.CAN_TXFP=DISABLE;           // 发送报文优先级确定:标志符CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack; // 回环模式CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;        // 1tq、BS1、BS2的值跟波特率有关CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;CAN_InitStructure.CAN_Prescaler=1;  // 分频系数为1CAN_Init(CAN1, &CAN_InitStructure);// 初始化CAN1/*CAN过滤器初始化结构体*//* CAN filter init */CAN_FilterInitStructure.CAN_FilterNumber=0;//初始化过滤器0CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//标识符屏蔽位模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//使用1个32位过滤器CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;//过滤器标识符为0x00000000CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//过滤器屏蔽标识符为0x00000000,即不屏蔽任何消息CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;//过滤器FIFO0指向过滤器0CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//使能过滤器CAN_FilterInit(&CAN_FilterInitStructure);}/*CAN的中断控制器设置*/void CAN_NVIC_Configuration(void){NVIC_InitTypeDef NVIC_InitStructure;/* Enable CAN1 RX0 interrupt IRQ channel */NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; /*!< USB Device Low Priority or CAN1 RX0 Interrupts       */NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;     // 主优先级为0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}TestStatus CAN_Interrupt(void){CanTxMsg TxMessage;//定义消息发送结构体uint32_t i = 0;/* CAN FIFO0 message pending interrupt enable */ CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); //中断使能/* transmit 1 message */TxMessage.StdId=0x00; // 标准标识符为0TxMessage.ExtId=0x1234; // 设置扩展标示符(29位)TxMessage.IDE=CAN_ID_EXT; // 使用扩展标识符TxMessage.RTR=CAN_RTR_DATA; // 消息类型为数据帧,一帧8位TxMessage.DLC=2; // 发送两帧信息TxMessage.Data[0]=0xDE; // 第一帧信息TxMessage.Data[1]=0xCA; // 第二帧信息CAN_Transmit(CAN1, &TxMessage);/* initialize the value that will be returned */ret = 0xFF;/* receive message with interrupt handling */i=0;while((ret == 0xFF) && (i < 0xFFF)){i++;}if (i == 0xFFF){ret=0;  }/* disable interrupt handling */CAN_ITConfig(CAN1, CAN_IT_FMP0, DISABLE);return (TestStatus)ret;}void CAN_Test(void){TestRx = CAN_Interrupt();if (TestRx == FAILED){    LED2( OFF );// LED2 OFF; }else{   LED2( ON );  // LED2 ON;}}

stm32f10x_it.c

#include "stm32f10x.h"extern __IO uint32_t ret;void USB_LP_CAN1_RX0_IRQHandler(void)//中断处理函数{CanRxMsg RxMessage;RxMessage.StdId=0x00;RxMessage.ExtId=0x00;RxMessage.IDE=0;RxMessage.DLC=0;RxMessage.FMI=0;RxMessage.Data[0]=0x00;RxMessage.Data[1]=0x00;CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);if((RxMessage.ExtId==0x1234)  &&    (RxMessage.IDE==CAN_ID_EXT)&&    (RxMessage.DLC==2)         &&    ((RxMessage.Data[1]|RxMessage.Data[0]<<8)==0xDECA)){ret = 1; }else{ret = 0; }}


0 0