主頁 > 軟體設計 > 1、基于STM32的音樂噴泉√♥

1、基于STM32的音樂噴泉√♥

2021-08-11 07:55:17 軟體設計

1、基于STM32的音樂噴泉

文章目錄

  • 1、基于STM32的音樂噴泉
  • Introduction
  • 引言
  • 1、系統概述
    • 1.1、設計任務
    • 1.2、設計要求
  • 2、 方案設計
    • 2.1、芯片選擇方案
    • 2.2、 系統概述:
    • 2.3、系統總體設計思路
    • 2.4、各功能模塊程式實作原理分析
      • 2.4.1.水泵驅動模塊
      • 2.4.2輸入音頻功率放大模塊
  • 3 、STM32性能介紹及硬體設計
    • 3.1、 STM32單片機性能介紹
    • 3.2、音樂噴泉系統硬體設計\
  • 4、 系統程式
    • 4.1、主程式設計如下
    • 4.2 主程式內容
  • 5、系統除錯及分析
    • 5.1、系統除錯
    • 5.2、除錯現象及分析
    • 5.3、測驗結果

Introduction

With the improvement of people’s living standards and the yearning to build a green city, musical fountains have become an important product in the leisure and entertainment industry with their unique charm and special functions, and more and more musical fountains have been built. According to the current development status of musical fountains, a small musical fountain control system with STM32F103C8T6 microcontroller as the core is introduced. Gives a simple single-chip control circuit, analyzes the audio output circuit and input circuit; introduces the principle of obtaining the spray pool data that determines the action of the spray pool from the audio signal of a specific structure; gives the main program block diagram and the use of program control To control the pattern. The audio signal also affects the changes in the brightness of the light. So that the flickering of the lights and the water posture of the fountain change with the rhythm of the music.

引言

隨著人們生活水平的提高和建立綠色城市的向往,音樂噴泉以其獨特的魅力和特殊的功能,愈來愈成為休閑娛樂產業中的一項重要產品,音樂噴泉的興建也越來越多,根據目前音樂噴泉的發展現狀,介紹了一個以STM32F103C8T6單片機為核心的小型音樂噴泉控制系統,給出了一個簡潔的單片機控制電路,分析了音頻輸出電路和輸入電路;介紹了從特定構造的音頻信號中獲得決定噴池動作的噴池資料的原理;給出了主程式框圖和采用程式控制來控制花型,音頻信號還影響燈光光線明暗的變化,從而使燈光的閃爍和噴泉水姿隨音樂節奏而變化,

1、系統概述

1.1、設計任務

用STM32設計一個噴泉音樂盒

1.2、設計要求

基于STM32單片機音樂噴泉設計 音樂盒播放器頻譜彩燈電子設計

  • 1.可以播放電腦、手機、MP3里面的音樂,

  • 2.產品具有8個LED頻譜彩燈,隨音樂變化閃爍,

  • 3.音樂停止,噴水電機停止作業,

  • 4.AD對音頻信號的采集,轉換為數字信號給單片機PWM控制水泵,實作水柱高低變化,

2、 方案設計

2.1、芯片選擇方案

STM32單片機是整個溫度控制系統的核心部分,因為對溫度控制器具有較高的要求,例如高執行速度,高控制精度,高穩定性以及高靈敏度等,所以選擇一個具有較高性能而又經濟的單片機就成為必然,本設計選用屬于STM32系列的STM32F103C8T6單片機作為控制電路的核心部件,該單片機屬于ST意法半導體公司生產的32位高性能、低成本、低功耗的增強型系列單片機,它的內核采用的是ARM公司最新研發的Cortex-M3架構,該內核是專門設計于滿足用戶對高性能、低功耗和經濟實用的要求,

2.2、 系統概述:

