初级会员

- 积分
- 197
- 金钱
- 197
- 注册时间
- 2016-2-19
- 在线时间
- 48 小时
|
1金钱
RT-Thread Studio 工程中,CAN能发数据,接收不到
STM32F407
PA11,12收发引脚
以下是源码
can.h
#ifndef _CAN_H_
#define _CAN_H_
#include "stdint.h"
#include <rtthread.h>
#include <drv_common.h>
#include "sys.h"
typedef union
{
u32 reg;
struct
{
u32 Priority : 4; //优先级,值月越小优先级越高。
u32 No : 8; //优先级,值月越小优先级越高。
u32 Adr : 16; //数据地址
}D;
}Canid;
#define CAN_BUFFER_SIZE 128
typedef struct {
uint32_t id[CAN_BUFFER_SIZE];
uint8_t dlc[CAN_BUFFER_SIZE];
uint8_t data[CAN_BUFFER_SIZE][8];
uint16_t in;
uint16_t out;
uint16_t size;
}CanBuffer;
#define Can_Y_Send 5
#define Can_X_Send 6
#define Can_ADC_Send 7
#define Can_Pul 8
#define Can_Pul_cmd 9
#define Can_Pul_set 10
#define Can_Pul_status 11
extern CanBuffer tx_buf;
extern CanBuffer rx_buf;
extern Canid canid;
extern u8 Sdata[8];
void User_Can_Rece(void); //CAN 数据接收
void User_Can_Send_Rece(void); //CAN 数据收发
uint8_t CAN_EnqueueTx(uint32_t ext_id, uint8_t len);
void can_printf(void);
#endif /* 0HARDWARE_CAN_H_ */
can.c
#include "define.h"
#include <rtthread.h>
#include <rtdevice.h>
#include <stdio.h>
#include "stm32f4xx.h"
#include "rtdef.h"
CAN_TxHeaderTypeDef TxHeader; //发送
CAN_RxHeaderTypeDef RxHeader; //接收
CanBuffer tx_buf = {0};
CanBuffer rx_buf = {0};
Canid canid;
u8 Sdata[8]={1,2,3,4,5,6,7};
CAN_TxHeaderTypeDef Txheader;
#define CAN_SPEED_500K 0
#define CAN_SPEED_250K 1
CAN_HandleTypeDef hcan1;
void CAN_Init(uint8_t speed_mode)
{
CAN_FilterTypeDef filter = {
.FilterIdHigh = 0x0000,
.FilterMaskIdHigh = 0x0000, // 接收所有ID
.FilterFIFOAssignment = CAN_FILTER_FIFO0,
.FilterBank = 0,
.FilterMode = CAN_FILTERMODE_IDMASK,
.FilterScale = CAN_FILTERSCALE_32BIT,
.FilterActivation = ENABLE
};
// 公共参数配置
hcan1.Instance = CAN1;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
// 速度参数动态配置
switch(speed_mode) {
case CAN_SPEED_500K:
hcan1.Init.Prescaler = 7;
hcan1.Init.TimeSeg1 = CAN_BS1_9TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
break;
case CAN_SPEED_250K:
hcan1.Init.Prescaler = 14;
hcan1.Init.TimeSeg1 = CAN_BS1_9TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
break;
}
// 其他固定参数
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = ENABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
HAL_CAN_ConfigFilter(&hcan1, &filter);
HAL_CAN_Init(&hcan1); // 初始化CAN控制器 :ml-citation{ref="8" data="citationList"}
}
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hcan->Instance == CAN1)
{
/* 1. 使能时钟 */
__HAL_RCC_CAN1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/* 2. 配置GPIO复用功能 */
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
}
void CAN_Receive_Init(CAN_HandleTypeDef *hcan)
{
// 启用FIFO0接收中断
HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
HAL_CAN_Start(hcan);
}
// 发送数据入队
uint8_t CAN_EnqueueTx(uint32_t ext_id, uint8_t len)
{
//u16 i = 0;
if(tx_buf.size >= CAN_BUFFER_SIZE) return 0;
tx_buf.id[tx_buf.in] = ext_id;
tx_buf.dlc[tx_buf.in] = len;
memcpy(tx_buf.data[tx_buf.in], Sdata, len);
//for( i=0; i<len; i++ )
//{ tx_buf.data[tx_buf.in][i] = Sdata[i]; }
tx_buf.in = (tx_buf.in + 1) % CAN_BUFFER_SIZE;
tx_buf.size++;
if( Printf_Can_Send_In )
{
RTC_PrintfData();
rt_kprintf("Can Send in %3d out %3d size %3d" ,tx_buf.in,tx_buf.out,tx_buf.size);/*
rt_kprintf("TX in %3d out %3d size %3d RX in %3d out %3d size %3d\n"
,tx_buf.in,tx_buf.out,tx_buf.size
,rx_buf.in,rx_buf.out,rx_buf.size);*/
}
return 1;
}
// 发送状态机处理
void CAN_TxSend( void )
{
static uint8_t retry_count = 0;
static uint8_t retry_reg = 0;
u16 i = 0;
if( tx_buf.size > 0)
{
Txheader.ExtId = tx_buf.id[tx_buf.out];
Txheader.DLC = tx_buf.dlc[tx_buf.out];
Txheader.IDE = CAN_ID_EXT;
Txheader.RTR = CAN_RTR_DATA;
Txheader.TransmitGlobalTime = DISABLE;
//if( HAL_CAN_AddTxMessage(hcan1, &Txheader, tx_buf.data[tx_buf.out], NULL) == HAL_OK)
retry_reg = HAL_CAN_AddTxMessage(&hcan1, &Txheader, tx_buf.data[tx_buf.out], NULL);
if( retry_reg == HAL_OK)
{
//LED_CAN |= 1;
if( Printf_Can_Send_Out )
{
RTC_PrintfData();
rt_kprintf("Can Send out %3d out %3d size %3d" ,tx_buf.in,tx_buf.out,tx_buf.size);
}
tx_buf.out = (tx_buf.out + 1) % CAN_BUFFER_SIZE;
tx_buf.size--;
retry_count = 0;
}
else if( Printf_Can_Send_Out )
{
RTC_PrintfData();
if( retry_reg == HAL_ERROR)
{ rt_kprintf("CAN TX HAL_ERROR " ); }
else if( retry_reg == HAL_BUSY)
{ rt_kprintf("CAN TX HAL_BUSY " ); }
else if( retry_reg == HAL_TIMEOUT)
{ rt_kprintf("CAN TX HAL_TIMEOUT " ); }
}
/*
else
{
if(++retry_count > 3)
{
tx_buf.out = (tx_buf.out + 1) % CAN_BUFFER_SIZE;
tx_buf.size--;
retry_count = 0;
}
}*/
}
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
CAN_RxHeaderTypeDef rx_header;
uint8_t rx_data[8];
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, &rx_data) == HAL_OK)
{
if(rx_buf.size < CAN_BUFFER_SIZE)
{
LED_CAN |= 2;
rx_buf.id[rx_buf.in] = rx_header.ExtId;
rx_buf.dlc[rx_buf.in] = rx_header.DLC;
memcpy(rx_buf.data[rx_buf.in], rx_data, rx_header.DLC);
if( Printf_Can_Rece_In )
{
RTC_PrintfData();
rt_kprintf("Can Rece in %3d out %3d size %3d" ,rx_buf.in,rx_buf.out,rx_buf.size);
}
rx_buf.in = (rx_buf.in + 1) % CAN_BUFFER_SIZE;
rx_buf.size++;
}
}
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO1, &rx_header, &rx_data) == HAL_OK)
{
if(rx_buf.size < CAN_BUFFER_SIZE)
{
LED_CAN |= 2;
rx_buf.id[rx_buf.in] = rx_header.ExtId;
rx_buf.dlc[rx_buf.in] = rx_header.DLC;
memcpy(rx_buf.data[rx_buf.in], rx_data, rx_header.DLC);
if( Printf_Can_Rece_In )
{
RTC_PrintfData();
rt_kprintf("Can Rece in %3d out %3d size %3d" ,rx_buf.in,rx_buf.out,rx_buf.size);
}
rx_buf.in = (rx_buf.in + 1) % CAN_BUFFER_SIZE;
rx_buf.size++;
}
}
}
void CAN1_RX0_IRQHandler(void)
{
rt_interrupt_enter();
HAL_CAN_IRQHandler(&hcan1);
rt_interrupt_leave();
}
void can_thread_entry(void *args)
{
//u16 inc=0;
while(1)
{
rt_thread_mdelay(1);
CAN_TxSend();
User_Can_Rece();
User_Can_Send_Rece();
//inc++;
//if( inc >= 22 ) { inc = 0; CAN_EnqueueTx( 123, 8 ); }
}
}
u8 MX_Can_init(void)
{
if( FSD_Can )
{
CAN_Init( CAN_SPEED_500K );
CAN_Receive_Init( &hcan1 );
//HAL_CAN_Start( &hcan1 ); // 必须启动CAN控制器
Printf_Can_Send_In = 1; //
Printf_Can_Send_Out = 1; //
Printf_Can_Send_Hex = 1; //
Printf_Can_Rece_In = 1; //
Printf_Can_Rece_Out = 1; //
Printf_Can_Rece_Hex = 1; //
tx_buf.in = 0;
tx_buf.out = 0;
tx_buf.size = 0;
rx_buf.in = 0;
rx_buf.out = 0;
rx_buf.size = 0;
// 创建 serial 线程
rt_thread_t thread = rt_thread_create("Can", can_thread_entry, RT_NULL, 1024, 16, 20);
// 创建成功则启动线程
if (thread != RT_NULL)
{
rt_thread_startup(thread);
}
}
return 0;
}
INIT_DEVICE_EXPORT( MX_Can_init );
void can_printf(void)
{
RTC_PrintfData();
rt_kprintf("TX in %3d out %3d size %3d RX in %3d out %3d size %3d"
,tx_buf.in,tx_buf.out,tx_buf.size
,rx_buf.in,rx_buf.out,rx_buf.size);
}
麻烦各位帮我析一下什么原因
|
|