#include "main.h" #include "tim.h" #include "dac.h" #include "st7565.h" #include "font_gfx.h" #include "bitmap_fonts.h" #include "bottom_button.h" #include "printf.h" #include "mcu_cs.h" #include "mcp41x.h" #include "ad9833.h" #define MAX_VOLT 330 typedef enum { FREQ, WAVE, ONOFF, GAIN, POT, REF, OFFS, ZERO, OPT_MAX } option_t; typedef enum { SIN, TRI, SQR } wave_t; st7565_handle_t hst7565; mcp41x_handle_t hmcp41; MCU_cs_t hmcp41_cs; ad9833_handle_t had9833; MCU_cs_t had9833_cs; GFX_display_t disp; uint32_t last_tick; option_t option; uint8_t on_off_s[2][4] = {"OFF", "ON"}; uint8_t wave_s[3][4] = {"SIN", "TRI", "SQR"}; uint32_t var[OPT_MAX]; void draw_string(void); void update_display(void); void encoderHandler(void); void changeValue(int8_t inc); void setup(void) { var[FREQ] = 1; var[POT] = 255; var[REF] = 197; var[ONOFF] = 1; hst7565.hspi = &hspi3; hst7565.cs_port = ST7565_CS_GPIO_Port; hst7565.cs_pin = ST7565_CS_Pin; hst7565.a0_port = ST7565_A0_GPIO_Port; hst7565.a0_pin = ST7565_A0_Pin; hst7565.rst_port = ST7565_RST_GPIO_Port; hst7565.rst_pin = ST7565_RST_Pin; ST7565_Init(&hst7565, &disp); mcu_cs_init(&hmcp41_cs, AMP1_CS_GPIO_Port, AMP1_CS_Pin, GPIO_PIN_SET); mcp41x_init(&hmcp41, &hspi2, &hmcp41_cs.super, MCP41X_10K); mcu_cs_init(&had9833_cs, DDS1_CS_GPIO_Port, DDS1_CS_Pin, GPIO_PIN_SET); ad9833_init(&had9833, &hspi2, &had9833_cs.super); bottomButtonInit(); DISP_clearScreen(&disp); DISP_writeString(&disp, &font5x7Info, (uint8_t *)"FUN GEN TEST", 24, 24, BM_NORMAL); ST7565_DisplayAll(&hst7565); HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL); HAL_DAC_Start(&hdac1, DAC1_CHANNEL_1); for (option_t opt = 0; opt < OPT_MAX; opt++) { option = opt; changeValue(0); } HAL_Delay(1000); DISP_clearScreen(&disp); draw_string(); last_tick = HAL_GetTick(); } void loop(void) { bottomButtonsHandler(); encoderHandler(); if (HAL_GetTick() - last_tick > 100) { last_tick = HAL_GetTick(); ST7565_DisplayAll(&hst7565); update_display(); } } void draw_string(void) { // frequenncy DISP_writeString(&disp, &font5x7Info, (uint8_t *)"FREQ:", 8, 0, BM_NORMAL); // wave type DISP_writeString(&disp, &font5x7Info, (uint8_t *)"WAVE:", 8, 8, BM_NORMAL); // dds on off DISP_writeString(&disp, &font5x7Info, (uint8_t *)"DDS:", 8, 16, BM_NORMAL); // gain switch DISP_writeString(&disp, &font5x7Info, (uint8_t *)"GAIN:", 8, 24, BM_NORMAL); // potentiometr DISP_writeString(&disp, &font5x7Info, (uint8_t *)"POT:", 8, 32, BM_NORMAL); // reference voltage DISP_writeString(&disp, &font5x7Info, (uint8_t *)"REF:", 8, 40, BM_NORMAL); // dac1 - offset DISP_writeString(&disp, &font5x7Info, (uint8_t *)"OFFS:", 8, 48, BM_NORMAL); // dac2 - zeroing DISP_writeString(&disp, &font5x7Info, (uint8_t *)"ZERO:", 8, 56, BM_NORMAL); for (option_t opt = FREQ; opt < OPT_MAX; opt++) { option = opt; update_display(); } option = OFFS; } void update_display(void) { uint8_t data[16]; uint32_t temp; DISP_clearRegion(&disp, 0, 0, 8, 64); switch (option) { case FREQ: snprintf((char *)data, 8, "%04uk", var[FREQ]); DISP_writeString(&disp, &font5x7Info, data, 48, 0, BM_NORMAL); DISP_writeString(&disp, &font5x7Info, (uint8_t *)"*", 0, 0, BM_NORMAL); break; case WAVE: DISP_writeString(&disp, &font5x7Info, wave_s[var[WAVE]], 48, 8, BM_NORMAL); DISP_writeString(&disp, &font5x7Info, (uint8_t *)"*", 0, 8, BM_NORMAL); break; case ONOFF: DISP_clearRegion(&disp, 48, 16, 24, 8); DISP_writeString(&disp, &font5x7Info, on_off_s[var[ONOFF]], 48, 16, BM_NORMAL); DISP_writeString(&disp, &font5x7Info, (uint8_t *)"*", 0, 16, BM_NORMAL); break; case GAIN: DISP_clearRegion(&disp, 48, 24, 24, 8); DISP_writeString(&disp, &font5x7Info, on_off_s[var[GAIN]], 48, 24, BM_NORMAL); DISP_writeString(&disp, &font5x7Info, (uint8_t *)"*", 0, 24, BM_NORMAL); break; case POT: snprintf((char *)data, 8, "%03u", var[POT]); DISP_writeString(&disp, &font5x7Info, data, 48, 32, BM_NORMAL); DISP_writeString(&disp, &font5x7Info, (uint8_t *)"*", 0, 32, BM_NORMAL); break; case REF: temp = (MAX_VOLT * var[REF] + 127) / UINT8_MAX; snprintf((char *)data, 16, "%03u (%01d.%02d)", var[REF], temp / 100, temp % 100); DISP_writeString(&disp, &font5x7Info, data, 48, 40, BM_NORMAL); DISP_writeString(&disp, &font5x7Info, (uint8_t *)"*", 0, 40, BM_NORMAL); break; case OFFS: snprintf((char *)data, 8, "%03u", var[OFFS]); DISP_writeString(&disp, &font5x7Info, data, 48, 48, BM_NORMAL); DISP_writeString(&disp, &font5x7Info, (uint8_t *)"*", 0, 48, BM_NORMAL); break; case ZERO: snprintf((char *)data, 8, "%03u", var[ZERO]); DISP_writeString(&disp, &font5x7Info, data, 48, 56, BM_NORMAL); DISP_writeString(&disp, &font5x7Info, (uint8_t *)"*", 0, 56, BM_NORMAL); break; default: break; } } void pushedDispBtnEvent(ButtonKey_t *key) { switch (key->instance) { case BTN_BOT_1: option = (option - 1) & (OPT_MAX - 1); break; case BTN_BOT_2: option = (option + 1) & (OPT_MAX - 1); break; default: break; } } void changeValue(int8_t inc) { inc = inc / 2; switch (option) { case FREQ: { if ((var[FREQ] <= 1 && inc < 0) || (var[FREQ] >= 1000 && inc > 0)) { break; } var[FREQ] += inc; ad9833_setFrequency(&had9833, CHAN_0, var[FREQ]); break; } case WAVE: { if (inc > 0 && var[WAVE] == 2) { var[WAVE] = 0; } else if (inc < 0 && var[WAVE] == 0) { var[WAVE] = 2; } else { var[WAVE] += inc; } switch (var[WAVE]) { case SIN: ad9833_setMode(&had9833, MODE_SINE); break; case TRI: ad9833_setMode(&had9833, MODE_TRIANGLE); break; case SQR: ad9833_setMode(&had9833, MODE_SQUARE1); break; default: break; } break; } case ONOFF: { var[ONOFF] ^= 1; if (var[ONOFF]) { HAL_GPIO_WritePin(LED_CH1_GPIO_Port, LED_CH1_Pin, GPIO_PIN_RESET); switch (var[WAVE]) { case SIN: ad9833_setMode(&had9833, MODE_SINE); break; case TRI: ad9833_setMode(&had9833, MODE_TRIANGLE); break; case SQR: ad9833_setMode(&had9833, MODE_SQUARE1); break; default: break; } } else { HAL_GPIO_WritePin(LED_CH1_GPIO_Port, LED_CH1_Pin, GPIO_PIN_SET); ad9833_setMode(&had9833, MODE_OFF); } break; } case GAIN: { var[GAIN] ^= 1; if (var[GAIN]) { HAL_GPIO_WritePin(GAIN1_GPIO_Port, GAIN1_Pin, GPIO_PIN_SET); } else { HAL_GPIO_WritePin(GAIN1_GPIO_Port, GAIN1_Pin, GPIO_PIN_RESET); } break; } case POT: { var[POT] = (var[POT] + inc) & UINT8_MAX; mcp41x_setValue(&hmcp41, var[POT]); break; } case REF: { var[REF] = (var[REF] + inc) & UINT8_MAX; HAL_DAC_SetValue(&hdac1, DAC1_CHANNEL_1, DAC_ALIGN_8B_R, var[REF]); break; } case OFFS: { var[OFFS] = (var[OFFS] + inc) & UINT8_MAX; break; } case ZERO: { var[ZERO] = (var[ZERO] + inc) & UINT8_MAX; break; } default: break; } } void encoderHandler(void) { static uint8_t cnt; if (htim3.Instance->CNT == cnt || htim3.Instance->CNT % 2 == 1) { return; } changeValue(htim3.Instance->CNT - cnt); cnt = (uint8_t)htim3.Instance->CNT; }