STM32F4+海泰电机调试实现控制

博主在项目中接触到海泰电机作为控制器件,是博主第一次接触RS485通信的电机,写下博客供跟博主一样的小白进行学习,拿到电机的第一时间,首先可以发现通信有RS485和CAN通信两种

基于项目需要我们采取RS485通信,但是我们使用的32单片机没有485通信口,所以采取了串口转485的方式进行电机的控制,PS:此方法最开始我心里也悬,问官方官方也说不建议,还好最后调试成功了。

模块不多做赘述,在某宝上面搜索就有,具体接法记住,与平常的串口通信不同,是需要直连的,RS485模块的458A接电机的485A,B接B,串口那边,RX接RX,TX接TX,这样进行控制,在代码中我们使用了一个串口进行通信一个进行串口打印,所以是双串口使能,分别是串口1和串口4,代码如下:

/**
 ****************************************************************************************************
 * @file        usart.c
 * @author      ÕýµãÔ­×ÓÍŶÓ(ALIENTEK)
 * @version     V1.0
 * @date        2021-10-14
 * @brief       ´®¿Ú³õʼ»¯´úÂë(Ò»°ãÊÇ´®¿Ú1)£¬Ö§³Öprintf
 * @license     Copyright (c) 2020-2032, ¹ãÖÝÊÐÐÇÒíµç×ӿƼ¼ÓÐÏÞ¹«Ë¾
 ****************************************************************************************************
 * @attention
 *
 * ʵÑéÆ½Ì¨:ÕýµãÔ­×Ó Ì½Ë÷Õß F407¿ª·¢°å
 * ÔÚÏßÊÓÆµ:www.yuanzige.com
 * ¼¼ÊõÂÛ̳:www.openedv.com
 * ¹«Ë¾ÍøÖ·:www.alientek.com
 * ¹ºÂòµØÖ·:openedv.taobao.com
 *
 * ÐÞ¸Ä˵Ã÷
 * V1.0 20211014
 * µÚÒ»´Î·¢²¼
 *
 ****************************************************************************************************
 */

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"


/* Èç¹ûʹÓÃos,Ôò°üÀ¨ÏÂÃæµÄÍ·Îļþ¼´¿É */
#if SYS_SUPPORT_OS
#include "os.h"                               /* os ʹÓà */
#endif

/******************************************************************************************/
/* ¼ÓÈëÒÔÏ´úÂë, Ö§³Öprintfº¯Êý, ¶ø²»ÐèҪѡÔñuse MicroLIB */

#if 1
#if (__ARMCC_VERSION >= 6010050)                    /* ʹÓÃAC6±àÒëÆ÷ʱ */
__asm(".global __use_no_semihosting\n\t");          /* ÉùÃ÷²»Ê¹ÓðëÖ÷»úģʽ */
__asm(".global __ARM_use_no_argv \n\t");            /* AC6ÏÂÐèÒªÉùÃ÷mainº¯ÊýΪÎÞ²ÎÊý¸ñʽ£¬·ñÔò²¿·ÖÀý³Ì¿ÉÄܳöÏÖ°ëÖ÷»úģʽ */

#else
/* ʹÓÃAC5±àÒëÆ÷ʱ, ÒªÔÚÕâÀﶨÒå__FILE ºÍ ²»Ê¹ÓðëÖ÷»úģʽ */
#pragma import(__use_no_semihosting)

struct __FILE
{
    int handle;
    /* Whatever you require here. If the only file you are using is */
    /* standard output using printf() for debugging, no file handling */
    /* is required. */
};

#endif

/* ²»Ê¹ÓðëÖ÷»úģʽ£¬ÖÁÉÙÐèÒªÖØ¶¨Òå_ttywrch\_sys_exit\_sys_command_stringº¯Êý,ÒÔͬʱ¼æÈÝAC6ºÍAC5ģʽ */
int _ttywrch(int ch)
{
    ch = ch;
    return ch;
}

/* ¶¨Òå_sys_exit()ÒÔ±ÜÃâʹÓðëÖ÷»úģʽ */
void _sys_exit(int x)
{
    x = x;
}

char *_sys_command_string(char *cmd, int len)
{
    return NULL;
}

/* FILE ÔÚ stdio.hÀïÃæ¶¨Òå. */
FILE __stdout;

/* ÖØ¶¨Òåfputcº¯Êý, printfº¯Êý×îÖÕ»áͨ¹ýµ÷ÓÃfputcÊä³ö×Ö·û´®µ½´®¿Ú */
int fputc(int ch, FILE *f)
{
    while ((UART4->SR & 0X40) == 0);               /* µÈ´ýÉÏÒ»¸ö×Ö·û·¢ËÍÍê³É */

    UART4->DR = (uint8_t)ch;                       /* ½«Òª·¢Ë͵Ä×Ö·û ch дÈëµ½DR¼Ä´æÆ÷ */
    return ch;
}
#endif
/***********************************************END*******************************************/
    
