1:下载软件
点击 这里立即下载,共454M。
2:通过STM32CubeMX配置USART1,CAN1
1:创建工程
创建文件夹存放工程
添加工程名称及路径:
为每个驱动单独创建.c和.h文件。
2:配置时钟
3:配置串口驱动
4:配置CAN驱动
配置波特率为500K
5:选择调试引脚
6:生成代码
7:调试
发现生成的代码无法调试,注释掉这一行。
编辑并删除掉下面这一行:
Message(2,"Not a genuine ST Drive! Abort connection");
3:代码编写
1:串口重定向到printf
在文件usart.c中添加
#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中添加
#include "stdio.h"
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);
进行测试。