加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權(quán)保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入

基于STM32波形信號發(fā)生器proteus仿真設(shè)計(仿真+程序+報告+講解)

08/22 13:43
3217
服務(wù)支持:
技術(shù)交流群

完成交易后在“購買成功”頁面掃碼入群,即可與技術(shù)大咖們分享疑惑和經(jīng)驗、收獲成長和認同、領(lǐng)取優(yōu)惠和紅包等。

虛擬商品不可退

當(dāng)前內(nèi)容為數(shù)字版權(quán)作品,購買后不支持退換且無法轉(zhuǎn)移使用。

加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論
放大
實物圖
相關(guān)方案
  • 方案介紹
    • 基于STM32波形信號發(fā)生器proteus仿真設(shè)計(仿真+程序+報告+講解)
  • 相關(guān)文件
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

基于STM32波形信號發(fā)生器proteus仿真設(shè)計(仿真+程序+報告+講解)

仿真圖proteus 8.9

程序編譯器:keil 5

編程語言:C語言

設(shè)計編號:C0075

講解仿真視頻:


基于STM32的波形信號發(fā)生器proteus仿真設(shè)計

主要功能:

結(jié)合實際情況,基于STM32F103單片機設(shè)計一個四種波形發(fā)生器(正弦波、方波、三角波、鋸齒波)。該系統(tǒng)應(yīng)滿足的功能要求為:

(1) 可以實現(xiàn)四種波形:正弦波、方波、三角波、鋸齒波;

(2) 通過按鍵進行選擇,頻率可以調(diào)整;

(3) LCD液晶顯示;

(4)設(shè)計出來之后用Proteus軟件仿真出效果;

主要硬件設(shè)備:STM32F103單片機、DAC0832數(shù)模轉(zhuǎn)換芯片、矩陣鍵盤、LCD12864液晶屏幕。

資料下載鏈接(可點擊):

騰訊文檔】C0075 下載鏈接

以下為本設(shè)計資料展示圖:

整體設(shè)計方案

四種波形發(fā)生器以STM32F103單片機作為整個系統(tǒng)的控制核心,應(yīng)用其強大的處理速度,構(gòu)成波形發(fā)生器系統(tǒng)。該系統(tǒng)具備將數(shù)字信號轉(zhuǎn)換為模擬信號的能力。正弦波可以直接采用數(shù)學(xué)函數(shù)sin計算出來,送入單片機進行數(shù)據(jù)處理。經(jīng)單片機運算后的數(shù)據(jù)送入DAC0832芯片將數(shù)字信號轉(zhuǎn)換為模擬信號輸出。其他的波形都可以采用自身的規(guī)律采用不同的算法實現(xiàn)。

img

圖2-1 基于STM32單片機的四種波形發(fā)生器原理圖

本系統(tǒng)硬件主要由矩陣鍵盤、D/A轉(zhuǎn)換器、LCD12864顯示系統(tǒng)、處理器等幾部分組成。各模塊的主要功能如下:

(1)矩陣鍵盤的功能是設(shè)置波形和頻率,然后送入單片機。

(2) MCU的功能是識別鍵盤的數(shù)據(jù)并進行相對應(yīng)的處理,然后轉(zhuǎn)換出波形的數(shù)字信號和LCD顯示的數(shù)據(jù)。

(3) LCD12864顯示系統(tǒng)的功能是將設(shè)置的波形和頻率顯示出來。

系統(tǒng)的整體設(shè)計方案設(shè)計圖如圖2-2所示。

img

圖2-2 系統(tǒng)的整體方案設(shè)計圖

采用的是DAC0832芯片來做DA轉(zhuǎn)換的,DAC0832將輸出電壓分成了0xFF(255)份,需要輸出不同的波形我們需要給不同的數(shù)據(jù),在這里我將所有的波形的一個周期分成了100份,定時器每隔一段時間中斷一次,中斷100次為一個周期。

正弦波采用數(shù)學(xué)計算公式sin來計算;

方波只需要在定時器前面50次給0,后面50次給最大值即可;

三角波只需要在定時器前面50次采用最大值的50分之一乘于它本身,后面50次相反即可;

鋸齒波只需要在一個周期內(nèi),定時器中斷一次就用他本身乘于電壓最大值的100分之一即可;

測試波形如下所示:

三角波

img

鋸齒波

img

方波

img

正弦波

img

程序:

img

img

main函數(shù)

#define KEY0  GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)		//讀取按鍵0

void Delay_Ms(u16 time);

 /***************  配置Switch用到的I/O口 *******************/
