头文件can.h:1.定义测试ID;2.声明相关函数;
#ifndef __CAN_H
#define __CAN_H
#include "stm32f10x.h"
#include "stm32f10x_can.h"
#define CAN_RX0_INT_ENABLE ENABLE
#define TESTID (0x0CF11AD0 & 0xFFFFFFFF)
#define HAN_TESTID ((TESTID<<3) | (0x01<<2) | (0x00<<1))
uint8_t Can_Mode_Init(u8 tsjw, u8 tbs2, u8 tbs1, u16 brp, u8 mode);
uint8_t Can_Mode_Init1(u8 tsjw, u8 tbs2, u8 tbs1, u16 brp, u8 mode);
uint8_t Can_Send_Msg(uint8_t* msg,uint8_t len);
uint8_t Can_Send_Msg1(uint8_t* msg,uint8_t len,uint32_t ExId);
uint8_t Can_Recive_Msg(uint8_t* buf);
#endif
源文件can.c:1.CAN1相关初始化(使用库函数及自己写寄存器);2.CAN发送报文函数(使用库函数及自己写寄存器);3.CAN接收函数;
#include "can.h"
uint8_t Can_Mode_Init(u8 tsjw, u8 tbs2, u8 tbs1, u16 brp, u8 mode)
{
GPIO_InitTypeDef GPIO_InitStruct;
CAN_InitTypeDef CAN_InitStruct;
CAN_FilterInitTypeDef CAN_FilterInitStruct;
#if CAN_RX0_INT_ENABLE
NVIC_InitTypeDef NVIC_InitStruct;
#endif
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
GPIO_Init(GPIOA,&GPIO_InitStruct);
CAN_InitStruct.CAN_TTCM = DISABLE;
CAN_InitStruct.CAN_ABOM = DISABLE;
CAN_InitStruct.CAN_AWUM = DISABLE;
CAN_InitStruct.CAN_NART = ENABLE;
CAN_InitStruct.CAN_RFLM = DISABLE;
CAN_InitStruct.CAN_TXFP = DISABLE;
CAN_InitStruct.CAN_Mode = mode;
CAN_InitStruct.CAN_SJW = tsjw;
CAN_InitStruct.CAN_BS1 = tbs1;
CAN_InitStruct.CAN_BS2 = tbs2;
CAN_InitStruct.CAN_Prescaler = brp;
CAN_Init(CAN1,&CAN_InitStruct);
CAN_FilterInitStruct.CAN_FilterNumber = 0;
CAN_FilterInitStruct.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStruct.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStruct.CAN_FilterIdHigh = (HAN_TESTID&0xFFFF0000)>>16;
CAN_FilterInitStruct.CAN_FilterIdLow = (HAN_TESTID&0x0000FFFF);
CAN_FilterInitStruct.CAN_FilterMaskIdHigh = 0xFFFF;
CAN_FilterInitStruct.CAN_FilterMaskIdLow = 0xFFFF;
CAN_FilterInitStruct.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
CAN_FilterInitStruct.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStruct);
#if CAN_RX0_INT_ENABLE
CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct);
#endif
return 0;
}
uint8_t Can_Send_Msg(uint8_t* msg,uint8_t len)
{
u8 mbox;
u16 i = 0;
CanTxMsg TxMessage;
TxMessage.StdId = 0x12;
TxMessage.ExtId = 0x12;
TxMessage.IDE = CAN_Id_Standard;
TxMessage.RTR = CAN_RTR_Data;
TxMessage.DLC = len;
for(i=0; i<len; i++)
{
TxMessage.Data[i] = msg[i];
}
mbox = CAN_Transmit(CAN1,&TxMessage);
i = 0;
while((CAN_TransmitStatus(CAN1,mbox) != CAN_TxStatus_Ok) && (i<0xfff)) i++;
if(i >= 0xfff) return 1;
return 0;
}
uint8_t Can_Recive_Msg(uint8_t* buf)
{
u32 i;
uint8_t stat = 0;
CanRxMsg RxMessage;
if(CAN_MessagePending(CAN1,CAN_FIFO0) == 0) return 0;
CAN_Receive(CAN1,CAN_FIFO0,&RxMessage);
if(RxMessage.FMI == 0)
{
for(i=0; i<8; i++)
{
buf[i] = RxMessage.Data[i];
}
stat = RxMessage.DLC;
}
return stat ;
}
uint8_t Can_Mode_Init1(u8 tsjw, u8 tbs2, u8 tbs1, u16 brp, u8 mode)
{
uint32_t wait_ack = 0;
uint8_t InitStatus = 0;
CAN_FilterInitTypeDef CAN_FilterInitStruct;
RCC->APB1ENR |= 0x01<<25;
RCC->APB2ENR |= 0x01<<2;
GPIOA->CRH &= ~(0x0F<<12);
GPIOA->CRH |= 0x08<<12;
GPIOA->BSRR = 0x01<<11;
GPIOA->CRH &= ~(0x0F<<16);
GPIOA->CRH |= 0x0B<<16;
CAN1->MCR &= ~(0x01<<1);
CAN1->MCR |= 0x01<<0;
while (((CAN1->MSR & 0x01) != 0x01) && (wait_ack != 0x0000FFFF))
{
wait_ack++;
}
if(((CAN1->MSR & 0x01) != 0x01))
{
InitStatus = 0;
}
CAN1->MCR &= ~(0x01<<7);
CAN1->MCR &= ~(0x01<<6);
CAN1->MCR &= ~(0x01<<5);
CAN1->MCR &= ~(0x01<<4);
CAN1->MCR &= ~(0x01<<3);
CAN1->MCR &= ~(0x01<<2);
CAN1->BTR = (uint32_t)((uint32_t)mode << 30) | \
((uint32_t)tsjw << 24) | \
((uint32_t)tbs1 << 16) | \
((uint32_t)tbs2 << 20) | \
((uint32_t)brp - 1);
CAN1->MCR &= ~(0x01<<0);
wait_ack = 0;
while (((CAN1->MSR & 0x01) == 0x01) && (wait_ack != 0x0000FFFF))
{
wait_ack++;
}
if((CAN1->MSR & 0x01) == 0x01)
{
InitStatus = 0;
}
CAN_FilterInitStruct.CAN_FilterNumber = 0;
CAN_FilterInitStruct.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStruct.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStruct.CAN_FilterIdHigh = (HAN_TESTID&0xFFFF0000)>>16;
CAN_FilterInitStruct.CAN_FilterIdLow = (HAN_TESTID&0x0000FFFF);
CAN_FilterInitStruct.CAN_FilterMaskIdHigh = 0xFFFF;
CAN_FilterInitStruct.CAN_FilterMaskIdLow = 0xFFFF;
CAN_FilterInitStruct.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
CAN_FilterInitStruct.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStruct);
return InitStatus;
}
uint8_t Can_Send_Msg1(uint8_t* msg,uint8_t len,uint32_t ExId)
{
u8 transmit_mailbox;
u16 i = 0;
if((CAN1->TSR & (0x01<<26)) == (0x01<<26))
{
transmit_mailbox = 0;
}
else if((CAN1->TSR & (0x01<<27)) == (0x01<<27))
{
transmit_mailbox = 1;
}
else if((CAN1->TSR & (0x01<<28)) == (0x01<<28))
{
transmit_mailbox = 2;
}
else
{
transmit_mailbox = 4;
}
if(transmit_mailbox != 0x04)
{
CAN1->sTxMailBox[transmit_mailbox].TIR &= 0x01;
CAN1->sTxMailBox[transmit_mailbox].TIR |= (0x00<<1) | (0x01<<2) | (ExId&0xffffffff)<<3 ;
CAN1->sTxMailBox[transmit_mailbox].TDTR &= (uint32_t)0xFFFFFFF0;
CAN1->sTxMailBox[transmit_mailbox].TDTR |= len&0x0f;
CAN1->sTxMailBox[transmit_mailbox].TDLR = ((u32)msg[0]) | ((u32)msg[1]<<8) | ((u32)msg[2]<<16) |((u32)msg[3]<<24);
CAN1->sTxMailBox[transmit_mailbox].TDHR = ((u32)msg[4]) | ((u32)msg[5]<<8) | ((u32)msg[6]<<16) |((u32)msg[7]<<24);
CAN1->sTxMailBox[transmit_mailbox].TIR |=0x01;
}
i = 0;
while((CAN_TransmitStatus(CAN1,transmit_mailbox) != CAN_TxStatus_Ok) && (i<0xfff)) i++;
if(i >= 0xfff) return 1;
return 0;
}
中断服务函数,
uint8_t buf[8] = {0,1,2,3,4,5,6,7};
uint8_t stat = 0;
void USB_LP_CAN1_RX0_IRQHandler(void)
{
uint8_t i;
CanRxMsg RxMessage;
stat = 0;
CAN_Receive(CAN1,CAN_FIFO0,&RxMessage);
if(RxMessage.FMI == 0)
{
for(i=0; i<8; i++)
{
buf[i] = RxMessage.Data[i];
}
stat = RxMessage.DLC;
}
ToggleLed(GPIOB,GPIO_Pin_15);
}
uint8_t ReadRxDat(uint8_t* read_buff)
{
uint8_t i;
uint8_t rx_ok =0;
if(stat != 0)
{
for(i = 0; i<8; i++)
{
read_buff[i] = buf[i];
}
stat = 0;
rx_ok = 1;
}
return rx_ok;
}
主函数main.c:1.调用初始化函数;2.若收到报文则向上位机返回原报文;
#include "stm32f10x.h"
#include "stm32f10x_it.h"
#include "led.h"
#include "timer.h"
#include "systick.h"
#include "can.h"
int main(void)
{
uint8_t can_buf[8] = {0,1,2,3,4,5,6,7};
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
LedInit1();
SysTick_Init();
Can_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq ,CAN_BS1_9tq ,8,CAN_Mode_Normal);
while(1)
{
if(ReadRxDat(can_buf) != 0)
{
Can_Send_Msg1(can_buf,8,TESTID);
ToggleLed(GPIOC,GPIO_Pin_6);
}
Delay_ms(500);
}
}
亲测可用,无论是库函数还是自己写的寄存器都能使用!!!
参考资料:正点原子代码及STM32中文参考手册!!!
|