diff --git a/Core/App/Graphic/monoimg.c b/Core/App/Graphic/monoimg.c index 39dc90c..c450c3e 100644 --- a/Core/App/Graphic/monoimg.c +++ b/Core/App/Graphic/monoimg.c @@ -40,6 +40,25 @@ void mimg_draw(mimg_FunctionSetPixel set_pixel, uint16_t x, uint16_t y, uint16_t } } +void mimg_draw_with_bg(mimg_FunctionSetPixel set_pixel, uint16_t x, uint16_t y, uint16_t color, uint16_t bg_color, const uint8_t *img, mimg_Area area) { + uint8_t width_s1 = img[0]; // width - 1 + uint8_t height_s1 = img[1]; // height - 1 + uint8_t ix = min(area.x, width_s1); + uint8_t iy = min(area.y, height_s1); + uint8_t iw = min(area.w, width_s1 - ix + 1); + uint8_t ih = min(area.h, height_s1 - iy + 1); + uint8_t off_x, off_y; + for (off_y = 0; off_y < ih; off_y ++) { + for (off_x = 0; off_x < iw; off_x ++) { + if (mimg_get_pixel_unsafe(img, ix + off_x, iy + off_y)) { + set_pixel(x + off_x, y + off_y, color); + } else { + set_pixel(x + off_x, y + off_y, bg_color); + } + } + } +} + mimg_Area mimg_get_tile_area(const uint8_t *img, uint8_t cols, uint8_t rows, uint8_t index) { uint8_t width = img[0] + 1; uint8_t height = img[1] + 1; diff --git a/Core/App/Graphic/monoimg.h b/Core/App/Graphic/monoimg.h index 5d5285d..0754bc2 100644 --- a/Core/App/Graphic/monoimg.h +++ b/Core/App/Graphic/monoimg.h @@ -15,5 +15,6 @@ typedef struct mimg_Area uint8_t mimg_get_pixel(const uint8_t *img, uint16_t x, uint16_t y); /** draw a part of img {ix, iy, iw, ih} , at (x, y) with color */ void mimg_draw(mimg_FunctionSetPixel set_pixel, uint16_t x, uint16_t y, uint16_t color, const uint8_t *img, mimg_Area area); +void mimg_draw_with_bg(mimg_FunctionSetPixel set_pixel, uint16_t x, uint16_t y, uint16_t color, uint16_t bg_color, const uint8_t *img, mimg_Area area); /** calc tile area */ mimg_Area mimg_get_tile_area(const uint8_t *img, uint8_t cols, uint8_t rows, uint8_t index); diff --git a/Core/App/Graphic/ui.c b/Core/App/Graphic/ui.c index aaf02e2..192de42 100644 --- a/Core/App/Graphic/ui.c +++ b/Core/App/Graphic/ui.c @@ -30,6 +30,30 @@ void ui_text_number18x32(uint32_t num, uint16_t x, uint16_t y, uint16_t color) { } } +void ui_text_number18x32_with_bg(uint32_t num, uint16_t x, uint16_t y, uint16_t color, uint16_t bg_color) { + uint32_t tmp = num; + uint32_t div = 1; + uint8_t num_count = 0; + while (tmp > 0) { + tmp = tmp / 10; + num_count ++; + div = div * 10; + } + div = div / 10; + if (div == 0) { + mimg_Area area = mimg_get_tile_area(IMG_DIGI_18_32, 10, 1, 0); + mimg_draw_with_bg(ST7735_DrawPixel, x, y, color, bg_color, IMG_DIGI_18_32, area); + } else { + while (div > 0) { + tmp = (num / div) % 10; + mimg_Area area = mimg_get_tile_area(IMG_DIGI_18_32, 10, 1, tmp); + mimg_draw_with_bg(ST7735_DrawPixel, x, y, color, bg_color, IMG_DIGI_18_32, area); + x = x + 18; + div = div / 10; + } + } +} + // TODO: 绘制界面的函数 /* UI元素 */ void ui_com_main_border() { @@ -42,20 +66,84 @@ void ui_com_main_border() { ST7735_FillRectangle(ST7735_WIDTH - 1, 0, 1, ST7735_HEIGHT, ST7735_YELLOW); } -void ui_com_freq_digital(uint8_t clear) { - // 5位数字, 即高32,宽90 - uint16_t off_x = (ST7735_WIDTH - 90) / 2; - uint16_t off_y = (ST7735_HEIGHT - 32 - 34 - 18) / 2 + 17; +void ui_com_title_bar(uint8_t clear, uint8_t *text, uint32_t bytes_len) { if (clear) { - ST7735_FillRectangle(off_x, off_y, 32, 90, ST7735_BLACK); + ST7735_FillRectangle(1, 1, ST7735_WIDTH - 2, 16, ST7735_BLACK); } - uint16_t scale = 10000; - uint32_t tmp = 0; - while (scale > 0) { - tmp = (global_data.freq / scale) % 10; - ui_text_number18x32(tmp, off_x, off_y, ST7735_COLOR565(0xFF, 0x7F, 0)); - off_x += 18; - scale /= 10; + uint16_t off_x = (ST7735_WIDTH - 2 - bmf_get_text_width(font_unifont_16x16, text, bytes_len)) / 2 + 1; + bmf_draw_text(font_unifont_16x16, text, bytes_len, off_x, 1, ST7735_WIDTH - 2, 16, ST7735_YELLOW); +} + +void ui_com_freq_digital(uint8_t clear) { + // 5位数字, 即高32+2(小数点高度),宽90 + uint16_t off_x = (ST7735_WIDTH - 90) / 2; + uint16_t off_y = (ST7735_HEIGHT - 34 - 34 - 18) / 2 + 17; + if (global_data.rf_mode == G_RF_MODE_AM) { + uint16_t scale = 10000; + uint32_t tmp = 0; + if (clear) { + ST7735_FillRectangle(off_x, off_y+32, 90, 2, ST7735_BLACK); // 清除小数点 + } + while (scale > 0) { + if (clear) { + ui_text_number18x32_with_bg(tmp, off_x, off_y, ST7735_COLOR565(0xFF, 0x7F, 0), ST7735_BLACK); + } else { + ui_text_number18x32(tmp, off_x, off_y, ST7735_COLOR565(0xFF, 0x7F, 0)); + } + off_x += 18; + scale /= 10; + } + } else { + uint16_t fm_freq = global_data.freq / 20; + uint8_t fm_freq_float = (global_data.freq % 20) * 5; + uint16_t scale = 100; + uint16_t tmp = 0; + if (clear) { + ST7735_FillRectangle(off_x, off_y + 32, 18 * 3 - 1, 2, ST7735_BLACK); // 清除小数点 + ST7735_FillRectangle(off_x + (18 * 3) + 1, off_y + 32, 18 * 2 - 1, 2, ST7735_BLACK); // 清除小数点 + } + while (scale > 0) { + tmp = (fm_freq / scale) % 10; + if (clear) { + ui_text_number18x32_with_bg(tmp, off_x, off_y, ST7735_COLOR565(0xFF, 0x7F, 0), ST7735_BLACK); + } else { + ui_text_number18x32(tmp, off_x, off_y, ST7735_COLOR565(0xFF, 0x7F, 0)); + } + off_x += 18; + scale /= 10; + } + scale = 10; + while (scale > 0) { + tmp = (fm_freq_float / scale) % 10; + if (clear) { + ui_text_number18x32_with_bg(tmp, off_x, off_y, ST7735_COLOR565(0xFF, 0x7F, 0), ST7735_BLACK); + } else { + ui_text_number18x32(tmp, off_x, off_y, ST7735_COLOR565(0xFF, 0x7F, 0)); + } + off_x += 18; + scale /= 10; + } + } +} + +void ui_com_fm_am(uint8_t clear) { + uint16_t area_w = (ST7735_WIDTH - 90) / 2 - 1; + uint16_t off_x = 1; + uint16_t off_y = 34 + 32; + if (clear) { + ST7735_FillRectangle(off_x, off_y, area_w, 16, ST7735_BLACK); + ST7735_FillRectangle(ST7735_WIDTH - area_w - 1 - 1, off_y, area_w, 16, ST7735_BLACK); + } + if (global_data.rf_mode == G_RF_MODE_AM) { + off_x = (area_w - bmf_get_text_width(font_unifont_16x16, u8str("AM"), 2)) / 2; + bmf_draw_text(font_unifont_16x16, u8str("AM"), 2, off_x, off_y, area_w, 16, ST7735_YELLOW); + off_x = ST7735_WIDTH - area_w - 1 + (area_w - bmf_get_text_width(font_unifont_16x16, u8str("KHz"), 3)) / 2; + bmf_draw_text(font_unifont_16x16, u8str("KHz"), 3, off_x, off_y, area_w, 16, ST7735_BLUE); + } else { + off_x = (area_w - bmf_get_text_width(font_unifont_16x16, u8str("FM"), 2)) / 2; + bmf_draw_text(font_unifont_16x16, u8str("FM"), 2, off_x, off_y, area_w, 16, ST7735_GREEN); + off_x = ST7735_WIDTH - area_w - 1 + (area_w - bmf_get_text_width(font_unifont_16x16, u8str("MHz"), 3)) / 2; + bmf_draw_text(font_unifont_16x16, u8str("MHz"), 3, off_x, off_y, area_w, 16, ST7735_BLUE); } } @@ -110,6 +198,8 @@ void ui_com_sig_bar(uint8_t clear) { void ui_screen_main() { ST7735_FillScreen(ST7735_BLACK); ui_com_main_border(); + ui_com_title_bar(0, u8str("Radio"), 5); + ui_com_fm_am(0); ui_com_freq_digital(0); ui_com_vol_bar(0); ui_com_sig_bar(0); diff --git a/Core/App/Graphic/ui.h b/Core/App/Graphic/ui.h index e821fb5..8ff14f9 100644 --- a/Core/App/Graphic/ui.h +++ b/Core/App/Graphic/ui.h @@ -3,5 +3,10 @@ void ui_text_number18x32(uint32_t num, uint16_t x, uint16_t y, uint16_t color); +/* 绘制界面元素 */ +void ui_com_freq_digital(uint8_t clear); +void ui_com_fm_am(uint8_t clear); +void ui_com_vol_bar(uint8_t clear); +void ui_com_sig_bar(uint8_t clear); /* 绘制主界面 */ void ui_screen_main(); diff --git a/Core/App/app.c b/Core/App/app.c index 2e6827d..49fdc9e 100644 --- a/Core/App/app.c +++ b/Core/App/app.c @@ -1,6 +1,8 @@ +#include #include "gpio.h" #include "ui.h" #include "keypad.h" +#include "global.h" void app_init() { // 程序开始时执行一次 @@ -9,19 +11,41 @@ void app_init() { printf("\n====start====\n"); } -#include "gpio.h" //test void app_main_loop() { // 反复被调用执行 - // HAL_GPIO_TogglePin(LED_STATUS_GPIO_Port,LED_STATUS_Pin); - // HAL_Delay(1000); uint8_t event = kp_query(); uint8_t event_type = kp_Type(event); uint8_t event_value = kp_Value(event); - // printf("Raw Event Value: %d\n", event); - if (event_type != kp_NOP) { + if (event_type == kp_ROTATE_RIGHT || event_type == kp_ROTATE_LEFT) { + // 调整频率 + if (event_type == kp_ROTATE_RIGHT) { + global_data.freq += event_value; + } else { + global_data.freq -= event_value; + } + uint16_t limit_min = (global_data.rf_mode == G_RF_MODE_AM) ? G_AM_FREQ_MIN : G_FM_FREQ_MIN; + uint16_t limit_max = (global_data.rf_mode == G_RF_MODE_AM) ? G_AM_FREQ_MAX : G_FM_FREQ_MAX; + if (global_data.freq < limit_min) { + global_data.freq = limit_min; + } else if (global_data.freq > limit_max) { + global_data.freq = limit_max; + } + printf("Freq: %d\n", global_data.freq); + ui_com_freq_digital(1); + } else if (event_type == kp_KEY_DOWN) { + if (event_value == kp_KEY1) { + // 切换FM和AM + if (global_data.rf_mode == G_RF_MODE_AM) { + global_data.rf_mode = G_RF_MODE_FM; + global_data.freq = G_FM_FREQ_MIN; + } else { + global_data.rf_mode = G_RF_MODE_AM; + global_data.freq = G_AM_FREQ_MIN; + } + ui_com_fm_am(1); + ui_com_freq_digital(1); + } + } else if (event_type != kp_NOP) { printf("event: %d, key: %d\n", event_type, event_value); } - - GPIO_PinState state = HAL_GPIO_ReadPin(ENCODER_KEY_GPIO_Port, ENCODER_KEY_Pin); - HAL_GPIO_WritePin(LED_STATUS_GPIO_Port, LED_STATUS_Pin, state); } diff --git a/Core/App/global.c b/Core/App/global.c index 637ca2a..d6fe198 100644 --- a/Core/App/global.c +++ b/Core/App/global.c @@ -2,7 +2,7 @@ #include "global.h" GlobalData global_data = { - 901 * 2, // freq + 880 * 2, // freq G_RF_MODE_FM, //rf_mode 16, // volumn 97 //signal diff --git a/Core/App/global.h b/Core/App/global.h index ecf0f43..3201c31 100644 --- a/Core/App/global.h +++ b/Core/App/global.h @@ -3,6 +3,10 @@ #include #define G_RF_MODE_FM 0x00 #define G_RF_MODE_AM 0x01 +#define G_FM_FREQ_MIN 880*2 +#define G_FM_FREQ_MAX 1080*2 +#define G_AM_FREQ_MIN 100 +#define G_AM_FREQ_MAX 33000 typedef struct GlobalData { uint16_t freq; // FM x50kHz AM x1kHz