307 lines
8.4 KiB
C
307 lines
8.4 KiB
C
/*
|
||
2页菜单:1:设定速度、实时速度; 2:母线电压、电流显示。
|
||
KEY1:按键切换速度及电压电流菜单
|
||
KEY2:方向切换按键。电机运行时也可以切换。LED2亮灭表示不同的方向。
|
||
KEY3:电机启停控制,LED3灯亮时,电机处于启动状态; LED3灯来时,电机处于停止状态;
|
||
电位器调速,切换到速度菜单,可以显示当前设定转速。
|
||
Designed by Cache.lee from UET company
|
||
Tel:18129915976
|
||
*/
|
||
#include "main.h"
|
||
#include "motor.h"
|
||
#include "globalv.h"
|
||
#include "init.h"
|
||
#include "pid.h"
|
||
#include "compu.h"
|
||
#include "control.h"
|
||
//#include "OLED_I2C.h"
|
||
|
||
unsigned int Menu=0;
|
||
|
||
|
||
|
||
//UARTx
|
||
#define DEBUG_USARTx CW_UART3
|
||
#define DEBUG_USART_CLK RCC_APB1_PERIPH_UART3
|
||
#define DEBUG_USART_APBClkENx RCC_APBPeriphClk_Enable1
|
||
#define DEBUG_USART_BaudRate 115200
|
||
#define DEBUG_USART_UclkFreq 64000000
|
||
|
||
//UARTx GPIO
|
||
#define DEBUG_USART_GPIO_CLK RCC_AHB_PERIPH_GPIOB
|
||
#define DEBUG_USART_TX_GPIO_PORT CW_GPIOB
|
||
#define DEBUG_USART_TX_GPIO_PIN GPIO_PIN_6
|
||
#define DEBUG_USART_RX_GPIO_PORT CW_GPIOB
|
||
#define DEBUG_USART_RX_GPIO_PIN GPIO_PIN_7
|
||
|
||
//GPIO AF
|
||
#define DEBUG_USART_AFTX PB06_AFx_UART3TXD()
|
||
#define DEBUG_USART_AFRX PB07_AFx_UART3RXD()
|
||
|
||
|
||
|
||
#ifdef __GNUC__
|
||
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
|
||
set to 'Yes') calls __io_putchar() */
|
||
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
|
||
#else
|
||
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
|
||
#endif /* __GNUC__ */
|
||
|
||
|
||
/**
|
||
* @brief 配置UART
|
||
*
|
||
*/
|
||
void UART_Configuration(void)
|
||
{
|
||
USART_InitTypeDef USART_InitStructure;
|
||
|
||
GPIO_InitTypeDef GPIO_InitStructure;
|
||
|
||
//外设时钟使能
|
||
RCC_AHBPeriphClk_Enable(DEBUG_USART_GPIO_CLK, ENABLE);
|
||
DEBUG_USART_APBClkENx(DEBUG_USART_CLK, ENABLE);
|
||
|
||
//UART TX RX 复用
|
||
DEBUG_USART_AFTX;
|
||
DEBUG_USART_AFRX;
|
||
|
||
GPIO_InitStructure.Pins = DEBUG_USART_TX_GPIO_PIN;
|
||
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
|
||
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
|
||
GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);
|
||
|
||
GPIO_InitStructure.Pins = DEBUG_USART_RX_GPIO_PIN;
|
||
GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;
|
||
GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
|
||
|
||
|
||
USART_InitStructure.USART_BaudRate = DEBUG_USART_BaudRate;
|
||
USART_InitStructure.USART_Over = USART_Over_16;
|
||
USART_InitStructure.USART_Source = USART_Source_PCLK;
|
||
USART_InitStructure.USART_UclkFreq = DEBUG_USART_UclkFreq;
|
||
USART_InitStructure.USART_StartBit = USART_StartBit_FE;
|
||
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
||
USART_InitStructure.USART_Parity = USART_Parity_No ;
|
||
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
|
||
USART_Init(DEBUG_USARTx, &USART_InitStructure);
|
||
}
|
||
|
||
/**
|
||
* @brief Retargets the C library printf function to the USART.
|
||
*
|
||
*/
|
||
PUTCHAR_PROTOTYPE
|
||
{
|
||
|
||
USART_SendData_8bit(DEBUG_USARTx, (uint8_t)ch);
|
||
|
||
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
|
||
|
||
return ch;
|
||
}
|
||
|
||
/******************************************************************************
|
||
* EOF (not truncated)
|
||
******************************************************************************/
|
||
#ifdef USE_FULL_ASSERT
|
||
/**
|
||
* @brief Reports the name of the source file and the source line number
|
||
* where the assert_param error has occurred.
|
||
* @param file: pointer to the source file name
|
||
* @param line: assert_param error line source number
|
||
* @retval None
|
||
*/
|
||
void assert_failed(uint8_t *file, uint32_t line)
|
||
{
|
||
/* USER CODE BEGIN 6 */
|
||
/* User can add his own implementation to report the file name and line number,
|
||
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
||
/* USER CODE END 6 */
|
||
}
|
||
#endif /* USE_FULL_ASSERT */
|
||
|
||
|
||
void PowerOnDelay(void)
|
||
{
|
||
unsigned int i;
|
||
|
||
for(i=0;i<60000;i++);
|
||
for(i=0;i<60000;i++);
|
||
for(i=0;i<60000;i++);
|
||
for(i=0;i<60000;i++);
|
||
for(i=0;i<60000;i++);
|
||
for(i=0;i<60000;i++);
|
||
|
||
KKN=(MAXSPEED-MINSPEED);
|
||
KKN=KKN/(NMAXVD-NMINVD);
|
||
}
|
||
|
||
unsigned int hte=0;
|
||
int main()
|
||
{
|
||
unsigned char DZCount=0;
|
||
char temp_buff[100],temp_buff1[50];
|
||
|
||
// unsigned char key_1=0;
|
||
|
||
PowerOnDelay();
|
||
RCC_Configuration(); //时钟配置
|
||
UART_Configuration();
|
||
GPIOInit(); //GPIO配置
|
||
LEDON();
|
||
ADC_Configuration(); //AD配置
|
||
PWMtimer_init();
|
||
BTIM_init();
|
||
Halltimer_init();
|
||
//printf("ADC[0]:%d ADC[1]:%d ADC[2]:%d ADC[3]:%d\r\n",SampleData[0],SampleData[1],SampleData[2],SampleData[3]);
|
||
|
||
PWM_AL_ON;
|
||
PWM_BL_ON;
|
||
PWM_CL_ON;
|
||
TimeCountTemp=0;
|
||
while(TimeCountTemp<50);
|
||
TimeCountTemp=0;
|
||
PWM_AL_OFF;
|
||
PWM_BL_OFF;
|
||
PWM_CL_OFF;
|
||
|
||
// I2C_init(); //OLED init
|
||
// I2C_OLED_Init();
|
||
// I2C_OLED_Clear(1);
|
||
// I2C_OLED_UPdata();
|
||
//
|
||
printf("Update %s %s\r\n",__DATE__,__TIME__);
|
||
printf("ADC[0]:%d ADC[1]:%d ADC[2]:%d ADC[3]:%d\r\n",SampleData[0],SampleData[1],SampleData[2],SampleData[3]);
|
||
|
||
|
||
SampleVI(); //采集电压电流
|
||
startflag=1;
|
||
EnDirCheck();
|
||
|
||
DIin=0x500; //偏置电流设定 0.9V-1.1V中间,认为正确
|
||
if(SampleData[1]>1117&&SampleData[1]<=1500)DIin=SampleData[1];
|
||
else printf("Current read err\r\n");
|
||
if(SampleData[2]>3000|| SampleData[2]<700) printf("Speed read err\r\n");
|
||
if(HALL_Check()==0|| HALL_Check()==7) printf("HALL Read Err\r\n");
|
||
if(CanshuV<30) printf("Votage read err\r\n");
|
||
sprintf(temp_buff1,"Set :%4d RPM ",SetSpeed); //输出显示占空比
|
||
sprintf(temp_buff,"Real:%4d RPM ",RealS); //显示电机转速
|
||
printf("%s\r\n",temp_buff);
|
||
printf("%s\r\n",temp_buff1);
|
||
sprintf(temp_buff1,"Vbus :%d.%d V ",CanshuV/10,CanshuV%10); //输出显示占空比
|
||
sprintf(temp_buff,"I(MA):%d ",CanshuI); //显示电机转速
|
||
printf("%s\r\n",temp_buff);
|
||
printf("%s\r\n",temp_buff1);
|
||
GPIO_WritePin(VOUT_EN_GPIO_PORT,VOUT_EN_GPIO_PIN,GPIO_Pin_SET); //12V输出
|
||
while(1)
|
||
{
|
||
if(TimeCountCompuSpeed>20) //20MS采集一次速度设定值,并检查HALL是否有误
|
||
{
|
||
TimeCountCompuSpeed=0;
|
||
SampleSpeed();
|
||
HALL_Check();
|
||
}
|
||
|
||
if(TimeCountVI>=200)//100MS计算一次电压电流,并作一次实时速度计算
|
||
{
|
||
printf("ADC[0]:%d ADC[1]:%d ADC[2]:%d ADC[3]:%d\r\n",SampleData[0],SampleData[1],SampleData[2],SampleData[3]);
|
||
|
||
TimeCountVI=0;
|
||
SampleVI();
|
||
|
||
RealS=hte*50/MPolePairs;//HALLcount1*10*60/6/MPolePairs; 100MS存储一次霍尔边沿数
|
||
|
||
if(MOTORSTATE==STATESTARTPID||MOTORSTATE==STATERUNPID)
|
||
{
|
||
if(RealS==0)
|
||
{
|
||
DZCount++;
|
||
if(DZCount>=10)//2S保护
|
||
{
|
||
DZCount=0;ErrorCode=7;//堵转
|
||
}
|
||
}
|
||
else DZCount=0;
|
||
}
|
||
}
|
||
|
||
if(ErrorCode!=0&&MOTORSTATE!=STATEERROR&&MOTORSTATE!=STATEERROROVER)//发生故障
|
||
{
|
||
MOTORSTATE=STATEERROR;
|
||
printf("ErrorCode=%d\r\n",ErrorCode);
|
||
GPIO_WritePin(VOUT_EN_GPIO_PORT,VOUT_EN_GPIO_PIN,GPIO_Pin_RESET); //12V输出
|
||
}
|
||
|
||
|
||
if(TimeCountkey>=500) //500ms刷新显示
|
||
{
|
||
LEDTOG();
|
||
TimeCountkey=0;
|
||
// if(Menu==0)
|
||
// {
|
||
sprintf(temp_buff1,"Set :%4d RPM ",SetSpeed); //输出显示占空比
|
||
sprintf(temp_buff,"Real:%4d RPM ",RealS); //显示电机转速
|
||
printf("%s\r\n",temp_buff);
|
||
printf("%s\r\n",temp_buff1);
|
||
// }
|
||
// else
|
||
// {
|
||
sprintf(temp_buff1,"Vbus :%d.%d V ",CanshuV/10,CanshuV%10); //输出显示占空比
|
||
sprintf(temp_buff,"I(MA):%d ",CanshuI); //显示电机转速
|
||
// }
|
||
printf("%s\r\n",temp_buff);
|
||
printf("%s\r\n",temp_buff1);
|
||
// printf("MOTORSTATE=%d\r\n",MOTORSTATE);
|
||
// I2C_OLED_ShowString(0,0,temp_buff1);
|
||
// I2C_OLED_ShowString(0,15,temp_buff);
|
||
// I2C_OLED_UPdata();
|
||
}
|
||
MotorBreak();
|
||
EnDirCheck();
|
||
|
||
//状态机
|
||
switch(MOTORSTATE)
|
||
{
|
||
case STATESTARTCHECK:
|
||
MotorStartCheck();
|
||
break;
|
||
case STATESTARTPID:
|
||
MotorStartPID();
|
||
break;
|
||
case STATERUNPID:
|
||
MotorRunPID();
|
||
break;
|
||
case STATESTOP: MotorStop();break;
|
||
case STATEERROR: MotorError();break;
|
||
case STATEERROROVER: MotorErrorOver();break;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
//1ms 定时器
|
||
void BTIM1_IRQHandler(void)
|
||
{
|
||
/* USER CODE BEGIN */
|
||
if(BTIM_GetITStatus(CW_BTIM1, BTIM_IT_OV))
|
||
{ //1MS timer
|
||
BTIM_ClearITPendingBit(CW_BTIM1, BTIM_IT_OV);
|
||
|
||
TimeCountTemp++;
|
||
TimeCountCompuSpeed++; //计算速度
|
||
TimeCountRealSpd++; //瞬时速度
|
||
if(TimeCountAvgSpd>=200){hte=HALLcount1;HALLcount1=0;TimeCountAvgSpd=0;}//用于显示的速度值
|
||
if(TimeCountRealSpd>=20){HALLcountTemp=HALLcount;HALLcount=0;TimeCountRealSpd=0;}
|
||
TimeCountPID++; //PID
|
||
TimeCountAvgSpd++; //平均速度
|
||
TimeCountVI++;//计算电压电流
|
||
TimeCountkey++;
|
||
}
|
||
/* USER CODE END */
|
||
}
|
||
|
||
|