init
This commit is contained in:
109
научка/code/pwm_motor_control/Interface/i2c_lcd.c
Normal file
109
научка/code/pwm_motor_control/Interface/i2c_lcd.c
Normal file
@@ -0,0 +1,109 @@
|
||||
#include "i2c_lcd.h"
|
||||
|
||||
extern unsigned tim1_cnt;
|
||||
|
||||
|
||||
//extern struct var_result VAR_RESULT;
|
||||
//LCD Delays (Delay1 - )
|
||||
|
||||
/**
|
||||
* @brief Initialization of LCD.
|
||||
* @note This called from main
|
||||
*/
|
||||
void LCD_Init(LCDI2C_HandleTypeDef *hlcd)
|
||||
{
|
||||
for (hlcd->Address = 0; hlcd->Address < 128; hlcd->Address++)
|
||||
{
|
||||
if(HAL_I2C_IsDeviceReady(hlcd->hi2c, hlcd->Address << 1, 1, HAL_MAX_DELAY)==HAL_OK) break; // scan i2c adresses
|
||||
}
|
||||
if (hlcd->Address >= 128)
|
||||
return;
|
||||
hlcd->Address = hlcd->Address << 1;
|
||||
|
||||
osDelay(500);
|
||||
LCD_Send_CMD(hlcd, 0x30);
|
||||
osDelay(5);
|
||||
LCD_Send_CMD(hlcd, 0x30);
|
||||
osDelay(1);
|
||||
LCD_Send_CMD(hlcd, 0x30);
|
||||
osDelay(10);
|
||||
LCD_Send_CMD(hlcd, 0x20); // 4bit mode
|
||||
osDelay(10);
|
||||
|
||||
//dislay initialisation
|
||||
LCD_Send_CMD(hlcd, 0x28); // display off
|
||||
osDelay(1);
|
||||
LCD_Send_CMD(hlcd, 0x08); // display off
|
||||
osDelay(50);
|
||||
LCD_Send_CMD(hlcd, 0x01); // clear display
|
||||
osDelay(10);
|
||||
osDelay(10);
|
||||
LCD_Send_CMD(hlcd, 0x06); // direction of cursor
|
||||
osDelay(1);
|
||||
LCD_Send_CMD(hlcd, 0x0C); // display on / cursor off
|
||||
|
||||
}
|
||||
|
||||
void LCD_Reinit(LCDI2C_HandleTypeDef *hlcd)
|
||||
{
|
||||
osDelay(1000);
|
||||
LCD_Init(hlcd);
|
||||
hlcd->LCD_REINIT=0;
|
||||
}
|
||||
void LCD_Check(LCDI2C_HandleTypeDef *hlcd)
|
||||
{
|
||||
if(hlcd->LCD_REINIT) LCD_Reinit(hlcd);
|
||||
}
|
||||
|
||||
void LCD_Send_CMD (LCDI2C_HandleTypeDef *hlcd, char cmd)
|
||||
{
|
||||
char data_up, data_low;
|
||||
uint8_t data_t[4];
|
||||
data_up = (cmd&0xf0);
|
||||
data_low=((cmd<<4)&0xf0);
|
||||
data_t[0]=data_up|0x0C; //en=1, rs=0
|
||||
data_t[1]=data_up|0x08; //en=0, rs=0
|
||||
data_t[2]=data_low|0x0C; //en=1, rs=0
|
||||
data_t[3]=data_low|0x08; //en=0, rs=0
|
||||
HAL_I2C_Master_Transmit(hlcd->hi2c, hlcd->Address, (uint8_t *)data_t, 4, HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
void LCD_Send_DATA (LCDI2C_HandleTypeDef *hlcd, char data)
|
||||
{
|
||||
char data_up, data_low;
|
||||
uint8_t data_t[4];
|
||||
data_up = (data&0xf0);
|
||||
data_low=((data<<4)&0xf0);
|
||||
data_t[0]=data_up|0x0D; //en=1, rs=1
|
||||
data_t[1]=data_up|0x09; //en=0, rs=1
|
||||
data_t[2]=data_low|0x0D; //en=1, rs=1
|
||||
data_t[3]=data_low|0x09; //en=0, rs=1
|
||||
HAL_I2C_Master_Transmit(hlcd->hi2c, hlcd->Address, (uint8_t *)data_t, 4, HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
void LCD_Send_STRING(LCDI2C_HandleTypeDef *hlcd, char *str)
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
LCD_Send_DATA (hlcd, *str++);
|
||||
osDelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
void LCD_Send_INT(LCDI2C_HandleTypeDef *hlcd, int int_to_string, uint8_t size)
|
||||
{
|
||||
char string_from_int[10];
|
||||
if(size)
|
||||
sprintf(string_from_int, "%0*d", size, int_to_string);
|
||||
else
|
||||
sprintf(string_from_int, "%d", int_to_string);
|
||||
LCD_Send_STRING(hlcd, string_from_int);
|
||||
}
|
||||
|
||||
void LCD_Send_NUMB(LCDI2C_HandleTypeDef *hlcd, float numb_to_string, uint8_t size)
|
||||
{
|
||||
char string_from_numb[size];
|
||||
snprintf(string_from_numb, size+1, "%.2f", numb_to_string);
|
||||
LCD_Send_STRING(hlcd, string_from_numb);
|
||||
}
|
||||
|
||||
30
научка/code/pwm_motor_control/Interface/i2c_lcd.h
Normal file
30
научка/code/pwm_motor_control/Interface/i2c_lcd.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef __LCD_H_
|
||||
#define __LCD_H_
|
||||
|
||||
#include "periph_general.h"
|
||||
#include "cmsis_os.h"
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct{
|
||||
uint8_t Address;
|
||||
I2C_HandleTypeDef *hi2c;
|
||||
unsigned LCD_REINIT : 1;
|
||||
uint16_t DisplayDelay;
|
||||
uint8_t ClearDelay;
|
||||
|
||||
}LCDI2C_HandleTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Initialization of LCD.
|
||||
* @note This called from main
|
||||
*/
|
||||
void LCD_Init(LCDI2C_HandleTypeDef *hlcd);
|
||||
void LCD_Reinit(LCDI2C_HandleTypeDef *hlcd);
|
||||
void LCD_Check(LCDI2C_HandleTypeDef *hlcd);
|
||||
void LCD_Send_STRING(LCDI2C_HandleTypeDef *hlcd, char *str);
|
||||
void LCD_Send_INT(LCDI2C_HandleTypeDef *hlcd, int int_to_string, uint8_t size);
|
||||
void LCD_Send_NUMB(LCDI2C_HandleTypeDef *hlcd, float numb_to_string, uint8_t size);
|
||||
void LCD_Send_DATA (LCDI2C_HandleTypeDef *hlcd, char data);
|
||||
void LCD_Send_CMD (LCDI2C_HandleTypeDef *hlcd, char cmd);
|
||||
|
||||
#endif
|
||||
517
научка/code/pwm_motor_control/Interface/interface.c
Normal file
517
научка/code/pwm_motor_control/Interface/interface.c
Normal file
@@ -0,0 +1,517 @@
|
||||
#include "interface.h"
|
||||
#include "pwm.h"
|
||||
|
||||
TIM_SettingsTypeDef TIM_ENCODER = {0};
|
||||
extern I2C_HandleTypeDef hi2c1;
|
||||
LCDI2C_HandleTypeDef hlcd1;
|
||||
TIM_EncoderTypeDef henc1;
|
||||
extern PWM_HandleTypeDef hpwm1;
|
||||
|
||||
Interface_HandleTypeDef hinterface;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read encoder function.
|
||||
* @param henc - хендл энкодера.
|
||||
* @param hlcd - хендл LCD-дисплея.
|
||||
* @note This called from freertos MainTask thread.
|
||||
*/
|
||||
void ReadEncoder(TIM_EncoderTypeDef *henc, LCDI2C_HandleTypeDef *hlcd)
|
||||
{
|
||||
uint8_t *menu = (uint8_t *)&hinterface.MenuItems;
|
||||
uint8_t *disp_menu = (uint8_t *)&hinterface.DisplayingItems;
|
||||
|
||||
//-----------READ SWITCH-------------
|
||||
if(hinterface.FineChanging == 0) // если кнопка энкодера не в режиме точной настройки
|
||||
{
|
||||
if((~henc->GPIOx->IDR)&henc->GPIO_PIN_SW) // ожидание нажатия кнопки
|
||||
{
|
||||
osDelay(50);
|
||||
if(((~henc->GPIOx->IDR)&henc->GPIO_PIN_SW )&& // если кнопка действительно нажата
|
||||
(HAL_GetTick() - hinterface.Switch_prevTick > hinterface.DoubleClick_Timeout) ) // и это не второй клик даблклика (слишком большая задержка после предыдущего нажатия)
|
||||
{
|
||||
hinterface.Encoder_Shdw = henc->htim->Instance->CNT;
|
||||
while((~henc->GPIOx->IDR)&henc->GPIO_PIN_SW) // ожидаем её отпускания
|
||||
{
|
||||
//------------FINE TUNE--------------
|
||||
if (hinterface.Encoder_Shdw != henc->htim->Instance->CNT) // если кнопка не отпускается, и енкодер начинает регулироваться
|
||||
{
|
||||
hinterface.FineChanging = 1; // переходим в режим точной настройки
|
||||
break; // выход из цикла
|
||||
}
|
||||
osDelay(1);
|
||||
}
|
||||
//-----------SWITCH PARAM------------
|
||||
if(hinterface.FineChanging == 0) // если энкодер не перешел в режим точной настройки
|
||||
{
|
||||
hinterface.Switch_prevTick = HAL_GetTick(); // сохраняем время отжатия для регистрации даблклика если он будет
|
||||
hinterface.CurrentSelection++; // переключаем режим
|
||||
|
||||
// skip item if it isnt displayin, until run out of items
|
||||
while((*disp_menu&(1<<(hinterface.CurrentSelection-1))) == 0)
|
||||
{
|
||||
hinterface.CurrentSelection++;
|
||||
if(hinterface.MenuNumber == 0) // if menu for params (registers)
|
||||
{
|
||||
if(hinterface.CurrentSelection > Menu_Size)
|
||||
{
|
||||
hinterface.CurrentSelection = NOTHING_SELECTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // if menu for modes (coils)
|
||||
{
|
||||
if(hinterface.CurrentSelection - NOTHING_COIL_SELECTED > Menu_Coil_Size)
|
||||
{
|
||||
hinterface.CurrentSelection = NOTHING_COIL_SELECTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(hinterface.MenuNumber == 0)
|
||||
{
|
||||
if(hinterface.CurrentSelection > (Menu_Size))
|
||||
hinterface.CurrentSelection = NOTHING_SELECTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((hinterface.CurrentSelection - NOTHING_COIL_SELECTED) > (Menu_Coil_Size))
|
||||
hinterface.CurrentSelection = NOTHING_COIL_SELECTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(((~henc->GPIOx->IDR)&henc->GPIO_PIN_SW )&& // если кнопка действительно нажата
|
||||
(HAL_GetTick() - hinterface.Switch_prevTick < hinterface.DoubleClick_Timeout) ) // и это не второй клик даблклика (слишком большая задержка после предыдущего нажатия)
|
||||
{
|
||||
hinterface.MenuNumber++;
|
||||
if(hinterface.MenuNumber >= 2)
|
||||
{
|
||||
hinterface.MenuNumber = 0;
|
||||
}
|
||||
|
||||
if (hinterface.MenuNumber == 0)
|
||||
hinterface.CurrentSelection = NOTHING_SELECTED;
|
||||
else if (hinterface.MenuNumber == 1)
|
||||
hinterface.CurrentSelection = NOTHING_COIL_SELECTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static uint16_t coef_value;
|
||||
if(hinterface.FineChanging == 0) // если енкодер не регулируется
|
||||
coef_value = 100;
|
||||
else
|
||||
coef_value = 2;
|
||||
|
||||
int16_t encoder_diff = (int32_t)henc->htim->Instance->CNT - hinterface.Encoder_Shdw;
|
||||
|
||||
int32_t tmpreg;
|
||||
switch(hinterface.CurrentSelection)
|
||||
{
|
||||
case PWM_VALUE_SELECTED:
|
||||
tmpreg = pwm_ctrl[R_PWM_CTRL_PWM_VALUE];
|
||||
tmpreg += ((encoder_diff*coef_value)/2);
|
||||
if (tmpreg >= 0)
|
||||
pwm_ctrl[R_PWM_CTRL_PWM_VALUE] = tmpreg;
|
||||
else
|
||||
pwm_ctrl[R_PWM_CTRL_PWM_VALUE] = 0;
|
||||
break;
|
||||
|
||||
case PWM_HZ_SELECTED:
|
||||
tmpreg = pwm_ctrl[R_PWM_CTRL_PWM_HZ];
|
||||
tmpreg += (encoder_diff*coef_value)/2;
|
||||
if (tmpreg >= 0)
|
||||
pwm_ctrl[R_PWM_CTRL_PWM_HZ] = tmpreg;
|
||||
else
|
||||
pwm_ctrl[R_PWM_CTRL_PWM_HZ] = 0;
|
||||
break;
|
||||
|
||||
case PWM_DUTYBRIDGE_SELECTED:
|
||||
tmpreg = pwm_ctrl[R_PWM_CTRL_DUTY_BRIDGE];
|
||||
tmpreg += ((encoder_diff*coef_value)/2);
|
||||
if (tmpreg < 0)
|
||||
pwm_ctrl[R_PWM_CTRL_DUTY_BRIDGE] = 0;
|
||||
else if (tmpreg > 10000)
|
||||
pwm_ctrl[R_PWM_CTRL_DUTY_BRIDGE] = 10000;
|
||||
else
|
||||
pwm_ctrl[R_PWM_CTRL_DUTY_BRIDGE] = tmpreg;
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case PWM_COIL_DC_SELECTED:
|
||||
if(encoder_diff)
|
||||
hpwm1.sPWM_Config.PWM_Mode->DC = ~hpwm1.sPWM_Config.PWM_Mode->DC;
|
||||
break;
|
||||
|
||||
|
||||
case PWM_COIL_BRIDGE_SELECTED:
|
||||
if(encoder_diff)
|
||||
hpwm1.sPWM_Config.PWM_Mode->BRIDGE = ~hpwm1.sPWM_Config.PWM_Mode->BRIDGE;
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case PWM_COIL_PHASE_SELECTED:
|
||||
if(encoder_diff)
|
||||
hpwm1.sPWM_Config.PWM_Mode->PHASE = ~hpwm1.sPWM_Config.PWM_Mode->PHASE;
|
||||
break;
|
||||
|
||||
|
||||
case PWM_COIL_POLARITY_SELECTED:
|
||||
if(encoder_diff)
|
||||
hpwm1.sPWM_Config.PWM_Mode->POLARITY = ~hpwm1.sPWM_Config.PWM_Mode->POLARITY;
|
||||
break;
|
||||
|
||||
case NOTHING_SELECTED:
|
||||
if(encoder_diff > 0)
|
||||
hinterface.StartMenuItem += 1;
|
||||
else if(encoder_diff < 0)
|
||||
hinterface.StartMenuItem -= 1;
|
||||
if(hinterface.StartMenuItem < 0)
|
||||
hinterface.StartMenuItem = 0;
|
||||
break;
|
||||
|
||||
case NOTHING_COIL_SELECTED:
|
||||
if(encoder_diff > 0)
|
||||
hinterface.StartMenuItem += 1;
|
||||
else if(encoder_diff < 0)
|
||||
hinterface.StartMenuItem -= 1;
|
||||
if(hinterface.StartMenuItem < 0)
|
||||
hinterface.StartMenuItem = 0;
|
||||
break;
|
||||
|
||||
|
||||
default: break;
|
||||
}
|
||||
hinterface.Encoder_Shdw = henc->htim->Instance->CNT;
|
||||
|
||||
|
||||
|
||||
|
||||
if(hinterface.FineChanging == 1) // если некодер в режиме точной настройки)
|
||||
{
|
||||
if(((~henc->GPIOx->IDR)&henc->GPIO_PIN_SW) == 0) // ожидание отпускания кнопки
|
||||
{
|
||||
osDelay(50);
|
||||
if(((~henc->GPIOx->IDR)&henc->GPIO_PIN_SW) == 0) // если кнопка действительно нажата
|
||||
{
|
||||
hinterface.FineChanging = 0; // отключение режима точной настройки
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void UpdateInterfaceStruct(void)
|
||||
{
|
||||
if(hinterface.MenuNumber == 0)
|
||||
{
|
||||
if(hpwm1.sPWM_Config.PWM_Mode->BRIDGE && hpwm1.sPWM_Config.PWM_Mode->DC)
|
||||
hinterface.MenuItems.PWM_DutyBridge = 1;
|
||||
else
|
||||
hinterface.MenuItems.PWM_DutyBridge = 0;
|
||||
hinterface.MenuItems.PWM_Hz = 1;
|
||||
hinterface.MenuItems.PWM_Value = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
hinterface.MenuItems.PWM_DC = 1;
|
||||
hinterface.MenuItems.PWM_BRIDGE = 1;
|
||||
hinterface.MenuItems.PWM_PHASE = 1;
|
||||
hinterface.MenuItems.PWM_POLARITY = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateLCDDisplay(LCDI2C_HandleTypeDef *hlcd)
|
||||
{
|
||||
LCD_Check(hlcd);
|
||||
|
||||
// clear display
|
||||
LCD_Send_CMD(hlcd, 0x01);
|
||||
osDelay(hlcd->ClearDelay);
|
||||
|
||||
uint8_t *menu = (uint8_t *)&hinterface.MenuItems;
|
||||
int8_t disp_cnt = 0;
|
||||
disp_cnt -= hinterface.StartMenuItem;
|
||||
hinterface.DisplayingItems = (const Menu_HandleTypeDef){0};
|
||||
|
||||
if(hinterface.MenuNumber == 0)
|
||||
disp_cnt = LCD_DisplayMenuRegisters(hlcd, menu, disp_cnt);
|
||||
else
|
||||
disp_cnt = LCD_DisplayMenuCoils(hlcd, menu, disp_cnt);
|
||||
|
||||
|
||||
// if less than 2 item displayed - decrease start menu item
|
||||
if(disp_cnt <= 1) hinterface.StartMenuItem--;
|
||||
|
||||
osDelay(hlcd->DisplayDelay);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t LCD_DisplayMenuCoils(LCDI2C_HandleTypeDef *hlcd, uint8_t *menu, int8_t disp_cnt)
|
||||
{
|
||||
for(int i = 0; i < Menu_Coil_Size; i++)
|
||||
{
|
||||
|
||||
// if first sring is printed
|
||||
if (disp_cnt%2 == 0)
|
||||
LCD_Send_CMD(hlcd, 0x80); // set cursor to second string
|
||||
|
||||
// if first sring is printed
|
||||
if (disp_cnt%2 == 1)
|
||||
LCD_Send_CMD(hlcd, 0xC0); // set cursor to second string
|
||||
switch(*menu&(1<<(i+NOTHING_COIL_SELECTED)))
|
||||
{
|
||||
case Menu_PWM_DC:
|
||||
disp_cnt++;
|
||||
|
||||
if(disp_cnt > 0)
|
||||
{
|
||||
hinterface.DisplayingItems.PWM_DC = 1;
|
||||
if(hinterface.CurrentSelection == NOTHING_COIL_SELECTED)
|
||||
Display_PWM_DC(hlcd);
|
||||
else if (hinterface.CurrentSelection == PWM_COIL_DC_SELECTED)
|
||||
Display_PWM_DC(hlcd);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case Menu_PWM_BRIDGE:
|
||||
disp_cnt++;
|
||||
|
||||
if(disp_cnt > 0)
|
||||
{
|
||||
hinterface.DisplayingItems.PWM_BRIDGE = 1;
|
||||
if(hinterface.CurrentSelection == NOTHING_COIL_SELECTED)
|
||||
Display_PWM_BRIDGE(hlcd);
|
||||
else if (hinterface.CurrentSelection == PWM_COIL_BRIDGE_SELECTED)
|
||||
Display_PWM_BRIDGE(hlcd);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case Menu_PWM_PHASE:
|
||||
disp_cnt++;
|
||||
|
||||
if(disp_cnt > 0)
|
||||
{
|
||||
hinterface.DisplayingItems.PWM_PHASE = 1;
|
||||
if(hinterface.CurrentSelection == NOTHING_COIL_SELECTED)
|
||||
Display_PWM_PHASE(hlcd);
|
||||
else if (hinterface.CurrentSelection == PWM_COIL_PHASE_SELECTED)
|
||||
Display_PWM_PHASE(hlcd);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case Menu_PWM_POLARITY:
|
||||
disp_cnt++;
|
||||
|
||||
if(disp_cnt > 0)
|
||||
{
|
||||
hinterface.DisplayingItems.PWM_POLARITY = 1;
|
||||
if(hinterface.CurrentSelection == NOTHING_COIL_SELECTED)
|
||||
Display_PWM_POLARITY(hlcd);
|
||||
else if (hinterface.CurrentSelection == PWM_COIL_POLARITY_SELECTED)
|
||||
Display_PWM_POLARITY(hlcd);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// if second sring is printed
|
||||
if (disp_cnt >= 2)
|
||||
break; // stop "displaying"
|
||||
}
|
||||
return disp_cnt;
|
||||
}
|
||||
|
||||
uint8_t LCD_DisplayMenuRegisters(LCDI2C_HandleTypeDef *hlcd, uint8_t *menu, int8_t disp_cnt)
|
||||
{
|
||||
for(int i = 0; i < Menu_Size; i++)
|
||||
{
|
||||
|
||||
// if first sring is printed
|
||||
if (disp_cnt%2 == 0)
|
||||
LCD_Send_CMD(hlcd, 0x80); // set cursor to second string
|
||||
|
||||
// if first sring is printed
|
||||
if (disp_cnt%2 == 1)
|
||||
LCD_Send_CMD(hlcd, 0xC0); // set cursor to second string
|
||||
switch(*menu&(1<<i))
|
||||
{
|
||||
case Menu_PWM_Value:
|
||||
disp_cnt++;
|
||||
|
||||
if(disp_cnt > 0)
|
||||
{
|
||||
hinterface.DisplayingItems.PWM_Value = 1;
|
||||
if(hinterface.CurrentSelection == NOTHING_SELECTED)
|
||||
Display_PWM_Value(hlcd);
|
||||
else if (hinterface.CurrentSelection == PWM_VALUE_SELECTED)
|
||||
Display_PWM_Value(hlcd);
|
||||
}
|
||||
break;
|
||||
|
||||
case Menu_PWM_Hz:
|
||||
disp_cnt++;
|
||||
|
||||
if(disp_cnt > 0)
|
||||
{
|
||||
hinterface.DisplayingItems.PWM_Hz = 1;
|
||||
if(hinterface.CurrentSelection == NOTHING_SELECTED)
|
||||
Display_PWM_Hz(hlcd);
|
||||
else if (hinterface.CurrentSelection == PWM_HZ_SELECTED)
|
||||
Display_PWM_Hz(hlcd);
|
||||
}
|
||||
break;
|
||||
|
||||
case Menu_PWM_DutyBridge:
|
||||
disp_cnt++;
|
||||
|
||||
if(disp_cnt > 0)
|
||||
{
|
||||
hinterface.DisplayingItems.PWM_DutyBridge = 1;
|
||||
if(hinterface.CurrentSelection == NOTHING_SELECTED)
|
||||
Display_PWM_DutyBridge(hlcd);
|
||||
else if (hinterface.CurrentSelection == PWM_DUTYBRIDGE_SELECTED)
|
||||
Display_PWM_DutyBridge(hlcd);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// if second sring is printed
|
||||
if (disp_cnt >= 2)
|
||||
break; // stop "displaying"
|
||||
}
|
||||
return disp_cnt;
|
||||
}
|
||||
|
||||
|
||||
void Display_PWM_Value(LCDI2C_HandleTypeDef *hlcd)
|
||||
{
|
||||
if(hpwm1.sPWM_Mode&PWM_DC_MODE && ((hpwm1.sPWM_Mode&PWM_BRIDGE_MODE) == 0)) // in dc mode disp pwm duty
|
||||
{
|
||||
LCD_Send_STRING(hlcd, "Duty: ");
|
||||
LCD_Send_INT(hlcd, pwm_ctrl[R_PWM_CTRL_PWM_VALUE]/100, 0);
|
||||
LCD_Send_STRING(hlcd, ".");
|
||||
LCD_Send_INT(hlcd, pwm_ctrl[R_PWM_CTRL_PWM_VALUE]%100, 2);
|
||||
LCD_Send_STRING(hlcd, "%");
|
||||
}
|
||||
else // in dc mode disp sine freq
|
||||
{
|
||||
LCD_Send_STRING(hlcd, "Sine: ");
|
||||
LCD_Send_INT(hlcd, pwm_ctrl[R_PWM_CTRL_PWM_VALUE]/100, 0);
|
||||
LCD_Send_STRING(hlcd, ".");
|
||||
LCD_Send_INT(hlcd, pwm_ctrl[R_PWM_CTRL_PWM_VALUE]%100, 2);
|
||||
LCD_Send_STRING(hlcd, " Hz");
|
||||
}
|
||||
}
|
||||
|
||||
void Display_PWM_Hz(LCDI2C_HandleTypeDef *hlcd)
|
||||
{
|
||||
LCD_Send_STRING(hlcd, "PWM: ");
|
||||
LCD_Send_INT(hlcd, pwm_ctrl[R_PWM_CTRL_PWM_HZ], 0);
|
||||
LCD_Send_STRING(hlcd, " Hz");
|
||||
}
|
||||
|
||||
void Display_PWM_DutyBridge(LCDI2C_HandleTypeDef *hlcd)
|
||||
{
|
||||
LCD_Send_STRING(hlcd, "Duty: ");
|
||||
LCD_Send_INT(hlcd, pwm_ctrl[R_PWM_CTRL_DUTY_BRIDGE]/100, 0);
|
||||
LCD_Send_STRING(hlcd, ".");
|
||||
LCD_Send_INT(hlcd, pwm_ctrl[R_PWM_CTRL_DUTY_BRIDGE]%100, 2);
|
||||
LCD_Send_STRING(hlcd, "%");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Display_PWM_DC(LCDI2C_HandleTypeDef *hlcd)
|
||||
{
|
||||
LCD_Send_STRING(hlcd, "DC: ");
|
||||
if(hpwm1.sPWM_Config.PWM_Mode->DC)
|
||||
LCD_Send_STRING(hlcd, "DC");
|
||||
else
|
||||
LCD_Send_STRING(hlcd, "Sine");
|
||||
}
|
||||
|
||||
|
||||
void Display_PWM_BRIDGE(LCDI2C_HandleTypeDef *hlcd)
|
||||
{
|
||||
LCD_Send_STRING(hlcd, "Bridge: ");
|
||||
if(hpwm1.sPWM_Config.PWM_Mode->BRIDGE)
|
||||
LCD_Send_STRING(hlcd, "Bridge");
|
||||
else
|
||||
LCD_Send_STRING(hlcd, "Single");
|
||||
}
|
||||
|
||||
|
||||
void Display_PWM_PHASE(LCDI2C_HandleTypeDef *hlcd)
|
||||
{
|
||||
LCD_Send_STRING(hlcd, "Phase: ");
|
||||
if(hpwm1.sPWM_Config.PWM_Mode->PHASE)
|
||||
LCD_Send_STRING(hlcd, "3-Phase");
|
||||
else
|
||||
LCD_Send_STRING(hlcd, "One Phase");
|
||||
}
|
||||
|
||||
void Display_PWM_POLARITY(LCDI2C_HandleTypeDef *hlcd)
|
||||
{
|
||||
LCD_Send_STRING(hlcd, "Polarity: ");
|
||||
if(hpwm1.sPWM_Config.PWM_Mode->POLARITY)
|
||||
LCD_Send_STRING(hlcd, "Neg");
|
||||
else
|
||||
LCD_Send_STRING(hlcd, "Pos");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief First initialization of Encoder Timer.
|
||||
* @note This called from main
|
||||
*/
|
||||
void EncoderFirstInit(void)
|
||||
{
|
||||
hinterface.DoubleClick_Timeout = 200;
|
||||
// tim settings
|
||||
TIM_ENCODER.htim.Instance = TIMER_ENCODER_INSTANCE;
|
||||
TIM_ENCODER.htim.Init.Period = 0xFFFF;
|
||||
TIM_ENCODER.htim.Init.Prescaler = 0;
|
||||
TIM_ENCODER.sTimMode = TIM_IT_MODE;
|
||||
// TIM_ENCODER.sTickBaseMHz = TIMER_ENCODER_TICKBASE;
|
||||
// TIM_ENCODER.sTimAHBFreqMHz = TIMER_ENCODER_AHB_FREQ;
|
||||
// TIM_ENCODER.sTimFreqHz = 0;
|
||||
|
||||
TIM_Base_Init(&TIM_ENCODER);
|
||||
|
||||
henc1.sConfig.EncoderMode = TIM_ENCODERMODE_TI2;
|
||||
henc1.sConfig.IC1Polarity = TIM_INPUTCHANNELPOLARITY_FALLING;
|
||||
henc1.sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
|
||||
henc1.sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
|
||||
henc1.sConfig.IC1Filter = 5;
|
||||
henc1.sConfig.IC2Polarity = TIM_INPUTCHANNELPOLARITY_FALLING;
|
||||
henc1.sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
|
||||
henc1.sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
|
||||
henc1.sConfig.IC2Filter = 5;
|
||||
henc1.GPIOx = TIMER_ENCODER_PORT;
|
||||
henc1.GPIO_PIN_TI1 = TIMER_ENCODER_PIN1;
|
||||
henc1.GPIO_PIN_TI2 = TIMER_ENCODER_PIN2;
|
||||
henc1.GPIO_PIN_SW = TIMER_ENCODER_PIN_SW;
|
||||
TIM_Encoder_Init(&henc1, &TIM_ENCODER.htim);
|
||||
|
||||
HAL_TIM_Base_Start(&TIM_ENCODER.htim);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief First initialization of LCD.
|
||||
* @note This called from main
|
||||
*/
|
||||
void LCD_FirstInit(void)
|
||||
{
|
||||
hlcd1.hi2c = &hi2c1;
|
||||
hlcd1.DisplayDelay = 250;
|
||||
hlcd1.ClearDelay = 10;
|
||||
LCD_Init(&hlcd1);
|
||||
}
|
||||
94
научка/code/pwm_motor_control/Interface/interface.h
Normal file
94
научка/code/pwm_motor_control/Interface/interface.h
Normal file
@@ -0,0 +1,94 @@
|
||||
#ifndef __INTERFACE_H_
|
||||
#define __INTERFACE_H_
|
||||
|
||||
#include "periph_general.h"
|
||||
#include "i2c_lcd.h"
|
||||
|
||||
|
||||
extern LCDI2C_HandleTypeDef hlcd1;
|
||||
extern TIM_EncoderTypeDef henc1;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NOTHING_SELECTED,
|
||||
PWM_VALUE_SELECTED,
|
||||
PWM_HZ_SELECTED,
|
||||
PWM_DUTYBRIDGE_SELECTED,
|
||||
|
||||
NOTHING_COIL_SELECTED,
|
||||
PWM_COIL_DC_SELECTED,
|
||||
PWM_COIL_BRIDGE_SELECTED,
|
||||
PWM_COIL_PHASE_SELECTED,
|
||||
PWM_COIL_POLARITY_SELECTED,
|
||||
}CurrentSelection_TypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned PWM_Value:1;
|
||||
unsigned PWM_Hz:1;
|
||||
unsigned PWM_DutyBridge:1;
|
||||
unsigned reserved:1;
|
||||
unsigned PWM_DC:1;
|
||||
unsigned PWM_BRIDGE:1;
|
||||
unsigned PWM_PHASE:1;
|
||||
unsigned PWM_POLARITY:1;
|
||||
}Menu_HandleTypeDef;
|
||||
typedef struct
|
||||
{
|
||||
Menu_HandleTypeDef MenuItems;
|
||||
Menu_HandleTypeDef DisplayingItems;
|
||||
CurrentSelection_TypeDef CurrentSelection;
|
||||
uint8_t MenuNumber;
|
||||
unsigned FineChanging:1;
|
||||
int8_t StartMenuItem;
|
||||
|
||||
uint32_t Encoder_Shdw;
|
||||
uint32_t Switch_Shdw;
|
||||
uint32_t Switch_prevTick;
|
||||
uint32_t DoubleClick_Timeout;
|
||||
}Interface_HandleTypeDef;
|
||||
|
||||
|
||||
#define Menu_Size 3
|
||||
#define Menu_Coil_Size 4
|
||||
|
||||
#define Menu_PWM_Value (1<<0)
|
||||
#define Menu_PWM_Hz (1<<1)
|
||||
#define Menu_PWM_DutyBridge (1<<2)
|
||||
|
||||
#define Menu_PWM_DC (1<<4)
|
||||
#define Menu_PWM_BRIDGE (1<<5)
|
||||
#define Menu_PWM_PHASE (1<<6)
|
||||
#define Menu_PWM_POLARITY (1<<7)
|
||||
|
||||
void UpdateInterfaceStruct(void);
|
||||
void ReadEncoder(TIM_EncoderTypeDef *henc, LCDI2C_HandleTypeDef *hlcd);
|
||||
void UpdateLCDDisplay(LCDI2C_HandleTypeDef *hlcd);
|
||||
void Display_PWM_Value(LCDI2C_HandleTypeDef *hlcd);
|
||||
void Display_PWM_Hz(LCDI2C_HandleTypeDef *hlcd);
|
||||
void Display_PWM_DutyBridge(LCDI2C_HandleTypeDef *hlcd);
|
||||
|
||||
|
||||
void Display_PWM_DC(LCDI2C_HandleTypeDef *hlcd);
|
||||
void Display_PWM_BRIDGE(LCDI2C_HandleTypeDef *hlcd);
|
||||
void Display_PWM_PHASE(LCDI2C_HandleTypeDef *hlcd);
|
||||
void Display_PWM_POLARITY(LCDI2C_HandleTypeDef *hlcd);
|
||||
uint8_t LCD_DisplayMenuCoils(LCDI2C_HandleTypeDef *hlcd, uint8_t *menu, int8_t disp_cnt);
|
||||
uint8_t LCD_DisplayMenuRegisters(LCDI2C_HandleTypeDef *hlcd, uint8_t *menu, int8_t disp_cnt);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief First initialization of LCD.
|
||||
* @note This called from main
|
||||
*/
|
||||
void LCD_FirstInit(void);
|
||||
|
||||
/**
|
||||
* @brief First initialization of Encoder Timer.
|
||||
* @note This called from main
|
||||
*/
|
||||
void EncoderFirstInit(void);
|
||||
|
||||
#endif // __INTERFACE_H_
|
||||
Reference in New Issue
Block a user