STM32F103C8T6單片機有3個不同的時鐘源可供選擇用以驅動系統時鐘,分別為HSI振蕩器時鐘、HSE振蕩器時鐘和PLL時鐘,這些設備還具有2個二級時鐘源,分別是40KHz的低速內部RC和32.768KHz的低速外部時鐘源,可以用來驅動看門狗時鐘和RTC,任何一個時鐘源在不被使用時,都可以被獨立的關倍訓者開啟,以實作對系統功耗的優化,

2.3、系統總體設計思路

通過單片機程式來控制噴泉的水姿變化,成為一種新的噴泉藝術形式,單片機作為一種控制用微處理器,包含有基本的軟硬體資源,本文采用了單片機控制技術,給出了單片機控制電路,水泵控制電路,流水燈控制電路及部分單片機I/O口初始化程式,單片機的輸出通過數模轉換通過水泵驅動電路驅動水泵,通過變頻調速技術對電泵進行調速,實作程式控制噴泉的高度,不僅能夠進行多種水型切換,而且能控制噴泉水柱上下起伏,同時單片機通過I/O來控制LED燈的亮滅,實作了對噴泉的水、光協同控制,

2.4、各功能模塊程式實作原理分析

系統主要有STM32F103C8T6單片機和、音頻功率放大電流和水泵驅動電路等組成,

2.4.1.水泵驅動模塊

根據單片機的電流特性,不足以直接驅動水泵,有三極管的輸出特性,利用晶體管的飽和和截止特性構成開關電路,通過二級三極管電流放大實作對水泵控制,P20為高電平時基極與集電極之間反向偏置,不導通;當P20為低電平時,基極與集電極之間正向偏置,導通,電路作業,水泵作業作業,單片機只需要吸收嬌小的輸入電流,

2.4.2輸入音頻功率放大模塊

LM386是低電壓小功率音頻放大集成電路,采用8腳雙列直插式塑封包裝電路特點

  • 1、外接元件極少,不需要用輸入耦合電容;

  • 2、負反饋電路在內部,增益有兩種26db46db可供選用;

  • 3、輸入級采用儀表用放大器的形式,帶有同相輸入和反響輸入兩個引腳4靜態功耗小,當電源電壓為6伏時,靜態功耗為24mw

1與8腳為增益調整端,當兩腳開路時,電壓放大數為20倍,當兩腳間接10uf電容時,電壓放大倍數為200倍;2腳為反相輸入端;3腳為同相輸入端;4腳為地端;5腳為輸出端;6腳為電源正端;7腳為旁路端;6腳與地之間接10uf電容可消除可能產生的自激震蕩,如無震蕩7腳可懸空不接,

3 、STM32性能介紹及硬體設計

3.1、 STM32單片機性能介紹

STM32它擁有的資源包括:48KB SRAM、256KB FLASH、2 個基本定時器、4 個通用定時器、2個高級定時器、2個DMA 控制器(共 12 個通道)、3 個SPI、2個IIC、5個串口、1個USB、1個CAN、3個12位ADC、1個12位DAC、1個SDIO介面及51 個通用IO口,該芯片性價比極高,

各個引腳說明如下

  • PA0 作用1,按鍵 KEY_UP 2,可以做待機喚醒腳(WKUP) 3,可以接 DS18B20 傳感器介面(P2 設定)

  • PA1作用1,NRF24L01 介面 IRQ 信號 2,接 HS0038 紅外接收頭(P2 設定)

  • PA2 作用 作為W25Q64 的片選信號

  • PA3 作用 作為SD 卡介面的片選腳

  • PA4 作用 作為NRF24L01 介面的 CE 信號

  • PA5 作用 作為W25Q64、SD 卡和 NRF24L01 介面的 SCK 信號

  • PA6 作用 作為 W25Q64、SD 卡和 NRF24L01 介面的 MISO 信號

  • PA7 作用 作為 W25Q64、SD 卡和 NRF24L01 介面的 MOSI 信號

  • PA8 作用 作為 接 DS0 LED 燈(紅色)

  • PA9 作用 作為串口 1 TX 腳,默認連接 CH340 的 RX(P4 設定)

  • PA10 作用 作為串口 1 RX 腳,默認連接 CH340 的 TX(P4 設定)

  • PA11 作用 作為接 USB D-引腳

  • PA12 作用 作為接 USB D+引腳

  • PA13作用 作為JTAG/SWD 仿真介面,沒接任何外設

  • PA14 作用 作為JTAG/SWD 仿真介面,沒接任何外設

  • PA15 作用 作為1,JTAG 仿真口(JTDI) 2,PS/2 介面的 CLK 信號 3,接按鍵 KEY1

