1:下载软件

点击 这里立即下载,共454M。

2:通过STM32CubeMX配置USART1,CAN1

1:创建工程

创建文件夹存放工程

STM32CUBEMX怎么配置SRAM_arm


STM32CUBEMX怎么配置SRAM_单片机_02


添加工程名称及路径:

STM32CUBEMX怎么配置SRAM_单片机_03

为每个驱动单独创建.c和.h文件。

STM32CUBEMX怎么配置SRAM_单片机_04

2:配置时钟

STM32CUBEMX怎么配置SRAM_#include_05


STM32CUBEMX怎么配置SRAM_#include_06

3:配置串口驱动

STM32CUBEMX怎么配置SRAM_arm_07

4:配置CAN驱动

STM32CUBEMX怎么配置SRAM_单片机_08


配置波特率为500K

STM32CUBEMX怎么配置SRAM_arm_09

5:选择调试引脚

STM32CUBEMX怎么配置SRAM_arm_10

6:生成代码

STM32CUBEMX怎么配置SRAM_单片机_11

7:调试

STM32CUBEMX怎么配置SRAM_arm_12


发现生成的代码无法调试,注释掉这一行。

STM32CUBEMX怎么配置SRAM_arm_13


STM32CUBEMX怎么配置SRAM_arm_14


编辑并删除掉下面这一行:

Message(2,"Not a genuine ST Drive! Abort connection");

STM32CUBEMX怎么配置SRAM_#include_15

3:代码编写

1:串口重定向到printf

在文件usart.c中添加

STM32CUBEMX怎么配置SRAM_arm_16

#include "stdio.h"
 
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
    HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
    return ch;
}

在文件usart.h中添加

STM32CUBEMX怎么配置SRAM_#include_17

#include "stdio.h"

STM32CUBEMX怎么配置SRAM_arm_18

2:对CAN配置

在can.c中/* USER CODE BEGIN 0 */下添加代码:

#include "usart.h"
extern CAN_TxHeaderTypeDef Can_Tx;
extern uint8_t Txdata[8];
void CAN_User_Init(CAN_HandleTypeDef* hcan )   //用户初始化函数
{
  CAN_FilterTypeDef  sFilterConfig;
  HAL_StatusTypeDef  HAL_Status;
  sFilterConfig.FilterActivation = ENABLE;  	//激活过滤器
  sFilterConfig.FilterBank = 1;                       //过滤器1
  sFilterConfig.FilterMode =  CAN_FILTERMODE_IDMASK;  //设为掩码模式
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;    //设为32位
  sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;    //接收到的报文放入到FIFO0中
  sFilterConfig.FilterIdHigh = 0;   //基本ID放入到STID中
  sFilterConfig.FilterIdLow  = 0;
  sFilterConfig.FilterMaskIdHigh =0;
  sFilterConfig.FilterMaskIdLow  =0;
  sFilterConfig.SlaveStartFilterBank  = 0;
 
  HAL_Status=HAL_CAN_ConfigFilter(hcan, &sFilterConfig);
  HAL_Status=HAL_CAN_Start(hcan);  //开启CAN
 
  if(HAL_Status!=HAL_OK){
//	printf("开启CAN失败\r\n");
 }
 HAL_Status=HAL_CAN_ActivateNotification(hcan,CAN_IT_RX_FIFO0_MSG_PENDING);
 if(HAL_Status!=HAL_OK){
	//printf("开启挂起中段允许失败\r\n");
  }
}
 