#if USART_EN_RX                                     /* Èç¹ûʹÄÜÁ˽ÓÊÕ */

/* ½ÓÊÕ»º³å, ×î´óUSART_REC_LEN¸ö×Ö½Ú. */
uint8_t g_usart_rx_buf[USART_REC_LEN];

/*  ½ÓÊÕ״̬
 *  bit15£¬      ½ÓÊÕÍê³É±êÖ¾
 *  bit14£¬      ½ÓÊÕµ½0x0d
 *  bit13~0£¬    ½ÓÊÕµ½µÄÓÐЧ×Ö½ÚÊýÄ¿
*/
uint16_t g_usart_rx_sta = 0;

uint8_t g_rx_buffer[RXBUFFERSIZE];                  /* HAL¿âʹÓõĴ®¿Ú½ÓÊÕ»º³å */

UART_HandleTypeDef g_uart4_handle;                  /* UART¾ä±ú */


/**
 * @brief       ´®¿ÚX³õʼ»¯º¯Êý
 * @param       baudrate: ²¨ÌØÂÊ, ¸ù¾Ý×Ô¼ºÐèÒªÉèÖò¨ÌØÂÊÖµ
 * @note        ×¢Òâ: ±ØÐëÉèÖÃÕýÈ·µÄʱÖÓÔ´, ·ñÔò´®¿Ú²¨ÌØÂʾͻáÉèÖÃÒì³£.
 *              ÕâÀïµÄUSARTµÄʱÖÓÔ´ÔÚsys_stm32_clock_init()º¯ÊýÖÐÒѾ­ÉèÖùýÁË.
 * @retval      ÎÞ
 */
void usart_init(uint32_t baudrate)
{
    g_uart4_handle.Instance = USART_UX;                         /* UART4 */
    g_uart4_handle.Init.BaudRate = baudrate;                    /* ²¨ÌØÂÊ */
    g_uart4_handle.Init.WordLength = UART_WORDLENGTH_8B;        /* ×Ö³¤Îª8λÊý¾Ý¸ñʽ */
    g_uart4_handle.Init.StopBits = UART_STOPBITS_1;             /* Ò»¸öֹͣλ */
    g_uart4_handle.Init.Parity = UART_PARITY_NONE;              /* ÎÞÆæÅ¼Ð£Ñéλ */
    g_uart4_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;        /* ÎÞÓ²¼þÁ÷¿Ø */
    g_uart4_handle.Init.Mode = UART_MODE_TX_RX;                 /* ÊÕ·¢Ä£Ê½ */
    HAL_UART_Init(&g_uart4_handle);                             /* HAL_UART_Init()»áʹÄÜUART1 */
    
    /* ¸Ãº¯Êý»á¿ªÆô½ÓÊÕÖжϣº±ê־λUART_IT_RXNE£¬²¢ÇÒÉèÖýÓÊÕ»º³åÒÔ¼°½ÓÊÕ»º³å½ÓÊÕ×î´óÊý¾ÝÁ¿ */
    HAL_UART_Receive_IT(&g_uart4_handle, (uint8_t *)g_rx_buffer, RXBUFFERSIZE);
}

/**
 * @brief       UARTµ×²ã³õʼ»¯º¯Êý
 * @param       huart: UART¾ä±úÀàÐÍÖ¸Õë
 * @note        ´Ëº¯Êý»á±»HAL_UART_Init()µ÷ÓÃ
 *              Íê³ÉʱÖÓʹÄÜ£¬Òý½ÅÅäÖã¬ÖжÏÅäÖÃ
 * @retval      ÎÞ
 */
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    GPIO_InitTypeDef gpio_init_struct;
    if(huart->Instance == USART_UX)                             /* Èç¹ûÊÇ´®¿Ú1£¬½øÐд®¿Ú1 MSP³õʼ»¯ */
    {
        USART_UX_CLK_ENABLE();                                  /* UART4 ʱÖÓʹÄÜ */
        USART_TX_GPIO_CLK_ENABLE();                             /* ·¢ËÍÒý½ÅʱÖÓʹÄÜ */
        USART_RX_GPIO_CLK_ENABLE();                             /* ½ÓÊÕÒý½ÅʱÖÓʹÄÜ */

        gpio_init_struct.Pin = USART_TX_GPIO_PIN;               /* TXÒý½Å */
        gpio_init_struct.Mode = GPIO_MODE_AF_PP;                /* ¸´ÓÃÍÆÍìÊä³ö */
        gpio_init_struct.Pull = GPIO_PULLUP;                    /* ÉÏÀ­ */
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* ¸ßËÙ */
        gpio_init_struct.Alternate = USART_TX_GPIO_AF;          /* ¸´ÓÃΪUART4 */
        HAL_GPIO_Init(USART_TX_GPIO_PORT, &gpio_init_struct);   /* ³õʼ»¯·¢ËÍÒý½Å */

        gpio_init_struct.Pin = USART_RX_GPIO_PIN;               /* RXÒý½Å */
        gpio_init_struct.Alternate = USART_RX_GPIO_AF;          /* ¸´ÓÃΪUART4 */
        HAL_GPIO_Init(USART_RX_GPIO_PORT, &gpio_init_struct);   /* ³õʼ»¯½ÓÊÕÒý½Å */

#if USART_EN_RX
        HAL_NVIC_EnableIRQ(USART_UX_IRQn);                      /* ʹÄÜUART4ÖжÏͨµÀ */
        HAL_NVIC_SetPriority(USART_UX_IRQn, 3, 3);              /* ÇÀÕ¼ÓÅÏȼ¶3£¬×ÓÓÅÏȼ¶3 */
#endif
    }
}