3.2、音樂噴泉系統硬體設計\

該程式所需要的電源電路,功率放大電路,音頻輸入電路,LED燈顯示電路,水泵驅動電路,次如下圖所示

img

圖1.1電源電路圖如下圖

img

圖1.2 功率放大電路圖如下圖

img

圖1.3音頻輸入電路圖如下圖

img

圖1.4 LED電路圖如下圖

img

圖1.5 水泵驅動電路圖如下圖

4、 系統程式

4.1、主程式設計如下

音樂噴泉系統主要由單片機通過紅外通信控制,當其完成紅外信號,讀取資料,其資料的傳輸根據協議的內容,音樂噴泉系統程式需要完成以下的功能:

  • 1、led燈隨音頻信號起伏;

  • 2、水泵的噴水量隨音量的變化而變化,

程式流程圖如下:

img

圖1.5主程式流程設計圖

4.2 主程式內容

#include "main.h"
#include "stm32f1xx_hal.h"

/* USER CODE BEGIN Includes */
#include <math.h>
#include <stdio.h>

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;

IWDG_HandleTypeDef hiwdg;

TIM_HandleTypeDef htim3;
TIM_HandleTypeDef htim4;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/

//宏定義燈IO
#define LED0_0  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_RESET)
#define LED0_1  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_SET)

#define LED1_0  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET)
#define LED1_1  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_SET)

#define LED2_0  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET)
#define LED2_1  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET)

#define LED3_0  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET)
#define LED3_1  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET)

#define LED4_0  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET)
#define LED4_1  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET)

#define LED5_0  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET)
#define LED5_1  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET)

#define LED6_0  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET)
#define LED6_1  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET)

#define LED7_0  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET)
#define LED7_1  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET)


unsigned char PWM_falg=1;
uint8_t ch;
uint8_t ch_r;
//重寫這個函式,重定向printf函式到串口,意思就是說printf直接輸出到串口,其默認輸出到控制臺的
 /*fputc*/
 int fputc(int c, FILE * f)
 {
     ch=c;
     HAL_UART_Transmit(&huart1,&ch,1,1000);//發送串口
     return c;
 }
 //重定向scanf函式到串口 意思就是說接受串口發過來的資料,其默認是接受控制臺的資料
 /*fgetc*/
 int fgetc(FILE * F)    
 {
     HAL_UART_Receive (&huart1,&ch_r,1,0xffff);//接收
     return ch_r;
 }
//#######################################################################################################//
//下面定義關于串口的
unsigned char Uart1_Buff[1024];  //串口1緩沖陣列
unsigned char Uart1_Count=0;     //串口1累加變數
uint8_t aRxBuffer[3];            //定義一個暫存陣列

//下面定義關于定時器的
unsigned int  Time4_ms=0;
//下面定義關于讀取ADC的
unsigned char Scan_Fre=0;
unsigned int  ADC_Dat=0;
//下面定義啟停部分
unsigned char Open_Close=1;
unsigned char System_Count=0;
unsigned int Open_Flsh=0;

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM4_Init(void);
static void MX_ADC1_Init(void);
static void MX_TIM3_Init(void);
static void MX_IWDG_Init(void);
static void MX_USART1_UART_Init(void);

void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
                                

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

struct Complex {
char real;//實部
char imag;//虛部
}; //構造復數結構
typedef struct Complex COMPLEX;  
#define  N    128   //FFT點數(長度)
#define  PI2 128		//一周期分成128點
COMPLEX  S[N]; //FFT復數陣列  
unsigned char  iw[128]={0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,10,11,11,12,12,12,13,13,14,14,14,15,15,15,16,16,16,17,17,17,17,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,22,22,22,22,23,23,23,23,23,24,24,24,24,25,25,25,25,25,26,26,26,26,26,27,27,27,27,27,27,28,28,28,28,28,29,29,29,29,29,29,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31};
char  costab[PI2]={
127,127,127,126,125,124,122,120,118,115,112,109,106,102,
98,94,90,85,81,76,71,65,60,54,48,43,37,31,24,18,12,6,0,
-6,-12,-18,-24,-31,-37,-43,-48,-54,-60,-65,-71,-76,-81,
-85,-90,-94,-98,-102,-106,-109,-112,-115,-118,-120,-122,
-124,-125,-126,-127,-127,-128,-127,-127,-126,-125,-124,
-122,-120,-118,-115,-112,-109,-106,-102,-98,-94,-90,-85,
-81,-76,-71,-65,-60,-54,-48,-43,-37,-31,-24,-18,-12,-6,0,
6,12,18,24,31,37,43,48,54,60,65,71,76,81,85,90,94,98,
102,106,109,112,115,118,120,122,124,125,126,127,127
//127,127,126,126,125,123,122,120,117,115,112,109,106,102,
//98,94,90,85,81,76,71,65,60,54,49,43,37,31,25,19,12,6,0,
//-6,-12,-19,-25,-31,-37,-43,-49,-54,-60,-65,-71,-76,-81,
//-85,-90,-94,-98,-102,-106,-109,-112,-115,-117,-120,-122,
//-123,-125,-126,-126,-127,-127,-127,-126,-126,-125,-123,
//-122,-120,-117,-115,-112,-109,-106,-102,-98,-94,-90,-85,
//-81,-76,-71,-65,-60,-54,-49,-43,-37,-31,-25,-19,-12,-6,
//0,6,12,19,25,31,37,43,49,54,60,65,71,76,81,85,90,94,98,
//102,106,109,112,115,117,120,122,123,125,126,126,127
};
char sintab[PI2]={
0,6,12,18,24,31,37,43,48,54,60,65,71,76,81,85,90,94,98,
102,106,109,112,115,118,120,122,124,125,126,127,127,128,
127,127,126,125,124,122,120,118,115,112,109,106,102,98,
94,90,85,81,76,71,65,60,54,48,43,37,31,24,18,12,6,0,-6,
-12,-18,-24,-31,-37,-43,-48,-54,-60,-65,-71,-76,-81,-85,
-90,-94,-98,-102,-106,-109,-112,-115,-118,-120,-122,-124,
-125,-126,-127,-127,-128  ,-127,-127,-126,-125,-124,-122,
-120,-118,-115,-112,-109,-106,-102,-98,-94,-90,-85,-81,
-76,-71,-65,-60,-54,-48,-43,-37,-31,-24,-18,-12,-6
//0,6,12,19,25,31,37,43,49,54,60,65,71,76,81,85,90,94,98,
//102,106,109,112,115,117,120,122,123,125,126,126,127,127,
//127,126,126,125,123,122,120,117,115,112,109,106,102,98,
//94,90,85,81,76,71,65,60,54,49,43,37,31,25,19,12,6,0,-6,
//-12,-19,-25,-31,-37,-43,-49,-54,-60,-65,-71,-76,-81,-85,
//-90,-94,-98,-102,-106,-109,-112,-115,-117,-120,-122,-123,
//-125,-126,-126,-127,-127,-127,-126,-126,-125,-123,-122,
//-120,-117,-115,-112,-109,-106,-102,-98,-94,-90,-85,-81,
//-76,-71,-65,-60,-54,-49,-43,-37,-31,-25,-19,-12,-6
};
/****************************************************
x:輸入資料實部,輸出資料實部(有符號數)
y:輸入資料虛部,輸出資料虛部(有符號數)
n:點數
*************************************************/
void fft(COMPLEX *XX,unsigned char n)
{//x[]為實部,y[]為虛部(全為0),n為點數
 int tr,ti,p,q;
 unsigned char i,j,k,qn,a,b,c,cen,zu,ge;
 a=n-1;
 for(i=0,j=0;i<a;i++)//回圈n-1次
 {											  
  if(i<j)									 
  {
   tr=XX[j].real;
   XX[j].real=XX[i].real;
   XX[i].real=tr; 
   ti=XX[j].imag;
   XX[j].imag=XX[i].imag;
   XX[i].imag=ti;
  }//交換x[i]<->x[j],y[i]<->y[j]
  k=n/2;
  while(k<(j+1))
  {
   j=j-k;
   k=k/2;
  }
  j=j+k;
 }//此回圈把原序列變成2點奇偶序列

 /****************************************/
 for(i=1,j=1;i<8;i++)
 {
   j=2*j;//j=2^p
   if(j>=n)break;
 }
 //2的i次方=n
 cen=i;			   	 	   //如果n=8,則cen=3;
 zu=n;
 for(i=0;i<cen;i++)		   //層數(0,1,2)
 {
  zu=zu/2;		   //組數(4,2,1)
  for(j=0;j<zu;j++)		   //第i 層中的第 j組
  {  
   ge=(n/zu)/2;//一組中蝶形的個數(1,2,4)      
   for(k=0;k<ge;k++)	   //第 j 組中的第k個
   {					   //第 a 和第 b 個元素作蝶形運算,WNC
    a=j*ge*2+k;			   //(0,2,4,6)(0,1,4,5)(0,1,2,3)
    b=a+ge;				   //(ge=1,2,4)
    c=k*zu;				   //(0,0,0,0)(0,2,0,2)(0,1,2,3)
   	qn=(PI2/n)*c;
	//注意sign
	  tr=(XX[b].real*costab[qn]+XX[b].imag*sintab[qn])>>7;//由于正余弦表放大128倍,此處縮小128倍
    ti=(XX[b].imag*costab[qn]-XX[b].real*sintab[qn])>>7;
    p=XX[a].real;
    q=XX[a].imag;
	//蝶形運算
    XX[a].real=(p+tr)>>1;//防止資料溢位
    XX[a].imag=(q+ti)>>1;
    XX[b].real=(p-tr)>>1;
    XX[b].imag=(q-ti)>>1;
   }
  } 
 }
}

 
unsigned char  FFTvaule[64];//輸出的頻譜值(轉換到0~31)
unsigned char  TopPoint[64];//頂點值 [頂部的綠點]
unsigned char  Keep[64];  //頂點停留
unsigned char  LINE;
unsigned char  ADC_Count;