/*
 发送命令函数
 StdId 			标准帧ID
 ExtId 			扩展帧ID  当标志位 IDE为CAN_ID_STD时 扩展帧无效
 IDE 			扩展帧标志位  CAN_ID_STD为标准ID CAN_ID_EXT为使用扩展ID
 RTR  			0(CAN_RTR_DATA)为数据帧 1(CAN_RTR_REMOTE)为远程帧
 DLC  			数据长度
*/
void sendOrder(uint32_t StdId,uint32_t ExtId,uint8_t IDE,uint8_t  RTR, uint8_t DLC)
{
	uint32_t pTxMailbox = 0;
 
	Can_Tx.StdId = StdId;//标准ID
	Can_Tx.ExtId = ExtId;//扩展ID
	Can_Tx.IDE = IDE;//CAN_ID_STD为标准ID CAN_ID_EXT为使用扩展ID
	Can_Tx.RTR = RTR;					//0(CAN_RTR_DATA)为数据帧 1(CAN_RTR_REMOTE)为远程帧
	Can_Tx.DLC = DLC;					//数据长度
	printf("TX ID:0x%X\r\n",ExtId);
	printf("TX DATA:%02X%02X%02X%02X%02X%02X%02X%02X\r\n",Txdata[0],Txdata[1],Txdata[2],Txdata[3],Txdata[4],Txdata[5],Txdata[6],Txdata[7]);
	HAL_CAN_AddTxMessage(&hcan,&Can_Tx,Txdata,&pTxMailbox);
 
}
void sendmessage(uint32_t StdId,uint32_t ExtId,uint8_t IDE,uint8_t  RTR, uint8_t DLC,float send_data)
{
	uint32_t pTxMailbox = 0;
	Can_Tx.StdId = StdId;//标准ID
	Can_Tx.ExtId = ExtId;//扩展ID
	Can_Tx.IDE = IDE;//CAN_ID_STD为标准ID CAN_ID_EXT为使用扩展ID
	Can_Tx.RTR = RTR;					//0(CAN_RTR_DATA)为数据帧 1(CAN_RTR_REMOTE)为远程帧
	Can_Tx.DLC = DLC;					//数据长度
	//将浮点数转化成4个字节存在tdata[4]----tdata[7]中
	send_data=send_data*100;
		Txdata[4] = (int)send_data&0x00ff;
		Txdata[3] = (int)send_data>>8;
		Txdata[1] = 0x01;
		printf("TX ID:0x%X\r\n",Can_Tx.ExtId);
	printf("TX DATA:%02X%02X%02X%02X%02X%02X%02X%02X\r\n",Txdata[0],Txdata[1],Txdata[2],Txdata[3],Txdata[4],Txdata[5],Txdata[6],Txdata[7]);
	HAL_CAN_AddTxMessage(&hcan,&Can_Tx,Txdata,&pTxMailbox);
}

在can.h的/* USER CODE BEGIN Prototypes */下添加:

void CAN_User_Init(CAN_HandleTypeDef* hcan );
void sendmessage(uint32_t StdId,uint32_t ExtId,uint8_t IDE,uint8_t  RTR, uint8_t DLC,float send_data);
void sendOrder(uint32_t StdId,uint32_t ExtId,uint8_t IDE,uint8_t  RTR, uint8_t DLC);

CAN中断中添加代码:
stm32f1xx_it.c文件/* USER CODE BEGIN Includes */下添加:

#include "can.h"
#include "gpio.h"
#include "usart.h"

/* USER CODE BEGIN EV */下添加:

extern CAN_RxHeaderTypeDef Can_Rx;
extern uint8_t Rxdata[8] ;
extern float rxdata;
uint8_t can_rx_finish_flag;//接收完成标志位

/* USER CODE BEGIN 1 */下添加

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef* hcan1)
{
	printf("***********************************************\r\n");
	HAL_CAN_GetRxMessage(&hcan,CAN_RX_FIFO0,&Can_Rx,Rxdata);
	 can_rx_finish_flag=1;
     printf("RX ID:0x%X\r\n",Can_Rx.ExtId);
	 printf("RX DATA: %02X%02X%02X%02X%02X%02X%02X%02X\r\n",Rxdata[0],Rxdata[1],Rxdata[2],Rxdata[3],Rxdata[4],Rxdata[5],Rxdata[6],Rxdata[7]);
 
}

main.c中
/* USER CODE BEGIN 0 */添加:

CAN_TxHeaderTypeDef Can_Tx;
CAN_RxHeaderTypeDef Can_Rx;
uint8_t Rxdata[8];//CAN接收缓冲区
uint8_t Txdata[8] = {0};//CAN发送缓冲区
extern uint8_t can_rx_finish_flag;//接收完成标志位

/* USER CODE BEGIN 2 */下添加

CAN_User_Init(&hcan);

/* USER CODE BEGIN 3 */下添加

if(can_rx_finish_flag==1)//接收完成
{
	  	sendmessage(0x123,0x14550151,CAN_ID_EXT,0,8,26.2);
	  	can_rx_finish_flag=0;
}

或者

Txdata[0]=0x01;
    Txdata[1]=0x01;
    Txdata[2]=0x04;
	sendOrder(0x123,0x13550151,CAN_ID_EXT,0,3);
    HAL_Delay(2000);

进行测试。