stm32 can中断通信

来源:互联网 发布:苹果越狱会清除数据吗 编辑:程序博客网 时间:2024/06/05 03:00

1、初始化can时钟

void canRCCInit(){    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);}

2、配置can的GPIO引脚

void canGPIOConfigure(){    GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);    GPIO_InitTypeDef gpioInit;    gpioInit.GPIO_Pin = GPIO_Pin_8;    gpioInit.GPIO_Mode = GPIO_Mode_IPU;    gpioInit.GPIO_Speed = GPIO_Speed_50MHz;    GPIO_Init(GPIOB, &gpioInit);    gpioInit.GPIO_Pin = GPIO_Pin_9;    gpioInit.GPIO_Mode = GPIO_Mode_AF_PP;    GPIO_Init(GPIOB, &gpioInit);

3、配置并使能can

void canConfigure(){    CAN_InitTypeDef can_init;    CAN_DeInit(CAN1);    CAN_StructInit(&can_init);    //关闭时间触发模式    can_init.CAN_TTCM = DISABLE;        //关闭自动离线管理    can_init.CAN_ABOM = DISABLE;    //关闭自动唤醒模式    can_init.CAN_AWUM = DISABLE;    //禁止报文自动重发    can_init.CAN_NART = DISABLE;    //FIFO 溢出时报文覆盖原文件    can_init.CAN_RFLM = DISABLE;    //报文发送优先级取决于ID号    can_init.CAN_TXFP = DISABLE;    //回环模式    can_init.CAN_Mode = CAN_Mode_LoopBack;    //配置时钟频率    can_init.CAN_SJW = CAN_SJW_1tq;    can_init.CAN_BS1 = CAN_BS1_3tq;    can_init.CAN_BS2 = CAN_BS2_2tq;    can_init.CAN_Prescaler = 48;    CAN_Init(CAN1, &can_init);    CAN_FilterInitTypeDef can_filter;    //屏蔽滤波    can_filter.CAN_FilterNumber = 0;    //屏蔽模式    can_filter.CAN_FilterMode = CAN_FilterMode_IdMask;    //32位寄存器    can_filter.CAN_FilterScale = CAN_FilterScale_32bit;    //高16位    can_filter.CAN_FilterIdHigh = 0x0000;    //低16位    can_filter.CAN_FilterIdLow = 0;    //屏蔽位高16位    can_filter.CAN_FilterMaskIdHigh = 0;    //屏蔽位低16位    can_filter.CAN_FilterMaskIdLow = 0;    //过滤器0关联到FIFO0    can_filter.CAN_FilterFIFOAssignment = CAN_FilterFIFO0;    //使能过滤器    can_filter.CAN_FilterActivation = ENABLE;    //初始化过滤器    CAN_FilterInit(&can_filter);    //使能接收中断    CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);}

4、配置中断源

void canNvicConfigure(){    NVIC_InitTypeDef nvic_init;    nvic_init.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;    nvic_init.NVIC_IRQChannelPreemptionPriority = 0;    nvic_init.NVIC_IRQChannelSubPriority = 0;    nvic_init.NVIC_IRQChannelCmd = ENABLE;    NVIC_Init(&nvic_init);    nvic_init.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;    nvic_init.NVIC_IRQChannelPreemptionPriority = 0;    nvic_init.NVIC_IRQChannelSubPriority = 1;    nvic_init.NVIC_IRQChannelCmd = ENABLE;    NVIC_Init(&nvic_init);}

5、实现中断处理函数

void USB_LP_CAN1_RX0_IRQHandler(void){    CanRxMsg rx;    CAN_Receive(CAN1, CAN_FIFO0, &rx);    for(int i = 0; i < rx.DLC; i++){        printf("recv data: %c\r\n",rx.Data[i]);    }}void USB_HP_CAN1_TX_IRQHandler(void){    if(count < len){        txMessage.Data[0] = txBuf[count++];        CAN_Transmit(CAN1, &txMessage);    }    else {        CAN_ITConfig(CAN1, CAN_IT_TME, DISABLE);    }}

6、实现发送函数

void canWrite(const char *p){    strcpy(txBuf, p);    len = strlen(p);    count = 0;    txMessage.StdId = 0xFE00 >> 5;    txMessage.ExtId = 0;    txMessage.IDE = CAN_ID_STD;    txMessage.RTR = CAN_RTR_DATA;    txMessage.DLC = 1;  //此处最多可传输8个字节    txMessage.Data[0] = txBuf[count++];    CAN_Transmit(CAN1, &txMessage);    CAN_ITConfig(CAN1, CAN_IT_TME, ENABLE);}

7、总结:在写can总线协议时,需要自己仔细阅读stm32的官方手册,can总线有多种模式及标识符列表模式、标识符屏蔽模式等,需要自己仔细琢磨。

原创粉丝点击