|
- #include "stm8s.h"
- #include "led.h"
- #define LED_delay (1) // one digit emitting time
- #define ADC_delay (50) // delay for reading voltage
- #define Display_delay (400) // delay for displaying value
- uint32_t Global_time = 0L; // global time in ms
- uint32_t ADC_time = 0L;
- uint32_t Display_time = 0L;
- uint8_t waitforADC = 0;
- uint8_t ADC_started = 0;
- uint16_t ADC_values[3] = { 0, 0, 0 };
- uint8_t index = 0;
- uint8_t current_channel = 1; // 0: AIN3, 1: AIN4
- void simpleDelay(uint8_t how_much);
- uint16_t adc_read(void){ uint16_t temph = 0;
- uint8_t templ = 0;
- ADC1->CR1 |= ADC1_CR1_ADON; // wake it up
- ADC1->CR1 |= ADC1_CR1_ADON; // start the conversion, wait few ms
- simpleDelay(1);
- while (!(ADC1->CSR & ADC1_CSR_EOC)); // wait for conversion to finish
- /* Read LSB first */
- templ = ADC1->DRL;
- /* Then read MSB */
- temph = ADC1->DRH;
- temph = (uint16_t)(templ | (uint16_t)(temph << (uint8_t)8));
- ADC1->CR1 &= (uint8_t)(~ADC1_CR1_ADON);
- // power it off return (uint16_t)temph;}
- // store ADC value in a rolling array void store(uint16_t value){ ADC_values[index++] = value; // store value in array if (index == 3) index = 0; // check index overflow}
- // get median value uint16_t median(uint16_t value1, uint16_t value2, uint16_t value3) if ((value1 <= value2) && (value1 <= value3)) { return (value2 <= value3) ? value2 : value3; } else { if ((value2 <= value1) && (value2 <= value3)) { return (value1 <= value3) ? value1 : value3; } else { return (value1 <= value2) ? value1 : value2; } } }
- // calculate average value uint16_t average(uint16_t value1, uint16_t value2, uint16_t value3) { uint16_t value = 0; uint8_t count = 0;
- if (value1 > 0) { value += value1; count++; } if (value2 > 0) { value += value2; count++; } if (value3 > 0) { value += value3; count++; } if (count > 0) value /= count;
- return value; }
- // ADC initialization void ADC_init() { // Initialize ADC // Setup ADC on AIN6/PD6, AIN4/PD3, AIN3/PD2 GPIOD->DDR &= (uint8_t)(0b10110011); // Set PD2/3/6 as floating input GPIOD->CR1 &= (uint8_t)(0b10110011);
- ADC1->CR1 &= (uint8_t)(~ADC1_CR1_CONT); // Set single conversion mode ADC1->CR1 &= (uint8_t)(~ADC1_CR1_SPSEL); // Clear the SPSEL bits (prescaler) ADC1->CR1 |= 0x40; // Select the prescaler division factor
- ADC1->CR2 |= ADC1_CR2_ALIGN; // Configure right data alignment ADC1->CR2 &= (uint8_t)(~ADC1_CR2_EXTTRIG); // Disable external trigger ADC1->CR2 &= (uint8_t)(~ADC1_CR2_EXTSEL); // Clear external trigger selection bits ADC1->CR2 &= (uint8_t)(~ADC1_CR2_SCAN); // Disable scan mode
- ADC1->CSR = 0x06; // Select AIN6 as initial channel }
- void main() { uint32_t T_LED = 0L; // time of last digit update uint16_t ADC_value = 0; uint16_t value = 0, vref = 0, value1 = 0, value2 = 0, value3 = 0; uint8_t i, count = 0;
- ADC_init();
- // Setup Timer1 TIM1-> PSCRH = 0; TIM1-> PSCRL = 15; // LSB should be written last TIM1->ARRH = 0x03; // auto-reload each 1ms TIM1->ARRL = 0xE8; TIM1->IER = TIM1_IER_UIE; TIM1->CR1 = TIM1_CR1_ARPE | TIM1_CR1_URS | TIM1_CR1_CEN;
- // Configure clocking CLK->CKDIVR = 0; // F_HSI = 16MHz
- // Configure pins CFG->GCR |= 1; // disable SWIM
- LED_init(); set_display_buf("000");
- Button_init(); enableInterrupts();
- while (1) { if (((uint16_t)(Global_time - ADC_time) > ADC_delay) || (ADC_time > Global_time)) { ADC_time = Global_time;
- // read three values and get median value1 = adc_read(); value2 = adc_read(); value3 = adc_read(); vref = median(value1, value2, value3);
- if (current_channel) { ADC1->CSR = (ADC1->CSR & 0xF0) | 0x04; // select AIN4 GPIOA->ODR &= (uint8_t)(0b11111011); // light blue LED } else { ADC1->CSR = (ADC1->CSR & 0xF0) | 0x03; // select AIN3 GPIOA->ODR |= (uint8_t)(0x04); // light red LED }
- value1 = adc_read(); value2 = adc_read(); value3 = adc_read(); value = median(value1, value2, value3); store(value * (long)3120 / vref); // avoid uint16_t overflow ADC1->CSR = 0x06; // restore AIN6 as sampling channel }
- if ((uint16_t)(Global_time - Display_time) > Display_delay) { Display_time = Global_time; value = average(ADC_values[0], ADC_values[1], ADC_values[2]); display_int(value, 1); // allow auto decimal point }
- if (Display_time > Global_time) Display_time = Global_time; // reset Display_time when Global_time overflows
- if ((uint8_t)(Global_time - T_LED) > LED_delay) { T_LED = Global_time; show_next_digit(); }
- // used for non-blocking read if (ADC_started) { wait_ADC(); } if (waitforADC) { ADC_value = adc_read_end(); store(value * (long)100 * 3.3 / 1024); // store current voltage value waitforADC = 0; } } }
- // keep the processor busy for some time void simpleDelay(uint8_t how_much) { unsigned int i, j; for (i = 0; i < how_much; i++) { for (j = 0; j < 40; j++) { } } }
- // Timer1 Update/Overflow/Trigger/Break Interrupt INTERRUPT_HANDLER(TIM1_UPD_OVF_TRG_BRK_IRQHandler, 11) { if (TIM1->SR1 & TIM1_SR1_UIF) // update interrupt { Global_time++; // increase timer } TIM1->SR1 = 0; // clear all interrupt flags }
- INTERRUPT_HANDLER(EXTI_PORTA_IRQHandler, 3) { if ((GPIOA->IDR & 0x08) == 0) { // delay 2ms for debounce unsigned int i, j; for (i = 0; i < 50; i++) { for (j = 0; j < 40; j++) {} }
- // release detection while ((GPIOA->IDR & 0x08) == 0) {}
- // toggle ADC channel current_channel = !current_channel; } }
複製代碼
- int main(void)
- {
- /* USER CODE BEGIN 1 */
- /* USER CODE END 1 */
- /* MCU Configuration--------------------------------------------------------*/
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
- HAL_Init();
- /* USER CODE BEGIN Init */
- /* USER CODE END Init */
- /* Configure the system clock */
- SystemClock_Config();
- /* USER CODE BEGIN SysInit */
- /* USER CODE END SysInit */
- /* Initialize all configured peripherals */
- MX_GPIO_Init();
- MX_SPI1_Init();
- MX_SPI2_Init();
- MX_USART1_UART_Init();
- MX_USB_DEVICE_Init();
- MX_TIM2_Init();
- MX_I2C1_Init();
- /* USER CODE BEGIN 2 */
- ST7735_Init();
- Encoder_Init();
- ReadRecord(); //Read the last settings from eeprom
- Display_Initial_UI();
- AD9833_Init((WaveDef)waveform_select, freq, 0, AMP_Value);
- /* USER CODE END 2 */
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1) {
- button_status = Button_Get_Status();
- switch (Menu_Selector) {
- case Main_Menu:
- Process_Main_Menu();
- break;
- case Change_Frequency:
- Process_Change_Frequency();
- break;
- case Change_Wave_Form:
- Process_Change_Waveform();
- break;
- case Amper_Level:
- Process_Amper_Level();
- break;
- case Sweep_Mode:
- // Process_Sweep_Mode();
- break;
- default:
- break;
- }
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
- }
- /* USER CODE END 3 */
- }
複製代碼 |
|