STM32——CAN通信升级版本(队列方式)

    xiaoxiao2021-03-25  96

    #ifndef _TYPE_H_ #define _TYPE_H_ /* exact-width signed integer types */ typedef signed char int8_t; typedef signed short int int16_t; typedef signed int int32_t; typedef signed __int64 int64_t; /* exact-width unsigned integer types */ typedef unsigned char uint8_t; typedef unsigned short int uint16_t; typedef unsigned int uint32_t; typedef unsigned int size_t; typedef unsigned __int64 uint64_t; #ifndef NULL #ifdef __cplusplus // EC++ #define NULL 0 #else #define NULL ((void *) 0) #endif #endif #ifndef boolean typedef uint8_t boolean; #endif #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #endif /* _TYPE_H_ */ #ifndef _CAN_QUEUE_H_ #define _CAN_QUEUE_H_ #include "stm32f10x_can.h" #include "type.h" #define CAN_TX_SIZE 0x25 typedef enum { CAN_ERROR = 0, CAN_OK = 1, CAN_BUSY = 2, } can_queue_status_t; typedef CanTxMsg can_frame_t; typedef struct { uint32_t write; uint32_t read; boolean is_full; uint32_t length; can_frame_t *frame; } can_queue_t; extern can_queue_t can_queue_send; void CanQueueInit(void); uint8_t CanQueueRead(can_queue_t *q, can_frame_t *frame); uint8_t CanQueueWrite(can_queue_t *q, can_frame_t *frame); #endif /* _CAN_QUEUE_H_ */ #include "can_queue.h" #include <string.h> #include "debug.h" static can_frame_t tx[CAN_TX_SIZE] = {0}; can_queue_t can_queue_send = { 0, 0, FALSE, CAN_TX_SIZE, tx }; const can_frame_t frame_init = { 0, 0, 0, 0, 0, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, }; static void can_queue_init(can_queue_t *q, can_frame_t *frame, uint8_t length) { uint8_t i; q->write = 0; q->read = 0; q->is_full = FALSE; q->length = length; q->frame = frame; for(i = 0; i < length; ++i) { q->frame[i] = frame_init; } } static can_frame_t *can_frame_malloc(can_queue_t *q) { can_frame_t *frame; if(NULL == q) { return NULL; } if(TRUE == q->is_full) { return NULL; } frame = &(q->frame[q->write++]); if(q->write >= q->length) { q->write = 0; } if(q->write == q->read) { q->is_full = TRUE; } *frame = frame_init; return frame; } static void can_frame_clear(can_frame_t *frame) { can_frame_t *dst = frame; dst->StdId = 0; dst->DLC = 0; dst->IDE = CAN_Id_Standard; dst->RTR = CAN_RTR_Data; memset(dst->Data, 0, 8); } static void can_frame_copy(can_frame_t *dst, can_frame_t *src) { can_frame_t *dst_tmp = dst, *src_tmp = src; dst_tmp->StdId = src_tmp->StdId; dst_tmp->DLC = src_tmp->DLC; dst_tmp->IDE = src_tmp->IDE; dst_tmp->RTR = src_tmp->RTR; memcpy(dst_tmp->Data, src_tmp->Data, 8); } uint8_t CanQueueRead(can_queue_t *q, can_frame_t *frame) { uint8_t status = CAN_ERROR; if(NULL == q) { return CAN_ERROR; } if((q->read != q->write) || (q->is_full == TRUE)) { can_frame_copy(frame, &q->frame[q->read]); can_frame_clear(&q->frame[q->read]); q->read += 1; if(q->read >= q->length) { q->read = 0; } q->is_full = FALSE; status = CAN_OK; } return status; } uint8_t CanQueueWrite(can_queue_t *q, can_frame_t *frame) { can_frame_t *dst; dst = can_frame_malloc(q); if(NULL == dst) { return CAN_ERROR; } can_frame_copy(dst, frame); return CAN_OK; } void CanQueueInit(void) { can_queue_init(&can_queue_send, tx, CAN_TX_SIZE); } #ifndef _CAN_H_ #define _CAN_H_ #include "can_queue.h" #include "type.h" #include "debug.h" void CANInit(void); void CanSendMsg(can_frame_t *frame); #ifdef CONFIG_CAN void can_general(void); #endif #endif /* _CAN_H_ */ #include "can.h" #include "stm32f10x_can.h" #include "stm32f10x.h" #include "delay.h" #include "target.h" #include "string.h" static void can_gpio_clk_init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); GPIO_PinRemapConfig(GPIO_Remap2_CAN1, ENABLE); } static void can_gpio_init(void) { can_gpio_clk_init(); CAN_TX_CONFIG(); CAN_RX_CONFIG(); } static void can_mode_init(void) { CAN_InitTypeDef CAN_InitStructure; CAN_DeInit(CAN_CHANNEL); CAN_InitStructure.CAN_TTCM = DISABLE; CAN_InitStructure.CAN_ABOM = ENABLE ; CAN_InitStructure.CAN_AWUM = DISABLE; CAN_InitStructure.CAN_NART = ENABLE ; CAN_InitStructure.CAN_RFLM = DISABLE; CAN_InitStructure.CAN_TXFP = DISABLE; CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; // baund = APB1/((tbs1+1+tbs2+1+1)*brp) --- APB1 = 36K CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq; CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq; CAN_InitStructure.CAN_Prescaler = 8; CAN_Init(CAN_CHANNEL, &CAN_InitStructure); } static void can_nvic_init(void) { NVIC_InitTypeDef NVIC_InitStructure; CAN_ITConfig(CAN_CHANNEL, CAN_IT_FMP0, ENABLE); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } static void can_filter_init(void) { CAN_FilterInitTypeDef CAN_FilterInitStructure; CAN_FilterInitStructure.CAN_FilterNumber = 0; 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_Filter_FIFO0; CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; CAN_FilterInit(&CAN_FilterInitStructure); } void CANInit(void) { can_gpio_init(); can_mode_init(); can_filter_init(); can_nvic_init(); } void CanSendMsg(can_frame_t *frame) { int i; CAN_Transmit(CAN_CHANNEL, frame); for(i=0;i<1000;++i); } void CAN1_RX0_IRQHandler(void) { CanRxMsg RxMessage; CanTxMsg TxMessage; int i = 0; CAN_Receive(CAN_CHANNEL, 0, &RxMessage); #if 1 TxMessage.StdId = 0x101; TxMessage.IDE = CAN_Id_Standard; TxMessage.RTR = CAN_RTR_Data; TxMessage.DLC = RxMessage.DLC; for(i = 0; i < TxMessage.DLC; i++) { TxMessage.Data[i] = RxMessage.Data[i]; } CanQueueWrite(&can_queue_send, &TxMessage); #endif } #ifdef CONFIG_CAN void can_general(void) { int i; can_frame_t frame; uint8_t buffer[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; frame.StdId = 0x11; frame.DLC = 6; frame.IDE = CAN_Id_Standard; frame.RTR = CAN_RTR_Data; memcpy(frame.Data, buffer, 6); //CanQueueWrite(&can_queue_send, &frame); for(i = 0; i < 7000; ++i); } #endif
    转载请注明原文地址: https://ju.6miu.com/read-24437.html

    最新回复(0)