/**
 * @brief       Rx´«Ê仨µ÷º¯Êý
 * @param       huart: UART¾ä±úÀàÐÍÖ¸Õë
 * @retval      ÎÞ
 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART_UX)             /* Èç¹ûÊÇ´®¿Ú1 */
    {
        if((g_usart_rx_sta & 0x8000) == 0)      /* ½ÓÊÕδÍê³É */
        {
            if(g_usart_rx_sta & 0x4000)         /* ½ÓÊÕµ½ÁË0x0d */
            {
                if(g_rx_buffer[0] != 0x0a)
                {
                    g_usart_rx_sta = 0;         /* ½ÓÊÕ´íÎó,ÖØÐ¿ªÊ¼ */
                }
                else
                {
                    g_usart_rx_sta |= 0x8000;   /* ½ÓÊÕÍê³ÉÁË */
                }
            }
            else                                /* »¹Ã»ÊÕµ½0X0D */
            {
                if(g_rx_buffer[0] == 0x0d)
                {
                    g_usart_rx_sta |= 0x4000;
                }
                else
                {
                    g_usart_rx_buf[g_usart_rx_sta & 0X3FFF] = g_rx_buffer[0] ;
                    g_usart_rx_sta++;
                    if(g_usart_rx_sta > (USART_REC_LEN - 1))
                    {
                        g_usart_rx_sta = 0;     /* ½ÓÊÕÊý¾Ý´íÎó,ÖØÐ¿ªÊ¼½ÓÊÕ */
                    }
                }
            }
        }
    }
}

/**
 * @brief       ´®¿Ú1ÖжϷþÎñº¯Êý
 * @param       ÎÞ
 * @retval      ÎÞ
 */
void USART_UX_IRQHandler(void)
{
    uint32_t timeout = 0;
    uint32_t maxDelay = 0x1FFFF;
    
#if SYS_SUPPORT_OS                              /* ʹÓÃOS */
    OSIntEnter();    
#endif

    HAL_UART_IRQHandler(&g_uart4_handle);       /* µ÷ÓÃHAL¿âÖжϴ¦Àí¹«Óú¯Êý */

    timeout = 0;
    while (HAL_UART_GetState(&g_uart4_handle) != HAL_UART_STATE_READY) /* µÈ´ý¾ÍÐ÷ */
    {
        timeout++;                              /* ³¬Ê±´¦Àí */
        if(timeout > maxDelay)
        {
            break;
        }
    }
     
    timeout=0;
    
    /* Ò»´Î´¦ÀíÍê³ÉÖ®ºó£¬ÖØÐ¿ªÆôÖжϲ¢ÉèÖÃRxXferCountΪ1 */
    while (HAL_UART_Receive_IT(&g_uart4_handle, (uint8_t *)g_rx_buffer, RXBUFFERSIZE) != HAL_OK)
    {
        timeout++;                              /* ³¬Ê±´¦Àí */
        if (timeout > maxDelay)
        {
            break;
        }
    }

#if SYS_SUPPORT_OS                              /* ʹÓÃOS */
    OSIntExit();
#endif

}

#endif

博主认为,最麻烦的是控制命令的编写,虽说有文档,但是需要十进制到十六进制的转换,并且最后进行CRC冗余算法才能得出最后两位,在命令不多的时候我支持自己算出来写出命令,推荐一个计算网站: CRC在线计算

在算出命令值后再进行串口命令的发送,即可实现控制:             HAL_UART_Transmit(&huart1,lvjing1,sizeof(lvjing1),0xffff);

最后实现的功能是串口4接串口助手,串口1接电机,串口4发送0,1,2,3分别实现设置原点,前进,返回原点,调速等操作,博主的资源链接如下: https://download.csdn.net/download/weixin_43955009/88374177


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

电子大王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值