STM32F103RCT6中CAN重映射调不通
板子上设计成了PB8和PB9为CAN的IO口,查了资料说是可以用STM32的端口重映射来解决这个问题。再查看相关资料,在CAN初始化上加了__HAL_AFIO_REMAP_CAN1_2();,怎么还是不通呢,是不是要使能重映射时钟,在库文件里没有找到对应的时钟。求知道的兄弟们指点小弟一番,谢谢!!本帖最后由 wenyangzeng 于 2018-8-17 10:34 编辑
使用CubeMX配置并重映像CAN到PB8,PB9后,CubeMX就自动为你配置GPIOB和CAN重映像,在stm32f1xx_hal_msp.c中void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hcan->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspInit 0 */
/* USER CODE END CAN1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_CAN1_CLK_ENABLE();
/**CAN GPIO Configuration
PB8 ------> CAN_RX
PB9 ------> CAN_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
__HAL_AFIO_REMAP_CAN1_2();
/* USER CODE BEGIN CAN1_MspInit 1 */
/* USER CODE END CAN1_MspInit 1 */
}
}
wenyangzeng 发表于 2018-8-17 10:32
使用CubeMX配置并重映像CAN到PB8,PB9后,CubeMX就自动为你配置GPIOB和CAN重映像,在stm32f1xx_hal_msp.c中
...
__HAL_RCC_CAN1_CLK_ENABLE();//使能CAN时钟
__HAL_RCC_GPIOB_CLK_ENABLE();//使能IO口时钟
memset(Can.data, 0, 8);//初始化数值
Can.data = 1;
Can.Stdid = 0x0742;
Can.Rtr = CAN_RTR_DATA;
Can.Ide = CAN_ID_STD;//标准帧
Can.Dlc = 8;
/**
*@ PB9 ------> CAN_TX
*@ PB8 ------> CAN_RX
*@ GPIO配置
*/
GPIO_InitStructe.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructe.Pin = GPIO_PIN_9;
GPIO_InitStructe.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStructe);
GPIO_InitStructe.Mode = GPIO_MODE_INPUT;
GPIO_InitStructe.Pin = GPIO_PIN_8;
GPIO_InitStructe.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStructe);
__HAL_AFIO_REMAP_CAN1_2();//重印射
我也有这些代码啊,怎么还是不行。是不是哪个.h文件里的哪个define需要改 从代码上看初始化了IO口,应该是没问题。看一下CAN初始化的过程,是否有问题。 CAN_Handler.Instance = CAN1;
CAN_Handler.Init.Prescaler = 8;
CAN_Handler.Init.Mode = CAN_MODE_NORMAL;
CAN_Handler.Init.SJW = CAN_SJW_1TQ;
CAN_Handler.Init.BS1 = CAN_BS1_16TQ;
CAN_Handler.Init.BS2 = CAN_BS2_1TQ;
CAN_Handler.Init.TTCM = DISABLE;//非时间触发通信模式
CAN_Handler.Init.ABOM = DISABLE;//软件自动离线管理
CAN_Handler.Init.AWUM = DISABLE;//睡眠模式通过软件唤醒
CAN_Handler.Init.NART = ENABLE;//禁止报文自动传送
CAN_Handler.Init.RFLM = DISABLE;//报文部锁定,新的覆盖旧的
CAN_Handler.Init.TXFP = DISABLE;//优先级由报文标识符决定
CAN_Handler.pTxMsg = &TxMessage;
CAN_Handler.pRxMsg = &RxMessage;
if(HAL_CAN_Init(&CAN_Handler) != HAL_OK)
{
Error_Handler();
}
/**
*@ 过滤组设置
*/
CAN_FilterConfStructe.FilterIdHigh = FilterIDH;
CAN_FilterConfStructe.FilterIdLow = FilterIDL;
CAN_FilterConfStructe.FilterMaskIdHigh = FilterMaskIDH;
CAN_FilterConfStructe.FilterMaskIdLow = FilterMaskIDL;
CAN_FilterConfStructe.FilterFIFOAssignment = FilterFIFOA;
CAN_FilterConfStructe.FilterNumber = FilterNum;
CAN_FilterConfStructe.FilterMode = Filtermode;
CAN_FilterConfStructe.FilterScale = Filterscale;
CAN_FilterConfStructe.FilterActivation = FilterAct;
CAN_FilterConfStructe.BankNumber = BankNum;
if(HAL_CAN_ConfigFilter(&CAN_Handler, &CAN_FilterConfStructe) != HAL_OK)
{
Error_Handler();
}
void Can_Send(uint8_t *Buff, uint32_t Stdid)
{
uint8_t i = 0;
CAN_Handler.pTxMsg->StdId = Stdid;//标准标识符
CAN_Handler.pTxMsg->RTR = CAN_RTR_DATA;//数据帧
CAN_Handler.pTxMsg->IDE = CAN_ID_STD;//使用标准帧
CAN_Handler.pTxMsg->DLC = 8;//数据长度
for(i = 0; i < 8; i ++)
{
CAN_Handler.pTxMsg->Data = Buff;
}
if(HAL_CAN_Transmit(&CAN_Handler, 0xff) != HAL_OK)//超时
{
// Error_Handler();
}
}
大神们能帮我看下吗?上面一段是初始化,下面的函数是CAN发送函数,实在找不出问题出在哪? 楼主,用STM32CubeMX生成一个工程测试一下。我这里用的是PD0和PD1。 根据楼上的讨论和代码看,CAN重映射应该没有问题。
但是还是CAN不通,那么你外部是怎么接线的?STM32输出的CAN,经过CAN收发器后,出去CAN_H、CAN_L信号;CAN_H、CAN_L与外部CAN设备连接,如果只是两个设备连接的话,需要根据实际情况,是否加120欧姆终端匹配电阻。正确的是在CAN的首尾两个端点的CAN_H、CAN_L之间各加一个120欧姆电阻,但有时加一个或者不加也可以工作。 不一定是重映射的问题,也有可能是和其它外设功能哪里冲突了 你初始化过了吗?你有接终端吗? 安 发表于 2018-8-17 10:58
楼主,用STM32CubeMX生成一个工程测试一下。我这里用的是PD0和PD1。
用CUbe试过还是不行