//對fft資料進行處理
void FFTK()
{ 
unsigned char pt=0,j; 
for(pt=0;pt<N;pt++)
{
	S[pt].imag=0; //清零虛部 
	S[pt].real=(S[pt].real-128);//電壓轉換128
}

fft(S,N);//對當前資料進行傅立葉變換  
FFTvaule[0]=0x00;
//處理頂點		
for(pt=0;pt<N/2;pt++) 
{
 
	S[pt].real=sqrtf(S[pt].real*S[pt].real+S[pt].imag*S[pt].imag);//求模
	if((unsigned char)(S[pt].real)<255) 
		FFTvaule[pt] =iw[(unsigned char)(S[pt].real)];
	//處理頂點值 
	if(FFTvaule[pt]>=TopPoint[pt])
	{
		TopPoint[pt] = FFTvaule[pt]+1;
		Keep[pt] = 12;
	}
	else if(TopPoint[pt]>1)
	{ 
		if(Keep[pt])  	Keep[pt]--;
		else   
		{
		  TopPoint[pt]--;
		}
	}
	else 
	TopPoint[j] = 1; 
}
}
//#######################################################################################################//
unsigned int Get_ADC()
{
    unsigned int ADC_Back;
		HAL_ADC_Start(&hadc1);  
		HAL_ADC_PollForConversion(&hadc1,0xffff); //等待檢測結束
		ADC_Back=((HAL_ADC_GetValue(&hadc1)));  
		HAL_ADC_Stop(&hadc1); //結束AD檢測
	  ADC_Dat=ADC_Back;
	  
	  if(Open_Close==1) 
		{
		  if(Open_Flsh!=ADC_Dat)
			{
			  if(Open_Flsh>ADC_Dat)
				{
				  if(Open_Flsh-ADC_Dat >70) 
					{
					  System_Count++;
						
						if(System_Count>=5) 
						{
						  System_Count=0;
							Open_Close=0;
						}
					}
				}
				else 
				{
				  if(ADC_Dat-Open_Flsh >70) 
					{
					   System_Count++;
						 if(System_Count>=5) 
						 {
						  System_Count=0;
							Open_Close=0;
						 }
					}
				}
				Open_Flsh=ADC_Dat;
			}
		}
		else 
		{
		  if(Open_Flsh!=ADC_Dat)
			{
			  if(Open_Flsh>ADC_Dat)
				{
				  if(Open_Flsh-ADC_Dat <70) 
					{
					  System_Count++;
						
						if(System_Count>=5) 
						{
						  System_Count=0;
							Open_Close=1;
						}
					}
				}
				else 
				{
				  if(ADC_Dat-Open_Flsh <70) 
					{
					   System_Count++;
						 if(System_Count>=5) 
						 {
						  System_Count=0;
							Open_Close=1;
						 }
					}
				}
				Open_Flsh=ADC_Dat;
			}
		}
    
    return ADC_Back;
}
//#######################################################################################################//
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 
{
    if(htim==&htim4)
      {
         Time4_ms++;
				 if(Time4_ms%80==0) 
				 {
					 Time4_ms=0;
				   Scan_Fre =1;
					 GPIOC->ODR^=GPIO_PIN_13;
				 }
			}
}
void LED_Dispose(unsigned char Dat_) 
{
  if(Dat_>31) LED0_0;
	else        LED0_1;
	if(Dat_>62) LED1_0;
	else         LED1_1;
	if(Dat_>93) LED2_0;
	else    LED2_1;
		
	if(Dat_>124) LED3_0;
	else LED3_1;
		
	if(Dat_>155) LED4_0;
	else LED4_1;
		
	if(Dat_>186) LED5_0;
	else LED5_1;
		
	if(Dat_>217)LED6_0; 
	else LED6_1;
		
	if(Dat_>240)LED7_0; 
	else LED7_1;
}

//#######################################################################################################//
void Debug_Output()
{
   unsigned char Coun=0;
	 for(Coun=0;Coun<30;Coun++) 
	 {
		 if(FFTvaule[0]<22)
		 {
		  	LED0_1 ;
			  LED1_1 ;
			  LED2_1 ;
			  LED3_1 ;
			  LED4_1 ;
			  LED5_1 ;
			  LED6_1 ;
			  LED7_1 ;
			  HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_4);
			  PWM_falg=1;
		 }
		 else  
		 {
			 if(PWM_falg==1)
			 {
			   HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
				 PWM_falg=0;
			 }
			 if(FFTvaule[Coun]*257<65535)   TIM3->CCR4 = FFTvaule[Coun]*257;
		   LED_Dispose(FFTvaule[Coun]);
		 }		 
		 printf("%d,",FFTvaule[Coun]);		 
	 }
	  printf("\r\n%d",ADC_Dat); 	 
	  printf("%s","\r\n");		
}

//#######################################################################################################//
/**
  * @brief  The application entry point.
  * @main函式
  * @retval None
  */
int main(void)
{
  HAL_Init();
  /* Configure the system clock */
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM4_Init();
  MX_ADC1_Init();
  MX_TIM3_Init();
  MX_IWDG_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim4); 
  HAL_UART_Transmit(&huart1,(unsigned char *)"System_Star\r\n",13,100);
  HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
  TIM3->CCR4 =0;
  while (1)
  {
	Get_ADC(); 
	if(Open_Close ==0) 
	{
		for(ADC_Count=0;ADC_Count<N;ADC_Count++)
		{
			S[ADC_Count].real =Get_ADC()/4;
			S[ADC_Count].imag =0;	
		}	
		FFTK();	//FFT
		if(Scan_Fre==1) 
		{
			Scan_Fre=0;
			Debug_Output();
		}
	}
     HAL_IWDG_Refresh(&hiwdg); 
  }
}
/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_PeriphCLKInitTypeDef PeriphClkInit;
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
  /**Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

    /**Configure the Systick 
    */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

