仿真圖:
51hei.png (96.6 KB, 下載次數: 37)
下載附件
2020-12-2 15:58 上傳
51hei.png (19.52 KB, 下載次數: 55)
下載附件
2020-12-2 15:57 上傳
1763378e93d09013472c7cb0dac72cd2.png (53.38 KB, 下載次數: 54)
下載附件
2020-12-2 15:04 上傳
系統功能設計框圖該系統采用單片機作為數據處理及控制核心,由單片機完成人機界面、系統控制、信號的采集分析以及信號的處理和變換,采用按鍵輸入,利用虛擬示波器顯示波形的方案。將設計任務分解為按鍵電路、輸出轉換電路等模塊。圖3-1為系統的總體框圖。
 圖3-1 總體方框圖
3、系統設計原理圖
4.1 單片機最小系統的設計AT89C51是片內有ROM/EPROM的單片機,因此,這種芯片構成的最小系統簡單﹑可靠。用AT89C51單片機構成最小應用系統時,只要將單片機接上時鐘電路和復位電路即可,如圖89C51單片機最小系統所示。由于集成度的限制,最小應用系統只能用作一些小型的控制單元。其應用特點: (1)有可供用戶使用的大量I/O口線。 (2)內部存儲器容量有限。 (3)應用系統開發具有特殊性。 標準的51為8K程序空間,128字節的RAM,32條端口,5個中斷,2個定時/計數器,12個時鐘周期執行一條基本指令,最長的除法為48個周期。 圖4-1 AT89C51單片機最小系統 4.2運算放大器電路本系統的放大電路如圖4-2所示: 圖4-2運算放大器電路 4.3 波形產生原理及模塊設計波形產生的原理: 1、內存中首先存儲波形的數字量值數組TABLE; 2、51單片機讀取數組中的值,送入D/A轉換器; 3、D/A轉換器將輸入的數字值轉換成模擬量輸出; 4、D/A輸出的模擬電流量通過運放轉換成電壓量輸出。 由單片機采用編程方法產生四種波形、通過DA轉換模塊DAC0832在進過濾波放大之后輸出。其電路圖4-3如下: 圖4-3波形產生電路
4.4控制系統設計電路圖 圖4-4 系統設計電路圖
4、程序設計流程圖
圖5-1 程序設計流程圖
5、系統仿真將keil5編譯產生的hex文件加載到仿真軟件的單片機里后,單擊仿真界面左下方的開始按扭,仿真就開始了。具體仿真過程如下: (1)f=50HZ正弦波的調試結果 圖6-1 正弦波的調試結果 (2)f=50HZ方波的調試結果 圖6-2 方波的調試結果 (3)f=50HZ三角波的調試結果 圖6-3 三角波的調試結果
程序代碼:
- #include <reg52.H>
- #include<absacc.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define dz XBYTE[0x7fff]//dac0832總線地址
- //1602LCD相關
- sbit RS = P3^0; //定義端口
- sbit EN = P3^1;
- //按鍵定義
- sbit key1 = P3^2;
- sbit key2 = P3^3;
- sbit key3 = P3^4;
- sbit key4 = P3^5;
- uchar mode = 0;//輸出波形的模式
- uchar LCDFlag;//LCD更新顯示標志
- uchar LCDbuf[16];//LCD顯示緩存
- uchar TIMER_H;//給計數器的值
- uchar TIMER_L;
- int Fre10X = 200;//當前頻率的10的倍數 此時為20.0hz
- uchar CurStal = 1;//步進檔位1=0.1x 10=1x 100=10x
- uchar code WaveInfo[3][15] = {"Sine Wave ",//顯示當前波形類型
- "Triangle Wave ",
- "Square Wave "};
- uchar i = 0;
- //方波
- uchar code Squaretab[64] = {0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255
- };
- //sin波
- uchar code Sinetab[256] = {
- 0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,0x9f,0xa2,
- 0xa5,0xa8,0xab,0xae,0xb1,0xb4,0xb7,0xba,0xbc,0xbf,0xc2,0xc5,
- 0xc7,0xca,0xcc,0xcf,0xd1,0xd4,0xd6,0xd8,0xda,0xdd,0xdf,0xe1,
- 0xe3,0xe5,0xe7,0xe9,0xea,0xec,0xee,0xef,0xf1,0xf2,0xf4,0xf5,
- 0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,
- 0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf2,0xf1,
- 0xef,0xee,0xec,0xea,0xe9,0xe7,0xe5,0xe3,0xe1,0xde,0xdd,0xda,
- 0xd8,0xd6,0xd4,0xd1,0xcf,0xcc,0xca,0xc7,0xc5,0xc2,0xbf,0xbc,
- 0xba,0xb7,0xb4,0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99,
- 0x96,0x93,0x90,0x8d,0x89,0x86,0x83,0x80,0x80,0x7c,0x79,0x76,
- 0x72,0x6f,0x6c,0x69,0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,0x51,
- 0x4e,0x4c,0x48,0x45,0x43,0x40,0x3d,0x3a,0x38,0x35,0x33,0x30,
- 0x2e,0x2b,0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a,0x18,0x16,
- 0x15,0x13,0x11,0x10,0x0e,0x0d,0x0b,0x0a,0x09,0x08,0x07,0x06,
- 0x05,0x04,0x03,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x02,0x03,0x04,0x05,
- 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0d,0x0e,0x10,0x11,0x13,0x15,
- 0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b,0x2e,
- 0x30,0x33,0x35,0x38,0x3a,0x3d,0x40,0x43,0x45,0x48,0x4c,0x4e,
- 0x51,0x55,0x57,0x5a,0x5d,0x60,0x63,0x66 ,0x69,0x6c,0x6f,0x72,
- 0x76,0x79,0x7c,0x80 };
- //三角
- uchar code Triangletab[64] = {
- 0, 8, 16, 24, 32, 40, 48, 56,
- 64, 72, 80, 88, 96,104,112,120,
- 128,136,144,152,160,168,176,184,
- 192,200,208,216,224,232,240,248,
- 248,240,232,224,216,208,200,192,
- 184,176,168,160,152,144,136,128,
- 120,112,104, 96, 88, 80, 72, 64,
- 56, 48, 40, 32, 24, 16, 8, 0};
- //鋸齒
- uchar code juchi[64] = {
- 0,4,8,12,16,20,24,28,32,36,40,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,130,134,138,142,
- 146,150,154,158,162,166,170,174,178,182,186,190,194,198,202,206,210,215,219,223,227,231,235,239,243,247,251,255
- };
- //uS延時函數
- void DelayUs2x(uchar t)
- {
- while(--t);
- }
- //mS延時函數
- void DelayMs(uint t)
- {
- while(t--)
- {
- DelayUs2x(245);
- DelayUs2x(245);
- }
- }
- // 寫入命令函數
- void LCD_Write_Com(uchar com)
- {
- RS = 0;
- EN = 1;
- P1 = com; //送入數據
- DelayUs2x(200);
- EN = 0;
- DelayUs2x(500); //延時等待LCD處理數據
- }
- // 寫入數據函數
- void LCD_Write_Data(unsigned char Data)
- {
- RS = 1;
- EN = 1;
- P1 = Data; //送入數據
- DelayUs2x(200);
- EN = 0;
- DelayUs2x(500); //延時等待LCD處理數據
- }
- // 清屏函數
- void LCD_Clear(void)
- {
- LCD_Write_Com(0x01);
- DelayMs(5);
- }
- // 寫入字符串函數
- void LCD_Write_String(uchar x, uchar y, uchar *s)
- {
- if(y == 0)
- {
- LCD_Write_Com(0x80 + x); //表示第一行
- }
- else
- {
- LCD_Write_Com(0xC0 + x); //表示第二行
- }
- while(*s)
- {
- LCD_Write_Data(*s);
- s++;
- }
- }
- /**************************************************
- 初始化函數
- ***************************************************/
- void LCD_Init(void)
- {
- LCD_Write_Com(0x38); //顯示模式設置
- DelayMs(5);
- LCD_Write_Com(0x38);
- DelayMs(5);
- LCD_Write_Com(0x38);
- LCD_Write_Com(0x08); //顯示關閉
- LCD_Write_Com(0x01); //顯示清屏
- LCD_Write_Com(0x06); //顯示光標移動設置
- DelayMs(5);
- LCD_Write_Com(0x0C); //顯示開及光標設置
- }
- /**************************************************
- 在LCD指定位置顯示光標
- **************************************************/
- void LCD_Cursor_Dis(uchar x, uchar y)
- {
- if(y == 0) //LCD第一行
- {
- LCD_Write_Com(0x80 + x);
- }
- else //LCD第二行
- {
- LCD_Write_Com(0xC0 + x);
- }
- LCD_Write_Com(0x0F); //光標顯示開
- DelayUs2x(4); //延時越40us
- }
- /**************************************************
- 關閉光標
- **************************************************/
- void LCD_Close_Cursor()
- {
- LCD_Write_Com(0x0C); //光標顯示關
- DelayUs2x(4); //延時越40us
- }
- void keyscanf() //按鍵掃描
- {
- uint temp;
- if(key1 == 0)//模式選擇
- {
- mode++;
- LCDFlag = 1;
- if(mode == 4)
- mode = 0;
- while(!key1);
- }
- if(key2 == 0)//增加
- {
- if((Fre10X + CurStal) < 501)
- {
- Fre10X = Fre10X + CurStal;
- temp = (unsigned long)10000000 / 64 / Fre10X;
- TIMER_H = (65535 - temp) / 256;
- TIMER_L = (65535 - temp) % 256;
- }
- LCDFlag = 1;
- while(!key2);
- }
- if(key3 == 0)
- {
- if((Fre10X - (int)CurStal) > 1)
- {
- Fre10X = Fre10X - CurStal;
- temp = (unsigned long)10000000 / 64 / Fre10X;
- TIMER_H = (65535 - temp) / 256;
- TIMER_L = (65535 - temp) % 256;
- }
- LCDFlag = 1;
- while(!key3);
- }
- if(key4 == 0)
- {
- switch(CurStal)//調整步進檔位
- {
- case 1: CurStal = 10;
- break;
- case 10: CurStal = 100;
- break;
- case 100: CurStal = 1;
- break;
- }
- LCDFlag = 1;
- while(!key4);
- }
- }
- void init_time()
- {
- EA = 1; //開中斷
- ET0 = 1;
- TMOD = 0X01; //初始化
- TR0 = 1; //開定時器
- }
- void time0() interrupt 1 using 2
- {
- TH0 = TIMER_H;
- TL0 = TIMER_L;
- switch(mode)
- {
- case 0://正弦顯示
- dz = Sinetab[i];
- i = i + 4;
- break;
- case 1://三角顯示
- dz = Triangletab[i];
- i = (i + 1) % 64;
- break;
- case 2://方波顯示
- dz = Squaretab[i];
- i = (i + 1) % 64;
- break;
- case 3://鋸齒波顯示
- dz = juchi[i];
- i = (i + 1) % 64;
- break;
- }
- }
- void main()
- {
- uint temp;
- init_time(); //定時器初始化調用
- mode = 1;
- temp = (unsigned long)10000000 / 64 / Fre10X;
- TIMER_H = (65535 - temp) / 256;
- TIMER_L = (65535 - temp) % 256;
- LCD_Init(); //初始化液晶
- LCDFlag = 1; //將液晶需要刷新標志置1
- while(1)
- {
- keyscanf(); //按鍵一直掃描
- if(LCDFlag)
- {
- LCD_Write_String(0, 0, WaveInfo[mode]);//顯示當期選擇的波形
- LCDbuf[0] = Fre10X / 100 + 0x30; //顯示當前的頻率
- LCDbuf[1] = Fre10X / 10 % 10 + 0x30; //
- LCDbuf[2] = '.'; //
- LCDbuf[3] = Fre10X % 10 + 0x30; //
- LCDbuf[4] = 'H'; //
- LCDbuf[5] = 'z'; //
- LCDbuf[6] = 0; //
- LCD_Write_String(0, 1, LCDbuf);//
- switch(CurStal)//顯示當前選擇的步進檔位
- {
- case 1: LCD_Write_String(8, 1, "+- 0.1Hz");
- break;
- case 10: LCD_Write_String(8, 1, "+- 1Hz");
- break;
- case 100:LCD_Write_String(8, 1, "+- 10Hz");
- break;
- }
- LCDFlag = 0;
- }
- }
- }
復制代碼 全部資料51hei下載地址:
簡易信號發生器.zip
(663.31 KB, 下載次數: 17)
2020-12-2 13:25 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|