以基于STM32F103的FOC源码为例分析;

保存电机参数

采用宏定义开关来决定是否要进行参数校准;

//1 已校准
//0 未校准
#define IS_ALIGN 0

//参数数据结构体
struct ALIGN_DATA
{
    long direction;
    int pole;
    float zero_angle;
} DATA_ALIGN;

//根据宏定义判断是否要更新FLASH中存储的参数
#if IS_ALIGN
    Internal_ReadFlash(ALIGN_ANGLE_ADDR, (uint32_t *)&DATA_ALIGN, 3);//读取内部FLASH中的参数
    sensor_direction = DATA_ALIGN.direction;    //方向
    pole_pairs = DATA_ALIGN.pole;               //极对数
    zero_electric_angle = DATA_ALIGN.zero_angle;//零点角度
#else
    //
    //此处略去参数识别代码
    //
    DATA_ALIGN.direction = sensor_direction;    //方向
    DATA_ALIGN.pole = pole_pairs;               //极对数
    DATA_ALIGN.zero_angle = zero_electric_angle;//零点角度
    Internal_WriteFlash(ALIGN_ANGLE_ADDR, (uint32_t *)&DATA_ALIGN, 3);//将参数写入单片机内部FLASH中

通过UART通信控制电机

/**
 * @brief 简易串口命令接收,需在while循环里重复调用该函数
 * @return 无
 */
void commander_run(void)
{
    if ((USART_RX_STA & 0x8000) != 0)
    {
        switch (USART_RX_BUF[0])
        {
        case 'H':
            printf("Hello World!\r\n");
            break;
        case 'T': // T6.28
            target = atof((const char *)(USART_RX_BUF + 1));
            printf("RX=%.4f\r\n", target);
            break;
        case 'D': // D
            M1_Disable;
            printf("OK!\r\n");
            break;
        case 'E': // E
            M1_Enable;
            printf("OK!\r\n");
            break;
        }
        USART_RX_STA = 0;
    }
}

#define USART_REC_LEN 256
unsigned char USART_RX_BUF[USART_REC_LEN]; //接收缓冲,usart.h中定义长度
//接收状态
// bit15  接收完成标志
// bit14  接收到0x0D
// bit13~0  接收的字节数
unsigned short USART_RX_STA = 0; //接收状态标志
//发送的命令必须以"\r\n"作为结尾,以标志命令的结束
void USART1_IRQHandler(void) //串口1中断程序
{
    unsigned char Res;
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //
    {
        Res = USART_ReceiveData(USART1); //读取接收到的字节
        if ((USART_RX_STA & 0x8000) == 0) //接收未完成
        {
            if (USART_RX_STA & 0x4000) //接收到了0x0d
            {
                if (Res != 0x0a)
                {
                    USART_RX_STA = 0; //接收错误,重新开始
                }
                else
                {
                    USART_RX_STA |= 0x8000;                     //接收完成
                    USART_RX_BUF[USART_RX_STA & 0X3FFF] = '\0'; //最后一个字节放'0’,方便判断
                }
            }
            else //还没收到0x0D
            {
                if (Res == 0x0d)
                {
                    USART_RX_STA |= 0x4000;
                }
                else
                {
                    USART_RX_BUF[USART_RX_STA & 0X3FFF] = Res;
                    USART_RX_STA++;
                    if (USART_RX_STA > (USART_REC_LEN - 1))
                    {
                        USART_RX_STA = 0; //接收错误,重新开始
                    }
                }
            }
        }
    }
}