stm32g031_PWM + LPF 信号发生器
/* Includes ------------------------------------------------------------------*/ #include "main.h" #include "dma.h" #include "spi.h" #include "tim.h" #include "gpio.h" #include "oled.h" #include "bmp.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ static void setparameters(void); void showbegin(void); void startoutput(void); void stopoutput(void); void ShowAMP(double AMP); void ShowFRE(uint16_t FRE); void increaseamplitude(void); void decreaseamplitude(void); #define LEN 500 uint16_t send_Buf[LEN] = {0};//数组内是PWM比较�????? static const uint8_t sine_wave_value[LEN]={51,51,52,53,53,54,54,55,56,56,57,58,58,59,59,60,61,61,62,62, 63,64,64,65,65,66,67,67,68,68,69,70,70,71,71,72,72,73,74,74, 75,75,76,76,77,77,78,78,79,79,80,80,81,81,82,82,83,83,84,84, 85,85,86,86,86,87,87,88,88,89,89,89,90,90,90,91,91,92,92,92, 93,93,93,94,94,94,94,95,95,95,96,96,96,96,96,97,97,97,97,98, 98,98,98,98,98,99,99,99,99,99,99,99,99,100,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,99,99,99,99,99,99,99,99,98,98,98,98,98,98,97,97,97,97,96, 96,96,96,96,95,95,95,94,94,94,94,93,93,93,92,92,92,91,91,90, 90,90,89,89,89,88,88,87,87,86,86,86,85,85,84,84,83,83,82,82, 81,81,80,80,79,79,78,78,77,77,76,76,75,75,74,74,73,72,72,71, 71,70,70,69,68,68,67,67,66,65,65,64,64,63,62,62,61,61,60,59, 59,58,58,57,56,56,55,54,54,53,53,52,51,51,50,49,49,48,47,47, 46,46,45,44,44,43,42,42,41,41,40,39,39,38,38,37,36,36,35,35, 34,33,33,32,32,31,30,30,29,29,28,28,27,26,26,25,25,24,24,23, 23,22,22,21,21,20,20,19,19,18,18,17,17,16,16,15,15,14,14,14, 13,13,12,12,11,11,11,10,10,10,9,9,8,8,8,7,7,7,6,6,6,6,5,5,5, 4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2, 2,2,3,3,3,3,4,4,4,4,4,5,5,5,6,6,6,6,7,7,7,8,8,8,9,9,10,10, 10,11,11,11,12,12,13,13,14,14,14,15,15,16,16,17,17,18,18,19, 19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,28,28,29,29, 30,30,31,32,32,33,33,34,35,35,36,36,37,38,38,39,39,40,41,41, 42,42,43,44,44,45,46,46,47,47,48,49,49,50, }; static const uint8_t triangle_wave_value[LEN] = {0,0,1,1,2,2,2,3,3,4,4,4,5,5,6,6,6,7,7,8, 8,8,9,9,10,10,10,11,11,12,12,12,13,13,14, 14,14,15,15,16,16,16,17,17,18,18,18,19,19, 20,20,20,21,21,22,22,22,23,23,24,24,24,25, 25,26,26,26,27,27,28,28,28,29,29,30,30,30, 31,31,32,32,32,33,33,34,34,34,35,35,36,36, 36,37,37,38,38,38,39,39,40,40,40,41,41,42, 42,42,43,43,44,44,44,45,45,46,46,46,47,47, 48,48,48,49,49,50,50,50,51,51,52,52,52,53, 53,54,54,54,55,55,56,56,56,57,57,58,58,58, 59,59,60,60,60,61,61,62,62,62,63,63,64,64, 64,65,65,66,66,66,67,67,68,68,68,69,69,70, 70,70,71,71,72,72,72,73,73,74,74,74,75,75, 76,76,76,77,77,78,78,78,79,79,80,80,80,81, 81,82,82,82,83,83,84,84,84,85,85,86,86,86, 87,87,88,88,88,89,89,90,90,90,91,91,92,92, 92,93,93,94,94,94,95,95,96,96,96,97,97,98, 98,98,99,99,100,100,99,99,98,98,98,97,97,96, 96,96,95,95,94,94,94,93,93,92,92,92,91,91,90, 90,90,89,89,88,88,88,87,87,86,86,86,85,85,84, 84,84,83,83,82,82,82,81,81,80,80,80,79,79,78, 78,78,77,77,76,76,76,75,75,74,74,74,73,73,72, 72,72,71,71,70,70,70,69,69,68,68,68,67,67,66, 66,66,65,65,64,64,64,63,63,62,62,62,61,61,60, 60,60,59,59,58,58,58,57,57,56,56,56,55,55,54, 54,54,53,53,52,52,52,51,51,50,50,50,49,49,48, 48,48,47,47,46,46,46,45,45,44,44,44,43,43,42, 42,42,41,41,40,40,40,39,39,38,38,38,37,37,36, 36,36,35,35,34,34,34,33,33,32,32,32,31,31,30, 30,30,29,29,28,28,28,27,27,26,26,26,25,25,24, 24,24,23,23,22,22,22,21,21,20,20,20,19,19,18, 18,18,17,17,16,16,16,15,15,14,14,14,13,13,12, 12,12,11,11,10,10,10,9,9,8,8,8,7,7,6,6,6,5,5, 4,4,4,3,3,2,2,2,1,1,0,0, }; uint16_t NUM = 0; uint16_t BUTTONSTATE = 0; uint16_t WAVESTATE = 0; //波形 uint16_t AMPSTATE = 0; uint16_t FRESTAYE = 0; uint16_t PUTSTATE = 0; double AMP = 1.65; uint16_t FRE = 2; uint16_t amplitude = 165; // max = 165,幅�????? uint16_t frequency = 2000; //频率KHz uint16_t tim; //定时器自动装载�?? /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ 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_DMA_Init(); MX_SPI2_Init(); MX_TIM3_Init(); /* USER CODE BEGIN 2 */ OLED_Init(); //OLED_ShowString(0, 6, "CH1", 8, 1); showbegin(); setparameters(); //OLED_Refresh(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ if(PUTSTATE==1){ startoutput(); } else{ stopoutput(); } /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1; RCC_OscInitStruct.PLL.PLLN = 8; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } /* USER CODE BEGIN 4 */ void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == Astate_Pin) { if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4)==0){ NUM=NUM+1; } else{ NUM=NUM-1; } switch(NUM%4){ case 1: OLED_ShowString(0, 100, "Amplitude:", 8, 1); OLED_ShowString(0, 120, "Signal Output:", 8, 1); OLED_ShowString(0, 90, "Signal Wave:", 8, 0); OLED_Refresh(); BUTTONSTATE=1; break; case 2: OLED_ShowString(0, 90, "Signal Wave:", 8, 1); OLED_ShowString(0, 110, "Frequency:", 8, 1); OLED_ShowString(0, 100, "Amplitude:", 8, 0); OLED_Refresh(); BUTTONSTATE=2; break; case 3: OLED_ShowString(0, 100, "Amplitude:", 8, 1); OLED_ShowString(0, 120, "Signal Output:", 8, 1); OLED_ShowString(0, 110, "Frequency:", 8, 0); OLED_Refresh(); BUTTONSTATE=3; break; case 0: OLED_ShowString(0, 110, "Frequency:", 8, 1); OLED_ShowString(0, 90, "Signal Wave:", 8, 1); OLED_ShowString(0, 120, "Signal Output:", 8, 0); OLED_Refresh(); BUTTONSTATE=0; break; } } if(GPIO_Pin == KeyUp_Pin){ switch(BUTTONSTATE){ case 1: if(WAVESTATE>=3){ WAVESTATE=0; } else{ WAVESTATE++; } switch(WAVESTATE){ case 0: OLED_ShowString(78, 90, "DC ", 8, 1); OLED_ShowPicture(0, 20, 128, 64, dc, 1); OLED_Refresh(); setparameters(); break; case 1: OLED_ShowString(78, 90, "SINE", 8, 1); OLED_ShowPicture(0, 20, 128, 64, sin, 1); OLED_Refresh(); setparameters(); break; case 2: OLED_ShowString(78, 90, "SQUA", 8, 1); OLED_ShowPicture(0, 20, 128, 64, sqr, 1); OLED_Refresh(); setparameters(); break; case 3: OLED_ShowString(78, 90, "TRIA", 8, 1); OLED_ShowPicture(0, 20, 128, 64, tri, 1); OLED_Refresh(); setparameters(); break; } break; case 2: increaseamplitude(); break; case 3: increasefreq(); break; case 0: switch(PUTSTATE){ case 0: OLED_ShowString(90, 120, "ON ", 8, 1); OLED_Refresh(); break; case 1: OLED_ShowString(90, 120, "OFF", 8, 1); OLED_Refresh(); break; } if(PUTSTATE>=1){ PUTSTATE=0; } else{ PUTSTATE++; } break; } } if(GPIO_Pin == KeyDown_Pin){ switch(BUTTONSTATE){ case 1: if(WAVESTATE <= 0){ WAVESTATE=3; } else{ WAVESTATE--; } switch(WAVESTATE){ case 0: OLED_ShowString(78, 90, "DC ", 8, 1); OLED_ShowPicture(0, 20, 128, 64, dc, 1); OLED_Refresh(); setparameters(); break; case 1: OLED_ShowString(78, 90, "SINE", 8, 1); OLED_ShowPicture(0, 20, 128, 64, sin, 1); OLED_Refresh(); setparameters(); break; case 2: OLED_ShowString(78, 90, "SQUA", 8, 1); OLED_ShowPicture(0, 20, 128, 64, sqr, 1); OLED_Refresh(); setparameters(); break; case 3: OLED_ShowString(78, 90, "TRIA", 8, 1); OLED_ShowPicture(0, 20, 128, 64, tri, 1); OLED_Refresh(); setparameters(); break; } break; case 2: decreaseamplitude(); break; case 3: decreasefreq(); break; case 0: switch(PUTSTATE){ case 0: OLED_ShowString(90, 120, "ON ", 8, 1); OLED_Refresh(); break; case 1: OLED_ShowString(90, 120, "OFF", 8, 1); OLED_Refresh(); break; } if(PUTSTATE<=0){ PUTSTATE=1; } else{ PUTSTATE--; } break; } } } void showbegin(void){ OLED_ShowPicture(0, 20, 128, 64, dc, 1); OLED_ShowString(0, 0, "Signal Generator", 16, 1); OLED_ShowString(0, 90, "Signal Wave:", 8, 1); OLED_ShowString(78, 90, "DC ", 8, 1); OLED_ShowString(0, 100, "Amplitude:", 8, 1); OLED_ShowString(66, 100, "3.00V", 8, 1); OLED_ShowString(0, 110, "Frequency:", 8, 1); OLED_ShowString(66, 110, "2KHz", 8, 1); OLED_ShowString(0, 120, "Signal Output:", 8, 1); OLED_ShowString(90, 120, "---", 8, 1); OLED_Refresh(); } void ShowAMP(double AMP) { char str[5]; sprintf(str, "%.2fV", AMP); OLED_ShowString(66, 100, str, 8, 1); OLED_Refresh(); } void ShowFRE(uint16_t FRE) { char str[6]; sprintf(str, "%dKHz", FRE); OLED_ShowString(66, 110, str, 8, 1); OLED_Refresh(); } void startoutput(void){ HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_3,(uint16_t*)send_Buf,LEN); } void stopoutput(void){ HAL_TIM_PWM_Stop_DMA(&htim3, TIM_CHANNEL_3); } void increaseamplitude(void){ if (amplitude < 165) { amplitude = amplitude + 15; if(WAVESTATE == 0){ AMP =(double) ( 3*((double)amplitude / (double)165 )); } else{ AMP = (double)((0.5*tim * amplitude / 165 + tim/2 )/tim*3-1.5); } setparameters(); ShowAMP(AMP); } } void decreaseamplitude(void){ if (amplitude > 0) { amplitude = amplitude - 15; if(WAVESTATE == 0){ AMP = (double) ( 3*((double)amplitude / (double)165 )); } else{ AMP = (double)((0.5*tim * amplitude / 165 + tim/2 )/tim*3-1.5); } setparameters(); ShowAMP(AMP); } } void increasefreq(void){ if (frequency < 100000) { frequency += 1000; FRE=frequency/1000; setparameters(); ShowFRE(FRE); } } void decreasefreq(void){ if (frequency > 100) { frequency -= 1000; FRE=frequency/1000; setparameters(); ShowFRE(FRE); } } static void setparameters(void){ uint16_t i; tim = 64000000 / LEN / frequency;// ARR TIM3->CNT = 0; __HAL_TIM_SET_AUTORELOAD(&htim3, (tim-1)); switch(WAVESTATE){ case 0: for (i = 0; i < LEN; i++){ send_Buf[i]=(uint16_t)((50*amplitude/165) * (tim-1) / 50);//直流 } break; case 1: for (i = 0; i < LEN; i++){ send_Buf[i]=(uint16_t)((sine_wave_value[i]-50) * (tim -1) / 100 * (amplitude) / 165 + tim /2);//sin } break; case 2: for (i = 0; i < LEN; i++){ send_Buf[i]=(uint16_t)((50 + 50*(amplitude)/165 * (i<LEN/2?1:-1)) * (tim-1) / 100);//方波 } break; case 3: for (i = 0; i < LEN; i++){ send_Buf[i]=(uint16_t)((triangle_wave_value[i]-50) * tim / 100 * (amplitude) / 165 + tim /2);//三角�???? } break; default: break; } } /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */