#include "headfile.h"
typedef enum
{
PAGE_MAIN_MENU = 0,
PAGE_MOTOR_MENU = 1,
PAGE_SERVO_MENU = 2
}
page_state_t;
typedef enum
{
MENU_MOTOR = 0,
MENU_SERVO = 1,
MENU_COUNT
}
menu_item_t;
typedef enum
{
MOTOR_MENU_KP = 0,
MOTOR_MENU_KI = 1,
MOTOR_MENU_KD = 2,
MOTOR_MENU_EXIT = 3,
MOTOR_MENU_COUNT
}
motor_menu_item_t;
typedef enum
{
SERVO_MENU_KP = 0,
SERVO_MENU_KD = 1,
SERVO_MENU_EXIT = 2,
SERVO_MENU_COUNT
}
servo_menu_item_t;
#define KEY_UP_PIN C3
#define KEY_DOWN_PIN C14
#define KEY_OK_PIN C2
#define KEY_LEFT_PIN C13
#define KEY_RIGHT_PIN C15
#define FLASH_SECTION_NUM FLASH_SECTION_30
#define FLASH_PAGE_NUM FLASH_PAGE_0
#define FLASH_MAGIC_NUMBER 0xAA55AA55
static page_state_t current_page = PAGE_MAIN_MENU;
static menu_item_t current_selection = MENU_MOTOR;
static motor_menu_item_t current_motor_selection = MOTOR_MENU_KP;
static servo_menu_item_t current_servo_selection = SERVO_MENU_KP;
static bool page_need_refresh = true;
static bool page_changed = false;
typedef struct
{
uint8_t digit1;
uint8_t digit2;
uint8_t digit3;
uint8_t digit4;
uint8_t digit5;
}
param_value_t;
typedef struct
{
uint32_t magic;
param_value_t kp_value;
param_value_t ki_value;
param_value_t kd_value;
param_value_t servo_kp_value;
param_value_t servo_kd_value;
}
flash_data_t;
static param_value_t kp_value = {0, 0, 0, 0, 0};
static param_value_t ki_value = {0, 0, 0, 0, 0};
static param_value_t kd_value = {0, 0, 0, 0, 0};
static param_value_t servo_kp_value = {0, 0, 0, 0, 0};
static param_value_t servo_kd_value = {0, 0, 0, 0, 0};
static bool editing_mode = false;
static param_value_t* current_editing_param = NULL;
static uint8_t current_digit = 0;
void display_main_menu(void);
void display_motor_menu(void);
void display_servo_menu(void);
void handle_key_input(void);
float param_to_float(param_value_t* param);
void float_to_param(float value, param_value_t* param);
void show_digit(uint16_t x, uint16_t y, uint8_t digit);
void show_param_value(uint16_t x, uint16_t y, param_value_t* param, bool is_editing);
void show_editing_param_value(uint16_t x, uint16_t y, param_value_t* param, uint8_t current_digit);
void save_parameters_to_flash(void);
void load_parameters_from_flash(void);
int main(void)
{
board_init(true);
lcd_init();
gpio_init(KEY_UP_PIN, GPI, GPIO_LOW, GPI_PULL_UP);
gpio_init(KEY_DOWN_PIN, GPI, GPIO_LOW, GPI_PULL_UP);
gpio_init(KEY_OK_PIN, GPI, GPIO_LOW, GPI_PULL_UP);
gpio_init(KEY_LEFT_PIN, GPI, GPIO_LOW, GPI_PULL_UP);
gpio_init(KEY_RIGHT_PIN, GPI, GPIO_LOW, GPI_PULL_UP);
load_parameters_from_flash();
while(1)
{
if(page_need_refresh)
{
switch(current_page)
{
case PAGE_MAIN_MENU:
display_main_menu();
break;
case PAGE_MOTOR_MENU:
display_motor_menu();
break;
case PAGE_SERVO_MENU:
display_servo_menu();
break;
}
page_need_refresh = false;
page_changed = true;
systick_delay_ms(100);
}
handle_key_input();
}
}
float param_to_float(param_value_t* param)
{
return param->digit1 * 100.0 + param->digit2 * 10.0 + param->digit3 * 1.0 +
param->digit4 * 0.1 + param->digit5 * 0.01;
}
void float_to_param(float value, param_value_t* param)
{
if(value < 0) value = 0;
if(value > 100.0) value = 100.0;
int int_part = (int)value;
int frac_part = (int)((value - int_part) * 100 + 0.5);
param->digit1 = int_part / 100;
param->digit2 = (int_part % 100) / 10;
param->digit3 = int_part % 10;
param->digit4 = frac_part / 10;
param->digit5 = frac_part % 10;
if(param->digit1 == 1)
{
param->digit2 = 0;
param->digit3 = 0;
param->digit4 = 0;
param->digit5 = 0;
}
}
void show_digit(uint16_t x, uint16_t y, uint8_t digit)
{
char str[2];
str[0] = '0' + digit;
str[1] = '\0';
lcd_showstr(x, y, str);
}
void show_param_value(uint16_t x, uint16_t y, param_value_t* param, bool is_editing)
{
if (param->digit1 == 1) {
show_digit(x, y, 1);
show_digit(x + 11, y, 0);
show_digit(x + 22, y, 0);
lcd_showstr(x + 33, y, ".");
show_digit(x + 44, y, 0);
show_digit(x + 55, y, 0);
}
else if (param->digit1 == 0 && (param->digit2 != 0 || param->digit3 != 0 || param->digit4 != 0 || param->digit5 != 0))
{
show_digit(x, y, param->digit2);
show_digit(x + 11, y, param->digit3);
lcd_showstr(x + 22, y, ".");
show_digit(x + 33, y, param->digit4);
show_digit(x + 44, y, param->digit5);
}
else if (param->digit1 == 0 && param->digit2 == 0 && param->digit3 == 0)
{
show_digit(x, y, 0);
show_digit(x + 11, y, 0);
lcd_showstr(x + 22, y, ".");
show_digit(x + 33, y, param->digit4);
show_digit(x + 44, y, param->digit5);
}
else
{
show_digit(x, y, param->digit1);
show_digit(x + 11, y, param->digit2);
show_digit(x + 22, y, param->digit3);
lcd_showstr(x + 33, y, ".");
show_digit(x + 44, y, param->digit4);
show_digit(x + 55, y, param->digit5);
}
}
void show_editing_param_value(uint16_t x, uint16_t y, param_value_t* param, uint8_t current_digit)
{
uint16_t base_x = x;
if(param->digit1 == 1)
{
if(current_digit == 0)
{
lcd_showstr(base_x, y, "[");
show_digit(base_x + 6, y, 1);
lcd_showstr(base_x + 12, y, "]");
}
else
{
show_digit(base_x + 6, y, 1);
}
show_digit(base_x + 19, y, 0);
show_digit(base_x + 26, y, 0);
lcd_showstr(base_x + 33, y, ".");
show_digit(base_x + 39, y, 0);
show_digit(base_x + 46, y, 0);
}
else
{
if(current_digit == 0)
{
lcd_showstr(base_x, y, "[");
show_digit(base_x + 6, y, param->digit1);
lcd_showstr(base_x + 13, y, "]");
show_digit(base_x + 19, y, param->digit2);
show_digit(base_x + 26, y, param->digit3);
lcd_showstr(base_x+33, y, ".");
show_digit(base_x + 39, y, param->digit4);
show_digit(base_x + 46, y, param->digit5);
}
else if(current_digit == 1)
{
lcd_showstr(base_x + 7, y, "[");
show_digit(base_x + 13, y, param->digit2);
lcd_showstr(base_x + 20, y, "]");
show_digit(base_x, y, param->digit1);
show_digit(base_x + 26, y, param->digit3);
lcd_showstr(base_x + 33, y, ".");
show_digit(base_x + 40, y, param->digit4);
show_digit(base_x + 47, y, param->digit5);
}
if(current_digit == 2)
{
lcd_showstr(base_x + 14, y, "[");
show_digit(base_x + 20, y, param->digit3);
lcd_showstr(base_x + 27, y, "]");
show_digit(base_x, y, param->digit1);
show_digit(base_x + 7, y, param->digit2);
lcd_showstr(base_x +34, y, ".");
show_digit(base_x + 40, y, param->digit4);
show_digit(base_x + 47, y, param->digit5);
}
if(current_digit == 3)
{
lcd_showstr(base_x + 27, y, "[");
show_digit(base_x + 34, y, param->digit4);
lcd_showstr(base_x + 41, y, "]");
show_digit(base_x, y, param->digit1);
show_digit(base_x + 7, y, param->digit2);
show_digit(base_x + 14, y, param->digit3);
lcd_showstr(base_x +21, y, ".");
show_digit(base_x + 48, y, param->digit5);
}
if(current_digit == 4)
{
lcd_showstr(base_x + 34, y, "[");
show_digit(base_x + 40, y, param->digit5);
lcd_showstr(base_x + 47, y, "]");
show_digit(base_x, y, param->digit1);
show_digit(base_x + 7, y, param->digit2);
show_digit(base_x + 14, y, param->digit3);
lcd_showstr(base_x +21, y, ".");
show_digit(base_x + 27, y, param->digit4);
}
}
}
void save_parameters_to_flash(void)
{
flash_data_t flash_data;
flash_data.magic = FLASH_MAGIC_NUMBER;
flash_data.kp_value = kp_value;
flash_data.ki_value = ki_value;
flash_data.kd_value = kd_value;
flash_data.servo_kp_value = servo_kp_value;
flash_data.servo_kd_value = servo_kd_value;
if(flash_erase_page(FLASH_SECTION_NUM, FLASH_PAGE_NUM) == 0)
{
flash_page_program(FLASH_SECTION_NUM, FLASH_PAGE_NUM, (uint32*)&flash_data, sizeof(flash_data)/4);
}
}
void load_parameters_from_flash(void)
{
flash_data_t flash_data;
flash_page_read(FLASH_SECTION_NUM, FLASH_PAGE_NUM, (uint32*)&flash_data, sizeof(flash_data)/4);
if(flash_data.magic == FLASH_MAGIC_NUMBER)
{
kp_value = flash_data.kp_value;
ki_value = flash_data.ki_value;
kd_value = flash_data.kd_value;
servo_kp_value = flash_data.servo_kp_value;
servo_kd_value = flash_data.servo_kd_value;
}
}
void display_main_menu(void)
{
lcd_clear(WHITE);
lcd_showstr(0, 32, "Menu");
if(current_selection == MENU_MOTOR)
{
lcd_showstr(0, 17, "> Motor");
lcd_showstr(0, 2, " Servo");
}
else
{
lcd_showstr(0, 17, " Motor");
lcd_showstr(0, 2, "> Servo");
}
}
void display_motor_menu(void)
{
lcd_clear(WHITE);
if(current_motor_selection == MOTOR_MENU_KP)
{
lcd_showstr(0, 32, "> P:");
if(editing_mode && current_editing_param == &kp_value)
{
show_editing_param_value(30, 32, &kp_value, current_digit);
}
else
{
show_param_value(30, 32, &kp_value, editing_mode && current_editing_param == &kp_value);
}
}
else
{
lcd_showstr(0,32, " P:");
show_param_value(30, 32, &kp_value, false);
}
if(current_motor_selection == MOTOR_MENU_KI)
{
lcd_showstr(0, 17, "> I:");
if(editing_mode && current_editing_param == &ki_value)
{
show_editing_param_value(30, 17, &ki_value, current_digit);
}
else
{
show_param_value(30, 17, &ki_value, editing_mode && current_editing_param == &ki_value);
}
}
else
{
lcd_showstr(0, 17, " I:");
show_param_value(30, 17, &ki_value, false);
}
if(current_motor_selection == MOTOR_MENU_KD)
{
lcd_showstr(0, 2, "> D:");
if(editing_mode && current_editing_param == &kd_value)
{
show_editing_param_value(30, 2, &kd_value, current_digit);
}
else
{
show_param_value(30, 2, &kd_value, editing_mode && current_editing_param == &kd_value);
}
}
else
{
lcd_showstr(0, 2, " D:");
show_param_value(30, 2, &kd_value, false);
}
if(current_motor_selection == MOTOR_MENU_EXIT)
{
lcd_showstr(0, 19, "> Exit");
}
else
{
lcd_showstr(0, 19, " Exit");
}
}
void display_servo_menu(void)
{
lcd_clear(WHITE);
if(current_servo_selection == SERVO_MENU_KP)
{
lcd_showstr(0, 32, "> P:");
if(editing_mode && current_editing_param == &servo_kp_value)
{
show_editing_param_value(30, 32, &servo_kp_value, current_digit);
}
else
{
show_param_value(30, 32, &servo_kp_value, editing_mode && current_editing_param == &servo_kp_value);
}
}
else
{
lcd_showstr(0, 32, " P:");
show_param_value(30, 32, &servo_kp_value, false);
}
if(current_servo_selection == SERVO_MENU_KD)
{
lcd_showstr(0, 17, "> D:");
if(editing_mode && current_editing_param == &servo_kd_value)
{
show_editing_param_value(30, 17, &servo_kd_value, current_digit);
}
else
{
show_param_value(30, 17, &servo_kd_value, editing_mode && current_editing_param == &servo_kd_value);
}
}
else
{
lcd_showstr(0, 17, " D:");
show_param_value(30, 17, &servo_kd_value, false);
}
if(current_servo_selection == SERVO_MENU_EXIT)
{
lcd_showstr(0, 2, "> Exit");
}
else
{
lcd_showstr(0, 2, " Exit");
}
}
void handle_key_input(void)
{
static bool last_up_state = 1;
static bool last_down_state = 1;
static bool last_ok_state = 1;
static bool last_left_state = 1;
static bool last_right_state = 1;
bool current_up_state = gpio_get(KEY_UP_PIN);
bool current_down_state = gpio_get(KEY_DOWN_PIN);
bool current_ok_state = gpio_get(KEY_OK_PIN);
bool current_left_state = gpio_get(KEY_LEFT_PIN);
bool current_right_state = gpio_get(KEY_RIGHT_PIN);
if(page_changed)
{
last_up_state = current_up_state;
last_down_state = current_down_state;
last_ok_state = current_ok_state;
last_left_state = current_left_state;
last_right_state = current_right_state;
page_changed = false;
return;
}
if(current_page == PAGE_MAIN_MENU)
{
if(last_up_state && !current_up_state)
{
if(current_selection != MENU_MOTOR)
{
current_selection = MENU_MOTOR;
page_need_refresh = true;
}
systick_delay_ms(200);
}
if(last_down_state && !current_down_state)
{
if(current_selection != MENU_SERVO)
{
current_selection = MENU_SERVO;
page_need_refresh = true;
}
systick_delay_ms(200);
}
if(last_ok_state && !current_ok_state)
{
if(current_selection == MENU_MOTOR)
{
current_page = PAGE_MOTOR_MENU;
current_motor_selection = MOTOR_MENU_KP;
page_need_refresh = true;
}
else if(current_selection == MENU_SERVO)
{
current_page = PAGE_SERVO_MENU;
current_servo_selection = SERVO_MENU_KP;
page_need_refresh = true;
}
systick_delay_ms(200);
}
}
else if(current_page == PAGE_MOTOR_MENU)
{
if(editing_mode)
{
if(last_up_state && !current_up_state)
{
if(current_editing_param->digit1 == 1 && current_digit > 0)
{
}
else {
uint8_t* digit_ptr = NULL;
uint8_t max_digit = 9;
switch(current_digit)
{
case 0:
digit_ptr = ¤t_editing_param->digit1;
max_digit = 1;
break;
case 1: digit_ptr = ¤t_editing_param->digit2; break;
case 2: digit_ptr = ¤t_editing_param->digit3; break;
case 3: digit_ptr = ¤t_editing_param->digit4; break;
case 4: digit_ptr = ¤t_editing_param->digit5; break;
}
if(digit_ptr != NULL)
{
(*digit_ptr)++;
if(*digit_ptr > max_digit) *digit_ptr = 0;
if(current_digit == 0 && *digit_ptr == 1)
{
current_editing_param->digit2 = 0;
current_editing_param->digit3 = 0;
current_editing_param->digit4 = 0;
current_editing_param->digit5 = 0;
}
page_need_refresh = true;
}
}
systick_delay_ms(200);
}
if(last_down_state && !current_down_state)
{
if(current_editing_param->digit1 == 1 && current_digit > 0)
{
}
else {
uint8_t* digit_ptr = NULL;
uint8_t max_digit = 9;
switch(current_digit)
{
case 0:
digit_ptr = ¤t_editing_param->digit1;
max_digit = 1;
break;
case 1: digit_ptr = ¤t_editing_param->digit2; break;
case 2: digit_ptr = ¤t_editing_param->digit3; break;
case 3: digit_ptr = ¤t_editing_param->digit4; break;
case 4: digit_ptr = ¤t_editing_param->digit5; break;
}
if(digit_ptr != NULL)
{
if(*digit_ptr == 0)
*digit_ptr = max_digit;
else
(*digit_ptr)--;
if(current_digit == 0 && *digit_ptr == 0)
{
}
page_need_refresh = true;
}
}
systick_delay_ms(200);
}
if(last_right_state && !current_right_state)
{
if(current_digit < 4)
{
if(!(current_editing_param->digit1 == 1))
{
current_digit++;
page_need_refresh = true;
}
}
systick_delay_ms(200);
}
if(last_left_state && !current_left_state)
{
if(current_digit > 0)
{
if(!(current_editing_param->digit1 == 1))
{
current_digit--;
page_need_refresh = true;
}
}
systick_delay_ms(200);
}
if(last_ok_state && !current_ok_state)
{
editing_mode = false;
save_parameters_to_flash();
current_editing_param = NULL;
page_need_refresh = true;
systick_delay_ms(200);
}
}
else
{
if(last_up_state && !current_up_state)
{
if(current_motor_selection > MOTOR_MENU_KP)
{
current_motor_selection--;
page_need_refresh = true;
}
systick_delay_ms(200);
}
if(last_down_state && !current_down_state)
{
if(current_motor_selection < MOTOR_MENU_EXIT)
{
current_motor_selection++;
page_need_refresh = true;
}
systick_delay_ms(200);
}
if(last_ok_state && !current_ok_state)
{
if(current_motor_selection == MOTOR_MENU_EXIT)
{
current_page = PAGE_MAIN_MENU;
page_need_refresh = true;
}
else
{
editing_mode = true;
current_digit = 0;
switch(current_motor_selection)
{
case MOTOR_MENU_KP:
current_editing_param = &kp_value;
break;
case MOTOR_MENU_KI:
current_editing_param = &ki_value;
break;
case MOTOR_MENU_KD:
current_editing_param = &kd_value;
break;
}
page_need_refresh = true;
}
systick_delay_ms(200);
}
if(last_left_state && !current_left_state)
{
current_page = PAGE_MAIN_MENU;
page_need_refresh = true;
systick_delay_ms(200);
}
}
}
else if(current_page == PAGE_SERVO_MENU)
{
if(editing_mode)
{
if(last_up_state && !current_up_state)
{
if(current_editing_param->digit1 == 1 && current_digit > 0)
{
}
else {
uint8_t* digit_ptr = NULL;
uint8_t max_digit = 9;
switch(current_digit)
{
case 0:
digit_ptr = ¤t_editing_param->digit1;
max_digit = 1;
break;
case 1: digit_ptr = ¤t_editing_param->digit2; break;
case 2: digit_ptr = ¤t_editing_param->digit3; break;
case 3: digit_ptr = ¤t_editing_param->digit4; break;
case 4: digit_ptr = ¤t_editing_param->digit5; break;
}
if(digit_ptr != NULL)
{
(*digit_ptr)++;
if(*digit_ptr > max_digit) *digit_ptr = 0;
if(current_digit == 0 && *digit_ptr == 1)
{
current_editing_param->digit2 = 0;
current_editing_param->digit3 = 0;
current_editing_param->digit4 = 0;
current_editing_param->digit5 = 0;
}
page_need_refresh = true;
}
}
systick_delay_ms(200);
}
if(last_down_state && !current_down_state)
{
if(current_editing_param->digit1 == 1 && current_digit > 0)
{
}
else {
uint8_t* digit_ptr = NULL;
uint8_t max_digit = 9;
switch(current_digit)
{
case 0:
digit_ptr = ¤t_editing_param->digit1;
max_digit = 1;
break;
case 1: digit_ptr = ¤t_editing_param->digit2; break;
case 2: digit_ptr = ¤t_editing_param->digit3; break;
case 3: digit_ptr = ¤t_editing_param->digit4; break;
case 4: digit_ptr = ¤t_editing_param->digit5; break;
}
if(digit_ptr != NULL)
{
if(*digit_ptr == 0)
*digit_ptr = max_digit;
else
(*digit_ptr)--;
if(current_digit == 0 && *digit_ptr == 0)
{
}
page_need_refresh = true;
}
}
systick_delay_ms(200);
}
if(last_right_state && !current_right_state)
{
if(current_digit < 4)
{
if(!(current_editing_param->digit1 == 1))
{
current_digit++;
page_need_refresh = true;
}
}
systick_delay_ms(200);
}
if(last_left_state && !current_left_state)
{
if(current_digit > 0)
{
if(!(current_editing_param->digit1 == 1))
{
current_digit--;
page_need_refresh = true;
}
}
systick_delay_ms(200);
}
if(last_ok_state && !current_ok_state)
{
editing_mode = false;
save_parameters_to_flash();
current_editing_param = NULL;
page_need_refresh = true;
systick_delay_ms(200);
}
}
else
{
if(last_up_state && !current_up_state)
{
if(current_servo_selection > SERVO_MENU_KP)
{
current_servo_selection--;
page_need_refresh = true;
}
systick_delay_ms(200);
}
if(last_down_state && !current_down_state)
{
if(current_servo_selection < SERVO_MENU_EXIT)
{
current_servo_selection++;
page_need_refresh = true;
}
systick_delay_ms(200);
}
if(last_ok_state && !current_ok_state)
{
if(current_servo_selection == SERVO_MENU_EXIT)
{
current_page = PAGE_MAIN_MENU;
page_need_refresh = true;
}
else
{
editing_mode = true;
current_digit = 0;
switch(current_servo_selection)
{
case SERVO_MENU_KP:
current_editing_param = &servo_kp_value;
break;
case SERVO_MENU_KD:
current_editing_param = &servo_kd_value;
break;
}
page_need_refresh = true;
}
systick_delay_ms(200);
}
if(last_left_state && !current_left_state)
{
current_page = PAGE_MAIN_MENU;
page_need_refresh = true;
systick_delay_ms(200);
}
}
}
last_up_state = current_up_state;
last_down_state = current_down_state;
last_ok_state = current_ok_state;
last_left_state = current_left_state;
last_right_state = current_right_state;
} 在此基础上,检查有没有多余的代码删去
最新发布