void Init_GPIO_Switch(void)	
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//關(guān)閉jtag,使能SWD,可以用SWD模式調(diào)試
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);	// 使能PC端口時鐘 
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_10;				//PC0 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//IO口速度為50MHz
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 	//設(shè)置成輸入
 	GPIO_Init(GPIOB, &GPIO_InitStructure);					//初始化PC0
}

/* Private functions ---------------------------------------------------------*/ 
/*******************************************************************************
*功能名稱:main
*描述:主程序。
*輸入:無
*輸出:無
*返回:無
*******************************************************************************/
int main(void)
{
	u8 i=0;
	RCC_ClocksTypeDef RCC_Clocks;		//初始化程序
	
	RCC_Configuration(RCC_PLLMul_4);	//8M*4 == 32M
	RCC_GetClocksFreq(&RCC_Clocks);		//獲取片上時鐘
	
    Init_12864();      				 	//初始化12864液晶
	
	Key_Init();  				
	Init_GPIO_Switch();
	Init_GPIO_DAC0832();
	
	Data0=25;
	TIM3_Int_Init(50+Data0,320);	//頻率:32000000/ 320 ==100 000	/100 == 1000 /50==20
	
	LCD_P6x8Str(3,16,"   Sine Wave   ");
	LCD_P6x8Str(7,6*2,"Frequency: 15 Hz");
	
  	while (1)
  	{
		if(KEY0)
		{
			if(i!=2)
			{
				__set_PRIMASK(1);
				GPIO_ResetBits(GPIOB, ((uint16_t)0xC000));
			}
			Key_Test();	
			
			i=2;
		}
		else{
			
			if(i!=5)
			{
				TIM3_Int_Init(50+Data0,320);
				__set_PRIMASK(0);  				//使能TIMx外設(shè)
				GPIO_ResetBits(GPIOB, ((uint16_t)0xC000));
			}
			
			i=5;
		}	
  	}
}

波形信號部分

 /***************  配置DAC用到的I/O口 *******************/
void Init_GPIO_DAC0832(void)	
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);	// 使能PC端口時鐘  
	GPIO_InitStructure.GPIO_Pin = ((uint16_t)0x03FF);		//選擇對應(yīng)的引腳
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		//推挽輸出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//IO口速度為50MHz
	GPIO_Init(GPIOC, &GPIO_InitStructure);					//初始化PC端口
	GPIO_SetBits(GPIOC, ((uint16_t)0x00FF));				// 高
	GPIO_ResetBits(GPIOC, ((uint16_t)0x00FF));				// 低
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);	// 使能PC端口時鐘  
	GPIO_InitStructure.GPIO_Pin = ((uint16_t)0xC000);		//選擇對應(yīng)的引腳
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		//推挽輸出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//IO口速度為50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure);					//初始化PC端口
	GPIO_SetBits(GPIOC, ((uint16_t)0xC000));				// 高
	GPIO_ResetBits(GPIOC, ((uint16_t)0xC000));				// 低
	
	
	time=0;
	ADC_CS_WR(0);
	mode=0;		//默認輸出正弦波
	freq=100;	//默認頻率
	AM=255;		//最大幅度
}

void DAC_0832_Data(uint8_t Data)
{
	GPIO_ResetBits(GPIOC,~Data);
	GPIO_SetBits(GPIOC,Data);
}

void sine_wave(u8 location)//輸出正弦波
{
	double x=(double)location/50*PI;//把0-100放縮到0-2派(pai,沒有那個符號)
	u8 y=(sin(x)*(AM/2)+(AM/2));//算出y,并放縮到0-254(因為ADC范圍0-AM,芯片落后)
	DAC_0832_Data(y);
}

void squ_wave(u8 location)//方……
{
	if(location<50)
		DAC_0832_Data(AM);
	else
		DAC_0832_Data(0);//這個簡單
}

void tri_wave(u8 location)//三……
{
	//為了簡化,在單周期輸出V字形
	u8 y;
	if(location<50)
		y=(50-location)*AM/50;
	else
		y=(location-50)*AM/50;
	DAC_0832_Data(y);
	//偶函數(shù),當(dāng)然說奇函數(shù)也沒錯
	
}

void saw_wave(u8 location)//鋸……
{
	DAC_0832_Data(location*AM/100);
	//用(100-location)也以變成反向鋸齒
}

