《智能儀器儀表設計與調試》課程設計報告
課程設計任務書 設計題目:基于單片機的波形發生器設計 |
| | | | | | | |
| | 1.要求設計的波形發生器完成以下功能: 1)運用單片機控制產生多種波形,這些波形包括三角波、方波、鋸齒波等。 2)信號發生器所產生的波形的頻率、幅值均為連續可調。 2. 擴展功能 1)在上位機將波形實時顯示出來。 2)用紅外線遙控器實現上述功能。 3)其它功能 | | | | 1. 布置儀表設計任務、方案設計 (1天) 2. 硬件設計、制作、調試 (1天) 3. 軟件設計、調試 (5天) 4. 綜合測試 (1天) 5. 成果展示、答辯 (1天) 6. 撰寫報告 (1天) 詳見進度安排表 | | - 程德福.智能儀器.機械工業出版社. 2009.9
- 胡文金. 單片機系統實訓教程.重慶:重慶大學出版社,2005
- 梁森. 自動檢測技術及應用.北京:機械工業出版社,2012
| |
| | 1.本表應在每次實施前一周由負責教師填寫二份,院系審批后交院系辦備案,一份由負責教師留用。2.若填寫內容較多可另紙附后。3.一題多名學生共用的,在設計內容、參數、要求等方面應有所區別。 |
系主任: 指導教師:
目錄
一、 設計任務和性能指標 1.1 設計任務 1.2 性能指標 二、設計方案 2.1硬件選擇 2.2 系統總體設計 三、系統硬件設計 3.1 單片機的最小系統 3.2 按鍵電路設計 3.3 LCD顯示的設計 四、系統軟件設計 4.1 主程序設計 4.2 LCD顯示子程序設計 4.3 D/A轉換子程序設計 五、調試及性能分析 5.1 調試步驟 5.2 性能分析 六、心得體會 參考文獻 附錄 1 系統硬件電路圖 附錄 2 程序代碼
一、 設計任務和性能指標
1.1 設計任務按要求設計波形發生器并完成相關功能: (1)運用單片機控制產生多種波形,這些波形包括三角波、方波、鋸齒波等。 (2)信號的發生器所產生波形的頻率、幅值均為連續可調。 擴展功能 在上位機將波形實時顯示出來,用紅外線遙控器實現上述功能,其它功能。 1.2 性能指標 (1)幅值0~5V可調 (2)頻率0~1KHz可調
二、設計方案 采用AT89C51單片機和數模轉換器PCF8591實現波形的產生。波形的產生方法是用AT89C51單片機執行波形程序,向PCF8591轉換器的輸入端輸入相應的數據,從而在DA轉換電路輸出端再通過運放電路轉換得到相應的電壓波形。在AT89C51的P1口接按鍵控制波形的各類和波形的頻率,每種波形對應一種按鍵方式。此方案原理簡單,同時適合操作,實現起來也相對較容易。產生的三種波形的頻率可由按鍵控制,并通過按鍵改變來轉換不同的波形,也能夠在示波器上顯示出所要求的波形。波形的頻率步進也可以實現調節,具有線路簡單、可行性高、符合設計要求等優點。加上LCD數碼顯示管,從而能夠在LCD上顯示出頻率值、幅度值信息。輸出的波形也較穩定,精度較高,通過濾波電路使得系統的抗干擾性增強,電路簡單,性價比高。
圖2.1系統組成結構框圖
2.1硬件選擇 (1)單片機:STC12C5AI6S2是高速/低功耗/超強抗干擾的新一代8051 單片機,指令代碼完全兼容傳統8051,但速度快8-12倍。內部集成MAX810 專用復位電路,2路PWM,8路高速10位A/D轉 換(250K/S),針對電機控制,強干擾場合。 (2)PCF8591:PCF8591是一個單片集成、單獨供電、低功耗、8-bit CMOS數據獲取器件。PCF8591具有4個模擬輸入、1個模擬輸出和1個串行I2C總線接口。PCF8591的3個地址引腳A0, A1和A2可用于硬件地址編程,允許在同個I2C總線上接入8個PCF8591器件,而無需額外的硬件。在PCF8591器件上輸入輸出的地址、控制和數據信號都是通過雙線雙向I2C總線以串行的方式進行傳輸。
2.2 系統總體設計 本系統是用單片機來控制波形的轉換以及幅值和頻率的改變的,所以該系 統可以分為4個電路模塊 ,下面是總體設計框圖。
圖2.2 系統總體設計框圖
三、系統硬件設計
3.1 單片機的最小系統 由于單片機最小系統只需要外圍有時鐘電路和復位電路即可,則單片機最小系統有著兩個外圍電路即可正常工作,下面是單片機的最小系統原理圖。
圖3.1 STC12C5AI6S2單片機最小系統
3.2 按鍵電路設計本實現采用4個按鍵來進行波形的轉換、幅值的改變、頻率的改變,P20鍵用來改變波P21、P22用來改變幅值的大小,P32用來改變頻率的大小,下面是按鍵電路圖。 圖3.2按鍵電路圖
3.3 LCD顯示的設計 本硬件采用的是12864-12L的液晶顯示屏,顯示屏將波形的轉化顯示在顯示屏上,下面是 液晶顯示的電路。
圖3.3 12864-12L液晶顯示電路
四、系統軟件設計
4.1 主程序設計 主程序內進行的是波形的切換及幅值、頻率的改變,用示波器和LCD顯示,將主要的寫進即可,其他的就寫在外面,下面是主程序流程圖。
圖4.1 主程序流程圖
4.2 LCD顯示子程序設計液晶顯示的程序在本程序中比較的簡單,就是為了實時的顯示出當前的波形是什么,用按鍵切換之后液晶顯示也跟著變。液晶顯示程序需首先初始化,再進行數據的傳輸,并進行字符的顯示,所以寫出相應的幾個程序即可進行LCD的顯示。
圖4.2 LCD 顯示流程圖 4.3 D/A轉換子程序設計本程序采用PCD8591來作D/A轉換器,需要將A1、A1、A2接地,單片機上的P1和P11接PCF8591上的SCL和SDA端口,AOUT接示波器,供顯示D/A轉換要滿足I2C協議才能進行數據的傳輸。
void write_add(uchar date) { start(); write_byte(0x90); respons(); write_byte(0x40); respons(); write_byte(date); respons(); stop();
}
五、調試及性能分析
5.1 調試步驟硬件調試:檢查線路連接有無錯誤,SDA和SCL接單片機的P10和P11口,VCC接電源,CND接地,AOUT接示波器,在下載數據到單片機之后數據在傳輸的時候PCF8591上的一個藍色的燈會不停的閃,說明有數據在傳輸,否則無數據傳輸。 軟件調試:首先看I2C協議是否正確,否則不能傳輸數據,再看按鍵的邏輯關系是否正確,還有就是LCD的顯示是否正確。 調節電源,使其輸出5V電壓,調整好示波器。給電路供電,觀察示波器,記錄各頻段對應波形的情況,峰峰值。調試結果表明,該電路在要求頻率范圍內的大部分頻率范圍基本上不失真,除了在最高頻率的最低頻率有少許失真,其中,當頻率接近10KHz時,方波高低電壓躍變時出現毛刺,審過零比較器的頻率特性所致,另外,在最高頻和最低頻段,三角波出現少許彎斜,可選用頻率特性更為寬的電容進行校正。
5.2 性能分析 經過一段時間運行后,可以對系統的性能進行測試。對于本波形發生器來說,用示波器可以測試其性能指標,按前面所述設計的波形發生器,能產生正弦波、三角波及方波信號,其幅值可以0—5V內變化,頻率也可以調整。
六、心得體會 在為期幾周的時間里,終于順利地完成了此次課程設計,并從中學習到了很多的知識和經驗,對單片機以及C語言有了更深刻的了解。本次課程設計也發現了許多問題,此次單片機的設計硬件電路較為簡單,而程序的設計在當中占據很重要的部分。這次課程設計是用STC12C5AI6S2單片機與PCF8591D/A轉換器來實現的波形產生與顯示,所以要對這兩個模塊非常的熟悉。對于PCF8591需要深入的認識I2C協議的內容才能正確的傳輸數據。而對于單片機而需要對各個接口非常熟悉,才能保證數據的正常傳輸。此外還要熟練的使用示波器,對產生的波形進行調整,來得到更好的效果。它考驗我們靈活的運用所學知識,培養了我們在遇到問題善于觸屏的良好學習態度,使我認識到設計思路更節省了時間。靈活運用,以書本知識為基礎靈活的擴展,學習前人的驗,向高層次邁進。當然還是存在不足的地方,例如當頻率過小的時候矩形波會有些失真,轉換器轉換可以加一個鎖存器,放大電路設計上還有待進一步改進,使其具有更強的輸出能力等。
附錄 1 系統硬件電路圖
單片機源程序如下: - #include<reg51.h>
- #include<intrins.h>
- #include<math.h>
- #define uchar unsigned char
- #define uint unsigned int
- unsigned long Result,i;
- sbit SDA=P1^1; //PCF8591 接口
- sbit SCL=P1^0;
- unsigned int a=0; //波形采樣點值
- unsigned int b=0;
- unsigned int c=0;
-
- unsigned int bx_chang=0;
- unsigned int n=40; //頻率計算值
- unsigned char TH;
- unsigned char TL;
- unsigned int mode=0; //0為調節幅度 1為調節頻率
- unsigned int fd=6; //幅度初值 3.0V
- unsigned int x; //采樣點的間隔
- unsigned int u; //lcd刷屏變量
- //*************
- sbit CS =P3^5; //LCD接口
- sbit SID=P3^6;
- sbit SCLK=P3^7;
- sbit PSB=P1^5;
- //*************
- sbit p20=P2^0; //波形調節
- sbit p21=P2^1; //增加 頻率、幅度
- sbit p22=P2^2; //減少 頻率、幅度
- sbit p32=P3^2; //頻率幅度選擇
-
- //sin波形數組
- uchar code tosin[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,0xDF,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
- };
-
-
- //***********************************************
-
- void delay(unsigned int z) //延遲函數
- { unsigned int x,y;
- for(x=z;x>0;x--)
- for(y=125;y>0;y--) ;
- }
- //***************************************************LCD顯示函數組
- void SendByte(unsigned char Dbyte) //LCD字節傳送
- {
- unsigned char i;
- CS=1;
- for(i=0;i<8;i++)
- { SCLK = 0;
- if((Dbyte<<i)&0x80)
- SID=1;
- else
- SID=0;
- SCLK = 1;
- SCLK = 0;
- }
- CS=0;
- }
-
- void Lcd_WriteCmd(unsigned char Cbyte ) //LCD的數據與指令傳送
- {
- delay(10);
- SendByte(0xf8);
- SendByte(0xf0&Cbyte);
- SendByte(0xf0&(Cbyte<<4));
- }
-
- void Lcd_WriteData(unsigned char Dbyte )
- {
- delay(10);
- SendByte(0xfa);
- SendByte(0xf0&Dbyte);
- SendByte(0xf0&(Dbyte<<4));
- }
- void InitLCD() //LCD初始化
- {
- Lcd_WriteCmd(0x30);
- Lcd_WriteCmd(0x06);
- Lcd_WriteCmd(0x0c);
- Lcd_WriteCmd(0x04);
- Lcd_WriteCmd(0x01);
- Lcd_WriteCmd(0x02);
- Lcd_WriteCmd(0x80);
- }
- void xianshi(unsigned char x,unsigned char y,unsigned char *stri) //LCD數據傳送地址
- {
- if(x==1) Lcd_WriteCmd(0x80+y-1);
- else if(x==2) Lcd_WriteCmd(0x90+y-1);
- else if(x==3) Lcd_WriteCmd(0x88+y-1);
- else if(x==4) Lcd_WriteCmd(0x98+y-1);
- while(*stri>0)
- {
- Lcd_WriteData(*stri);
- stri++;
- }
- }
- //****************************************************
-
- void delayp() //延遲函數
- {;;}
-
-
- void delay_1ms(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--)
- ;
- }
- //****************************************I2C協議
- void start()//開始信號
- {
- SDA=1;
- delayp();
- SCL=1;
- delayp();
- SDA=0;
- delayp();
- }
-
- void stop() //停止信號
- {
- SDA=0;
- delayp();
- SCL=1;
- delayp();
- SDA=1;
- delayp();
- }
-
-
- void respons()//應答 相當于一個智能的延時函數
- {
- uchar i;
- SCL=1;
- delayp();
- while((SDA==1)&&(i<250))
- i++;
- SCL=0;
- delayp();
- }
-
- void init() //初始化
- {
- SDA=1;
- delayp();
- SCL=1;
- delayp();
- }
-
- void write_byte(uchar date) //寫一字節數據
- {
- uchar i,temp;
- temp=date;
- for(i=0;i<8;i++)
- {
- temp=temp<<1; //左移一位 移出的一位在CY中
- SCL=0; //只有在scl=0時sda能變化值
- delayp();
- SDA=CY;
- delayp();
- SCL=1;
- delayp();
- }
- SCL=0;
- delayp();
- SDA=1;
- delayp();
- }
-
-
-
- void write_add(uchar date) //D/A轉換
- {
- start();
- write_byte(0x90);
- respons();
- write_byte(0x40);
- respons();
- write_byte(date);
- respons();
- stop();
-
- }
- //****************************************************
-
- int main()//************************************************主函數
- {
- TMOD = 0x01;
- TH0 = (65536-99000/n)/256; //定時時間
- TL0 = (65536-99000/n)%256;
- TH1 = (65536-5000)/256;
- TL1 = (65536-5000)%256;
- EA = 1;
- ET0 = 1;
- ET1 = 1;
- TR0 = 1;
- TR1 = 1;
- init();
- while(1)
- {
- PSB=0;
- InitLCD();
- //*******************************************顯示模塊
- for(u=0;u<9;u++)
- {
- xianshi(1,1,"信號發生器");
- xianshi(2,1,"波形:");
-
- if(bx_chang==0) xianshi(2,4,"sin");
- if(bx_chang==1) xianshi(2,4,"Square");
- if(bx_chang==2) xianshi(2,4,"Triangle");
- if(mode==0)
- {
- xianshi(3,1,"幅度:");
- Lcd_WriteData(0x30+(fd*5/10));
- xianshi(3,5,".");
- Lcd_WriteData(0x30+(fd*5%10));
- xianshi(3,6,"V");
- }
- if(mode==1)
- {
- xianshi(3,1,"頻率:");
- Lcd_WriteData(0x30+(n/2/100));
- Lcd_WriteData(0x30+(n/2/10));
- Lcd_WriteData(0x30+(n/2%10));
- xianshi(3,8,"HZ");
- }
- }
- }
- }
-
- //**************************************************************8
- void refresh_f( void ) interrupt 1 //定時器中斷
- {
-
- if(n>=0&&n<40)
- { x=14;
- TH0 = (65536-92900/n)/256;
- TL0 = (65536-92900/n)%256;
- }
- else if (n>=40&&n<80)
- { x=15;
- TH0 = (65536-97920/n)/256;
- TL0 = (65536-97920/n)%256;
- }
-
-
- //*************************************正弦波形
- a=a+x;
- if(a<256&&bx_chang==0)
- {
- write_add(tosin[a]*0.1*fd);
-
- }
- if(a>=256)
- {
- a=0;
- }
-
- //************************************方波波形
-
- b=b+x;
- if(b<128&&bx_chang==1)
- {
- write_add(0x00*0.1*fd);
-
- }
- if(b>=128&&b<256&&bx_chang==1)
- write_add(0xff*0.1*fd);
- if(b>=256)
- {
- b=0;
- }
-
-
-
-
- //*************************************三角波波形
- c=c+x;
-
- if(c<128&&bx_chang==2)
-
- {
-
- write_add(c*0.2*fd);
- }
- if(c>=128&&c<256&&bx_chang==2)
- write_add((-c+256)*0.2*fd);
-
-
- if(c>=256)
- {
- c=0;
- }
-
- }
- //********************************************定時器中斷 按鍵中斷
- void refresh_zd( void ) interrupt 3
- {
-
- TH1 = (65536-5000)/256; //5000us
- TL1 = (65536-5000)%256;
- //*******************************************8
- if(p32==0) //頻率或者幅度調節選擇
- {
-
- delay_1ms(1000);
- if(p32==0)
- mode=mode+1;
- if(mode>=2)
- mode=0;
-
- }
- if(p20==0) //波形選擇
- {
- delay_1ms(1000);
- bx_chang=bx_chang+1;
- if(bx_chang>=3)
- bx_chang=0;
-
- }
- //*******************************************頻率調節
- if(p21==0&&mode==1)
- {
- delay_1ms(1000);
- n=n+2;
- if(n>=120)
- n=1;
-
- }
- if(p22==0&&mode==1)
- {
- delay_1ms(1000);
- n=n-2;
- if(n<=0)
- n=120;
-
- }
- //*******************************************幅度調節
- if(p21==0&&mode==0)
- {
- delay_1ms(1000);
- fd=fd+1;
- if(fd>=10)
- fd=1;
-
- }
- if(p22==0&&mode==0)
- {
- delay_1ms(1000);
- fd=fd-1;
- if(fd<=1)
- fd=10;
-
- }
- }
復制代碼
所有資料51hei提供下載:
|