/* ADC1 init function */
static void MX_ADC1_Init(void)
{
  ADC_ChannelConfTypeDef sConfig;
  hadc1.Instance = ADC1;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
  sConfig.Channel = ADC_CHANNEL_8;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

/* IWDG init function */
static void MX_IWDG_Init(void)
{

  hiwdg.Instance = IWDG;
  hiwdg.Init.Prescaler = IWDG_PRESCALER_32;
  hiwdg.Init.Reload = 800;
  if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

/* TIM3 init function */
static void MX_TIM3_Init(void)
{

  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;
  TIM_OC_InitTypeDef sConfigOC;

  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 63;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 1000;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  HAL_TIM_MspPostInit(&htim3);

}

/*定時器 TIM4 init function */
static void MX_TIM4_Init(void)
{

  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;

  htim4.Instance = TIM4;
  htim4.Init.Prescaler = 63;
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim4.Init.Period = 1000;
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

/* USART1 init function */
static void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

/** Configure pins as 
        * Analog 
        * Input 
        * Output
        * EVENT_OUT
        * EXTI
*/
static void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6 
                          |GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_SET);

  /*Configure GPIO pin : PC13 */
  GPIO_InitStruct.Pin = GPIO_PIN_13;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pin : PA15 */
  GPIO_InitStruct.Pin = GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PB3 PB4 PB5 PB6 
                           PB7 PB8 PB9 */
  GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6 
                          |GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}


void _Error_Handler(char *file, int line)
{
 
  while(1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT

void assert_failed(uint8_t* file, uint32_t line)
{ 
  
}
#endif /* USE_FULL_ASSERT */

5、系統除錯及分析

5.1、系統除錯

根據系統設計方案,本系統的除錯共分為三大部分:硬體除錯,軟體除錯和軟硬體聯調,由于在系統設計中采用模塊設計法,所以方便對各電路模塊功能進行逐級測驗:LED驅動模塊的除錯,資料存盤模塊的除錯,PC機通信模塊的除錯等,最后將各模塊組合后進行整體測驗,

5.2、除錯現象及分析

進入除錯狀態后應該在關鍵的地方設定斷點然后按步運行,同時觀察引數的變化,通過變化來判斷程式運行的程序即可找出程式中混亂的部分,進行改正,這需要對軟體熟練的掌握和對語言程式的很好的理解,實驗板搭建成功后,我們就進入了程式的設計和除錯階段,開始撰寫程式時很順利,但是后來在除錯程序中出現了很多的錯誤,比如定時器準確度的設定,子程式的呼叫問題,最困難的就是對沒步程式執行順序的分析,由于程式中一些陳述句的錯誤理解和執行順序的判斷失誤,讓我掉進了誤區,耽誤了很長時間,最后在同學的幫助下終于找到了錯誤的關鍵點,更正成功了,看來對程式的除錯能力我還需要加強,程式的除錯需要耐心,而且需要熟練掌握軟體的跟部分功能,

5.3、測驗結果

image-20210808082014461

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/293004.html

標籤:其他

上一篇:cgb2106-day11

下一篇:聊聊 Kafka: Kafka 的基礎架構

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more