//通用定時器中斷初始化
//這里時鐘選擇為APB1的2倍,而APB1為36M
//arr:自動重裝值。
//psc:時鐘預(yù)分頻數(shù)
//這里使用的是定時器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //時鐘使能

	TIM_TimeBaseStructure.TIM_Period = arr; 			//設(shè)置在下一個更新事件裝入活動的自動重裝載寄存器周期的值	 計數(shù)到5000為500ms
	TIM_TimeBaseStructure.TIM_Prescaler =psc; 			//設(shè)置用來作為TIMx時鐘頻率除數(shù)的預(yù)分頻值  10Khz的計數(shù)頻率  
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; 		//設(shè)置時鐘分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上計數(shù)模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); 	//根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時間基數(shù)單位
 
	TIM_ITConfig(  //使能或者失能指定的TIM中斷
		TIM3, 		//TIM3
		TIM_IT_Update ,
		ENABLE  	//使能
		);
//	TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中斷
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占優(yōu)先級0級
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //從優(yōu)先級3級
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 	//IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  				//根據(jù)NVIC_InitStruct中指定的參數(shù)初始化外設(shè)NVIC寄存器

	TIM_Cmd(TIM3, ENABLE);  //使能TIMx外設(shè)
//	TIM_Cmd(TIM3, DISABLE);	
}

void TIM3_IRQHandler(void)   //TIM3中斷
{
	switch(mode)
	{
		case W_SINE:sine_wave((u8)(time*freq/100)%100);break;//計算出波的位置
		case W_SQU:squ_wave((u8)((time*freq/100)%100));break;
		case W_TRI:tri_wave((u8)((time*freq/100)%100));break;
		case W_SAW:saw_wave((u8)((time*freq/100)%100));break;
	}
	time++;
	if(time>=100)//計數(shù)100次
		time=0;
}

按鍵識別

/************************************
        按鍵表盤為:			1  2  3  A 
							4  5  6  B
							7  8  9  C
							*  0  #  D 
************************************/

u8 ee,Data0=0;
void Key_Test(void) 
{
    int num;
	char Freq[3]={'?'};
	  num = Key_Scan();
	if(ee!=num)
	  switch(num)
	  { 
			case 0: LCD_P6x8Str(1,1,"0"); break;
			case 1: LCD_P6x8Str(1,1,"1"); break;
			case 2: LCD_P6x8Str(1,1,"2"); break;
			case 3: LCD_P6x8Str(1,1,"3"); break;
			case 4: LCD_P6x8Str(1,1,"4"); break;
			case 5: LCD_P6x8Str(1,1,"5"); break;
			case 6: LCD_P6x8Str(1,1,"6"); break;
			case 7: LCD_P6x8Str(1,1,"7"); break;
			case 8: LCD_P6x8Str(1,1,"8"); break;
			case 9: LCD_P6x8Str(1,1,"9"); break;//
			case 'A': LCD_P6x8Str(1,1,"A");  mode=0;LCD_P6x8Str(3,16,"   Sine Wave   "); break;
			case 'B': LCD_P6x8Str(1,1,"B");  mode=1;LCD_P6x8Str(3,16,"  Square wave  "); break;
			case 'C': LCD_P6x8Str(1,1,"C");  mode=2;LCD_P6x8Str(3,16,"Ttiangular wave"); break;
			case 'D': LCD_P6x8Str(1,1,"D");  mode=3;LCD_P6x8Str(3,16," Sawtooth Wave "); break;
			case '#': LCD_P6x8Str(1,1,"#"); if(Data0>=5)Data0-=5; Freq[0]=(20-Data0/5)/10+'0';Freq[1]=(20-Data0/5)%10+'0'; LCD_P6x8Str(7,6*13,Freq); break;
			case '*': LCD_P6x8Str(1,1,"*"); if(Data0<50)Data0+=5; Freq[0]=(20-Data0/5)/10+'0';Freq[1]=(20-Data0/5)%10+'0'; LCD_P6x8Str(7,6*13,Freq); break;
      }
	  ee=num;
}

資料清單:

下載鏈接見文章最開頭
資料清單

  • 設(shè)計資料獲取聯(lián)系方式.doc

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風(fēng)險等級 參考價格 更多信息
SN74LVC1G08DCKT 1 Rochester Electronics LLC LVC/LCX/Z SERIES, 2-INPUT AND GATE, PDSO5, GREEN, PLASTIC, SC-70, 5 PIN
$0.94 查看
ASFL1-12.000MHZ-ERS-T 1 Abracon Corporation XTAL OSC XO 12.0000MHZ HCMOS TTL
$1.28 查看
ECS-.327-12.5-12QS-TR 1 ECS International Inc Parallel - Fundamental Quartz Crystal, 0.032768MHz Nom, SMD, 2 PIN

ECAD模型

下載ECAD模型
$1.31 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