| 
 
| #申请原创# #有奖活动# 我年前发布的一个视频帖子里向大家展示了APM32M3514通过板载通讯接口反馈反馈数据的功能,这个帖子就将详细的教程展示出来。
 一、硬件浅析
 1、电源部分
 电源部分比较简单,由于APM32M3514芯片自身具有3.3V LDO,因此整板只有一个二次电源电路,采用经典的LM5164芯片,降压到12V,为单片机、驱动电路等供电,这个应该是板子上为数不多的非国产芯片之一。而板子上的3.3V供电则由APM32M3514芯片提供,用于LED指示灯、霍尔传感器接口等电路
 
 
  2、功率部分
 功率部分采用典型的三个半桥拓扑架构,上下桥均采用Nmos驱动,采用的是无锡新洁能NCEP0178AK,这个片子性能还可以 VDS 可达100V,ID可以到78A,在咱们这个标称100W的DEMO里,降额也是足足的(这意思是这个板子还有很大空间,在自己实力可控的条件下,可以换更小的采样电阻,调下程序比例系数,输出功率可以做的更大)。
 
  3、通讯部分
 通讯部分设计就比较有意思了,板子虽然有基于ch340的串口通讯电路,但是这个电路的TTL电平引脚竟然和外部晶振共用,而且官方例程用的就是外部晶振,所以在这种情况下这个电路就成了摆设。手册给的外部晶振电路和通讯电路如下:
 
  
  如果我们想用该串口进行通讯,只需要将R37和R38上的短接0欧电阻焊下,焊接到R44和R45位置上即可,其在板子上位置如下图红框所示
 
 更改完成后,通过软件进行相应的配置就可以实现串口通讯了。
 二、软件调整
 官方文档对软件电机控制核心代码的描述还是比较详细的,而且也有一定的注释,所以我这里就不在详细分析官方的电机控制核心代码
 主要对该开发板改串口通讯部分的代码进行详细说明。
 1、工作时钟源
 前面已经提到,官方的例程采用外部晶振作为时钟源,想使用板载串口就需要改成内部时钟源,通过查看芯片数据手册——时钟树部分,可以知道内部晶振也为8MHz,但和外部晶振不同的是,它的预分频系数是固定的2,而外部晶振的预分频系数是可配置的,结合时钟锁相环的最大倍频系数,可知采用内部晶振后,单片机最大的工作频率只能到64MHz,下面也将按照64MHz进行配置。
 
  2、代码调整
 在官方给出的例程中,时钟源配置所在文件为system_apm32m35xx.c,其具体路径如下图高亮显示的文件可以找到
 
  打开该文件后,首先增加基于内部时钟源的64MHz定义,并屏蔽72MHz定义如下图所示
 
  下一步增加时钟变量如下图所示
 
  再下一步增加系统时钟配置函数如下图所示
 
  最后增加基于内部时钟源的64MHz初始化函数如下
 
  接着需要将parameter.h中时钟频率也配置到64000000,具体如下图,至此,时钟配置完毕。
 
  接着修改串口功能,在drv_uart.c文件中,初始化串口1,配置为921600波特率,8N1格式,具体如下
 void Pilot_uart_init(void)
 {
 USART_Config_T USART_InitStructure;
 DMA_Config_T   DMA_InitStructure;
 
 RCM_ConfigUSARTCLK(RCM_USART1CLK_SYSCLK);
 //    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_USART2);
 
 USART_InitStructure.baudRate   = 921600;//1945946;
 USART_InitStructure.mode       = USART_MODE_TX_RX;
 USART_InitStructure.hardwareFlowCtrl = USART_FLOW_CTRL_NONE;
 USART_InitStructure.parity     = USART_PARITY_NONE;
 USART_InitStructure.stopBits   = USART_STOP_BIT_1;
 USART_InitStructure.wordLength = USART_WORD_LEN_8B;
 USART_Config(USART1,&USART_InitStructure);
 USART_DisableOverSampling8(USART1);
 USART_DisableOneBitMethod(USART1);
 USART1->CTRL3 &= (uint32_t)~0x400;
 /** Enable USART */
 USART_Enable(USART1);
 
 }
 在drv_io.c文件中,增加PF1和PF2引脚的配置如下,并在IO初始化函数中增加串口引脚初始化,具体如下
 /*  uart1 io map    */
 void IOinit_uart1(void)
 {
 GPIO_Config_T   GPIO_InitStructure;
 /*  PF0 -> uart1_tx    */
 GPIO_InitStructure.pin      =   GPIO_PIN_0;
 GPIO_InitStructure.speed    =   GPIO_SPEED_50MHz;
 GPIO_InitStructure.mode     =   GPIO_MODE_AF;
 GPIO_InitStructure.pupd     =   GPIO_PUPD_NO;
 GPIO_InitStructure.outtype  = GPIO_OUT_TYPE_PP;
 GPIO_Config(GPIOF, &GPIO_InitStructure);
 GPIO_InitStructure.pin      =   GPIO_PIN_1;
 GPIO_Config(GPIOF, &GPIO_InitStructure);
 GPIO_ConfigPinAF(GPIOF, GPIO_PIN_SOURCE_0, GPIO_AF_PIN1);
 GPIO_ConfigPinAF(GPIOF, GPIO_PIN_SOURCE_1, GPIO_AF_PIN1);
 }
 
 
 /*********************************************************************************************************
 ** Func name:               IO_Init()
 ** Param:
 **
 ** Return:
 ** Description:             IO初始化
 *********************************************************************************************************/
 void IO_Init(void)
 {
 IOInit_LED();
 IOinit_uart1();
 IOinit_ADC();
 Other_Init();  //direction and lock
 }
 
 在main.c中增加如下函数
 int fputc(int ch, FILE* f)
 {
 /* send a byte of data to the serial port */
 USART_TxData(USART1, (uint8_t)ch);
 
 /* wait for the data to be send  */
 while (USART_ReadStatusFlag(USART1, USART_FLAG_TXBE) == RESET);
 
 return (ch);
 }
 
 至此,即可通过printf函数通过板载串口输出想要的打印结果,结合VOFA+软件的相关协议,实现参数实时显示和图表的实时绘制。
 
 | 
 |