標(biāo)題: 單片機(jī)-波形發(fā)生器實訓(xùn)報告 [打印本頁]

作者: 錯過12545    時間: 2017-12-30 09:53
標(biāo)題: 單片機(jī)-波形發(fā)生器實訓(xùn)報告
實訓(xùn)任務(wù)書        2
摘  要        4
Abstract        4
波形發(fā)生器的設(shè)計        5
1.1 實訓(xùn)目的        5
1.2 實訓(xùn)內(nèi)容        5
1.3 實訓(xùn)步驟        5
1.4 Keil uVision簡介        6
1.5 實驗原理        7
1.5.1 數(shù)碼管顯示原理        7
1.5.2 各種波形產(chǎn)生思路        8
1.6 DAC0832介紹        10
1.6.1 DAC0832的主要特性參數(shù)        11
1.6.2 DAC0832結(jié)構(gòu)        11
1.6.3 DAC0832工作方式        12
1.7 程序        13
1.7.1 主程序        13
1.7.2 VIIC_C51.C        22
1.7.3 ZLG7290        33
實訓(xùn)心得        38
參考文獻(xiàn)        39

實訓(xùn)任務(wù)書
課程名稱    微計算機(jī)應(yīng)用及計控技術(shù)實訓(xùn)
實訓(xùn)地點    秋實樓        時間    2015年1月
項目    波形發(fā)生器的設(shè)計
指導(dǎo)教師    賈玉瑛、李愛蓮、梁麗、陳波、李琦
一、實訓(xùn)目的
1、掌握使用D/A轉(zhuǎn)換器生成用戶所需要的波形;
2、掌握數(shù)/模轉(zhuǎn)換的基本原理及編程方法;
3、掌握D/A轉(zhuǎn)換芯片DAC0832的結(jié)構(gòu)特點、工作原理及使用方法;

二、基本要求  
(1)預(yù)習(xí)要求:學(xué)生要根據(jù)實訓(xùn)題目要求查閱參考資料,提前進(jìn)行認(rèn)真的預(yù)習(xí),初步弄懂實訓(xùn)內(nèi)容、原理,并寫出預(yù)習(xí)報告;預(yù)習(xí)報告應(yīng)包括基本的實訓(xùn)內(nèi)容和實訓(xùn)方案,基本實訓(xùn)步驟、過程以及數(shù)據(jù)記錄,對于有設(shè)計內(nèi)容的項目要提前做好設(shè)計方案。  
(2)操作要求:學(xué)生要搞清本次實訓(xùn)需使用的儀器,每種儀器在實訓(xùn)中所起的作用,合理選擇使用儀器,正確使用測量方法。根據(jù)已設(shè)計的實訓(xùn)步驟并經(jīng)老師同意后開始實訓(xùn)。學(xué)生要認(rèn)真觀察分析實訓(xùn)現(xiàn)象, 記錄實訓(xùn)數(shù)據(jù)。運(yùn)用所學(xué)知識解決實訓(xùn)中發(fā)生的問題;每項實訓(xùn)結(jié)果,需經(jīng)教師認(rèn)可后,方可結(jié)束實訓(xùn);實訓(xùn)后認(rèn)真填寫實訓(xùn)記錄。  
(3)實訓(xùn)報告要求:學(xué)生在做完實訓(xùn)后,科學(xué)地、真實地、完整地完成實訓(xùn)報告。實  訓(xùn)報告應(yīng)包括實訓(xùn)原理、實訓(xùn)方法的概述;實訓(xùn)步驟的描述;實訓(xùn)現(xiàn)象和實訓(xùn)數(shù)據(jù)的記載;

三、實訓(xùn)內(nèi)容
1、設(shè)計軟件程序,通過DAC0832實現(xiàn)D/A轉(zhuǎn)換,使其分別產(chǎn)生三角波、個鋸齒波、方波;
2、設(shè)計一個單片機(jī)系統(tǒng),能夠在不同開關(guān)控制下輸出不同的波形形式。
3、利用2*4鍵盤輸入加四位LED顯示器顯示,改變波形的周期。

四、參考資料
1、DAC08320的數(shù)據(jù)手冊。
2、參考《單片機(jī)實驗與實驗教程》實驗37內(nèi)容。

五、實訓(xùn)步驟
1、參考實驗37進(jìn)行接線
2、開關(guān)線接到單片機(jī)的P1口,自己設(shè)計接線。
3、運(yùn)行程序觀察結(jié)果,通過開關(guān)控制輸出波形的形式,用示波器觀察輸出的波  形。

      摘  要
   本設(shè)計是波形發(fā)生器的設(shè)計,以 51單片機(jī)為核心,通過按鍵輸入控制輸出信號的類型、頻率,采用 D/A轉(zhuǎn)換芯片DAC0832輸出相應(yīng)的波形,同時以LED 顯示器進(jìn)行實時顯示信號相關(guān)信息。我們采用 C 語言進(jìn)行編程,可實現(xiàn)方波,鋸齒波,三角波,三種波形的產(chǎn)生,且波形的類型、頻率可通過按鍵調(diào)節(jié),并頻率顯示在數(shù)碼管上。
關(guān)鍵字:單片機(jī)、D/A轉(zhuǎn)換芯片DAC0832


        Abstract
This design is the design of waveform generator, using 51 single chip microcomputer as the core, through the key input type, frequency control output signal, using D/A conversion chip DAC0832 the corresponding output waveform, simultaneously by LED display to display information related to real time signal. We use C language to program, can achieve a square wave, sawtooth wave, triangle wave, three kinds of waveform generation, type, frequency and waveform can be adjusted via buttons, and frequency in the digital tube display.
Key word: Microcontroller, D/A conversion chip DAC0832


波形發(fā)生器的設(shè)計

一.1 實訓(xùn)目的1、掌握使用D/A轉(zhuǎn)換器生成用戶所需要的波形;
2、掌握數(shù)/模轉(zhuǎn)換的基本原理及編程方法;
3、掌握D/A轉(zhuǎn)換芯片DAC0832的結(jié)構(gòu)特點、工作原理及使用方法;

一.2 實訓(xùn)內(nèi)容1、設(shè)計軟件程序,通過DAC0832實現(xiàn)D/A轉(zhuǎn)換,使其分別產(chǎn)生三角波、個鋸齒波、方波;
2、設(shè)計一個單片機(jī)系統(tǒng),能夠在不同開關(guān)控制下輸出不同的波形形式。
3、利用2*4鍵盤輸入加四位LED顯示器顯示,改變波形的周期。

一.3 實訓(xùn)步驟1、參考實驗37進(jìn)行接線
2、開關(guān)線接到單片機(jī)的P1口,自己設(shè)計接線。
3、運(yùn)行程序觀察結(jié)果,通過開關(guān)控制輸出波形的形式,用示波器觀察輸出的波形。

一.4 Keil uVision簡介
Keil C51是美國Keil Software公司出品的51系列兼容單片機(jī)C語言軟件開發(fā)系統(tǒng),與匯編相比,C語言在功能上、結(jié)構(gòu)性、可讀性、可維護(hù)性上有明顯的優(yōu)勢,因而易學(xué)易用。Keil提供了包括C編譯器、宏匯編、連接器、庫管理和一個功能強(qiáng)大的仿真調(diào)試器等在內(nèi)的完整開發(fā)方案,通過一個集成開發(fā)環(huán)境(uVision)將這些部分組合在一起。運(yùn)行Keil軟件需要WIN98、NT、WIN2000、WINXP等操作系統(tǒng)。如果你使用C語言編程,那么Keil幾乎就是你的不二之選,即使不使用C語言而僅用匯編語言編程,其方便易用的集成環(huán)境、強(qiáng)大的軟件仿真調(diào)試工具也會令你事半功倍。
優(yōu)點:
1.Keil C51生成的目標(biāo)代碼效率非常之高,多數(shù)語句生成的匯編代碼很緊湊,容易理解。在開發(fā)大型軟件時更能體現(xiàn)高級語言的優(yōu)勢。
2.與匯編相比,C語言在功能上、結(jié)構(gòu)性、可讀性、可維護(hù)性上有明顯的優(yōu)勢,因而易學(xué)易用。用過匯編語言后再使用C來開發(fā),體會更加深刻。 Keil C51軟件提供豐富的庫函數(shù)和功能強(qiáng)大的集成開發(fā)調(diào)試工具,全Windows界面


一.5 實驗原理一.5.1 數(shù)碼管顯示原理
一位 LED 顯示器由 8 個發(fā)光二極管組成,其中 7 個發(fā)光二極管 a-h控制 7 個筆畫段的亮或暗,另一位控制一個小數(shù)點的亮和暗。LED 顯示器有共陰極和共陽極 2 種形式。共陽極顯示器是發(fā)光二極管的陽極連接在一起,當(dāng)需要顯示某字符時,只需要將共陽極端接高電平,a-h 中某些位接低電平即可。共陰極顯示器是發(fā)光二極管的陰極連接在一起,當(dāng)需要顯示某字符時,只需要將共陰極端接低電平,a-h 中某些位接高電平即可。
顯示器的工作方式
顯示器的工作方式分為靜態(tài)顯示方式和動態(tài)顯示方式兩種。
☞ 靜態(tài)顯示方式
靜態(tài)顯示方式就是顯示器在顯示一個字符時,相應(yīng)的發(fā)光二極管恒定的導(dǎo)通或截止,例如 a、b、c、、e、f 導(dǎo)通,g 截止時顯示“0”,這種使顯示器顯示字符的字形數(shù)據(jù)常稱為段數(shù)據(jù)。靜態(tài)顯示方式的每一個七段顯示器,需要由一個 8 位并行口控制。優(yōu)點是顯示穩(wěn)定,提高了工作效率,缺點是位數(shù)較多時顯示口隨之增加。
☞ 動態(tài)顯示方式
動態(tài)顯示方式是一位一位的輪流點亮各位顯示器,對于每一位顯示器來說,每隔一段時間點亮一次。顯示器的亮度既與導(dǎo)通電流有關(guān),也與點亮?xí)r間和間隔時間的比例有關(guān)。調(diào)整電流和時間參數(shù)可以實現(xiàn)亮度較高較穩(wěn)定的顯示,如顯示器的位數(shù)不大于 8 位,則控制顯示器公共極的電位只需要一個 8 位口(位數(shù)據(jù)口),控制字形也需要一個 8 位口(段數(shù)據(jù)口)。
數(shù)碼管字型碼
要使顯示管顯示不同的數(shù)字或者字符,需要使端口輸出相應(yīng)的字型碼
顯示器字形與字型碼對應(yīng)關(guān)系表

一.5.2 各種波形產(chǎn)生思路【1】 方波產(chǎn)生思路
方波的產(chǎn)生比較簡單,只需要根據(jù)按鍵輸入的幅值和頻率計算出相應(yīng)的DA數(shù)據(jù)送給數(shù)據(jù)就可以產(chǎn)生相應(yīng)的波形。
具體來說,例如產(chǎn)生500Hz的2.5V的波形。
首先,要計算出定時器的定時頻率,由于,方波只有兩種狀態(tài),峰值和0值。峰值時由按鍵設(shè)定的,其中峰值占一個周期的一半,即要定時產(chǎn)生1000Hz的定時器頻率,每進(jìn)一次中斷函數(shù)就把DA的數(shù)據(jù)更新為上次值的取反。讓DA數(shù)據(jù)在峰值和0之間依次切換即可。

【2】 鋸齒波產(chǎn)生思路
首先,根據(jù)按鍵設(shè)定的波形頻率,選擇一個周期內(nèi)合適的點數(shù),根據(jù)點數(shù)和峰值計算相鄰3個點的幅度的步進(jìn)值,根據(jù)點數(shù)和頻率設(shè)定相鄰3點的時間值,計算出定時器的初值,然后從0開始逐漸疊加,當(dāng)疊加到最高點,然后溢出歸零。

【3】 三角波產(chǎn)生思路
首先,根據(jù)按鍵設(shè)定的波形頻率,選擇一個周期內(nèi)合適的點數(shù),根據(jù)點數(shù)和峰值計算相3個點的幅度的步進(jìn)值,根據(jù)點數(shù)和頻率設(shè)定相鄰3點的時間值,計算出定時器的初值,然后,設(shè)置一個變量每進(jìn)一次定時中斷DA數(shù)據(jù)就加幅值步進(jìn),當(dāng)?shù)扔诳傸c數(shù)的一半時,每進(jìn)一次定時中斷就把DA數(shù)據(jù)減幅值步進(jìn)直到DA數(shù)據(jù)為0,計數(shù)變量清零。每進(jìn)一次定時中斷輸出刷新DA的數(shù)據(jù)就可以產(chǎn)生一定頻率和幅值的三角波。


一.6 DAC0832介紹    DAC0832是8分辨率的D/A轉(zhuǎn)換集成芯片。與微處理器完全兼容。這個DA芯片以其價格低廉、接口簡單、轉(zhuǎn)換控制容易等優(yōu)點,在單片機(jī)應(yīng)用系統(tǒng)中得到廣泛的應(yīng)用。D/A轉(zhuǎn)換器由8位輸入鎖存器、8位DAC寄存器、8位D/A轉(zhuǎn)換電路及轉(zhuǎn)換控制電路構(gòu)成。

一.6.1 DAC0832的主要特性參數(shù)  * 分辨率為8位;
  * 電流穩(wěn)定時間1us;
  * 可單緩沖、雙緩沖或直接數(shù)字輸入;
  * 只需在滿量程下調(diào)整其線性度;
  * 單一電源供電(+5V~+15V);
* 低功耗,20mW。
一.6.2 DAC0832結(jié)構(gòu)* D0~D7:8位數(shù)據(jù)輸入線,TTL電平,有效時間應(yīng)大于90ns(否則鎖存器的數(shù)據(jù)會出錯);
* ILE:數(shù)據(jù)鎖存允許控制信號輸入線,高電平有效;
* CS:片選信號輸入線(選通數(shù)據(jù)鎖存器),低電平有效;
* WR1:數(shù)據(jù)鎖存器寫選通輸入線,負(fù)脈沖(脈寬應(yīng)大于500ns)有效。由ILE、CS、WR1的邏輯組合產(chǎn)生LE1,當(dāng)LE1為高電平時,數(shù)據(jù)鎖存器狀態(tài)隨輸入數(shù)據(jù)線變換,LE1的負(fù)跳變時將輸入數(shù)據(jù)鎖存;
* XFER:數(shù)據(jù)傳輸控制信號輸入線,低電平有效,負(fù)脈沖(脈寬應(yīng)大于500ns)有效;
* WR2:DAC寄存器選通輸入線,負(fù)脈沖(脈寬應(yīng)大于500ns)有效。由WR2、XFER的邏輯組合產(chǎn)生LE2,當(dāng)LE2為高電平時,DAC寄存器的輸出隨寄存器的輸入而變化,LE2的負(fù)跳變時將數(shù)據(jù)鎖存器的內(nèi)容打入DAC寄存器并開始D/A轉(zhuǎn)換。
* IOUT1:電流輸出端1,其值隨DAC寄存器的內(nèi)容線性變化;
* IOUT2:電流輸出端2,其值與IOUT1值之和為一常數(shù);
* Rfb:反饋信號輸入線,改變Rfb端外接電阻值可調(diào)整轉(zhuǎn)換滿量程精度;
* Vcc:電源輸入端,Vcc的范圍為+5V~+15V;
* VREF:基準(zhǔn)電壓輸入線,VREF的范圍為-10V~+10V;
* AGND:模擬信號地
* DGND:數(shù)字信號地



一.6.3 DAC0832工作方式⑴單緩沖方式。單緩沖方式是控制輸入寄存器和DAC寄存器同時接收資料,或者只用輸入寄存器而把DAC寄存器接成直通方式。此方式適用只有一路模擬量輸出或幾路模擬量異步輸出的情形。
⑵雙緩沖方式。雙緩沖方式是先使輸入寄存器接收資料,再控制輸入寄存器的輸出資料到DAC寄存器,即分兩次鎖存輸入資料。此方式適用于多個D/A轉(zhuǎn)換同步輸出的情節(jié)。
⑶直通方式。直通方式是資料不經(jīng)兩級鎖存器鎖存,即 CS*,XFER* ,WR1* ,WR2* 均接地,ILE接高電平。此方式適用于連續(xù)反饋控制線路和不帶微機(jī)的控制系統(tǒng),使用時,必須通過另加I/O接口與CPU連接,以匹配CPU與D/A轉(zhuǎn)換。






一.7 程序一.7.1 主程序#include"reg51.h"
#include"ZLG7290.h"
#include"VIIC_C51.h"
#include"absacc.h"
#include"intrins.h"
#define PA XBYTE[0xfff]
#define uchar unsigned char
#define uint unsigned int
uchar  count,change ,val,num,zk,keyport;
uchar code Table[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
bit flag,ful_flag;
uint cycle;

uint bai,shi,ge,shu;
void KeyScan(void);
void delay(uint time);

void fangbo(void);
void juchi();
void sanjiao();
void out();
void Init();
void display();


void main()
{
    Init();
        while(1)
        {
          KeyScan();
          display();
        }
}

void time0()interrupt 1
{
   switch(cycle)
   {
    case 0:{TH0=(65536-461)/256;TL0=(65536-461)%256;  break;}
        case 1:{TH0=(65536-921)/256;TL0=(65536-921)%256;  break;}
        case 2:{TH0=(65536-1382)/256;TL0=(65536-1382)%256;  break;}
   }
                out();

}

void Init()
{
    TMOD|=0X01;
        TR0=1;
        EA=1;
        ET0=1;
        TH0=(65536-461)/256;
        TL0=(65536-461)%256;
}

void fangbo()
{
                change++;
                if(change<42)
                PA=255;
                else
                PA=0;
                if(change==85)
                change=0;


}

void juchi()
{
                PA=val;
                val+=3;                       
}

void sanjiao()
{
                if(ful_flag==0)
                {
                   val+=3;
                   PA=val;
                }
                if(val>=255)
                  ful_flag=1;
           if(ful_flag==1)
                {
                   val-=3;
                   PA=val;
                }
                if(val<3)
                   ful_flag=0;               
}

void  out()
{
        if(num==1)
        {
                sanjiao();
        }
          if(num==2)
        {
                juchi();
        }
          if(num==3)
        {
                fangbo();
        }
          if(zk==1)
        {
                cycle=0;
                zk=0;                       
        }
          if(zk==2)
        {
               
                cycle=1;
                zk=0;
        }
     if(zk==3)
        {
                cycle=2;
                zk=0;
        }

}

void display()
{  
if(cycle==0)
   {         
      if(num==1)
      shu=1*85;
          else
          shu=0.5*85;

      bai=shu/100;
      shi=shu%100/10;
      ge=shu%10;
  
   }
   if(cycle==1)
  {
      if(num==1)
       shu=2*85;
          else
          shu=1*85;

      bai=shu/100;
      shi=shu%100/10;
      ge=shu%10;

   }
   if(cycle==2)
  {
     if(num==1)
     shu=3*85;
          else
           shu=1.5*85;
       bai=shu/100;
      shi=shu%100/10;
      ge=shu%10;         
   }
//   com1=0;com2=1;com3=1;
//   Send_164(Table[bai]);
//   delay(4);
//        com1=1;com2=0;com3=1;
//   Send_164(Table[shi]);
//   delay(4);
//    com1=1;com2=1;com3=0;
//   Send_164(Table[ge]);
//   delay(4);

     ZLG7290_SendCmd(0x60,Table[ge]);
     delay(1);
     ZLG7290_SendCmd(0x60+1,Table[shi]);
     delay(1);
     ZLG7290_SendCmd(0x60+2,Table[bai]);
     delay(1);
}

void delay(uint time)        //1ms
{
   uint i,j;
   for(i=time;i<0;i--)
     for(j=110;j<0;j--);
}
void KeyScan(void)  
{
     
     keyport=ZLG7290_GetKey();
       switch(keyport)
      {
          case 1:num=1;break;
          case 2:num=2;break;
                  case 3:num=3;break;
          case 4:zk=1;break;
          case 5:zk=2;break;
          case 6:zk=3;break;
}

}




一.7.2 VIIC_C51.C  此程序是I2C操作平臺(主方式的軟件平臺)的底層的C子程序,如發(fā)送數(shù)據(jù)
及接收數(shù)據(jù)              
#include <reg52.h>          /*頭文件的包含*/
#include <intrins.h>
#define  uchar unsigned char /*宏定義*/
#define  uint  unsigned int

#define  _Nop()  _nop_()        /*定義空指令*/

/* 常,變量定義區(qū) */

                                                 /*端口位定義*/
sbit SDA=P1^7;            /*模擬I2C數(shù)據(jù)傳送位*/
sbit SCL=P1^6;            /*模擬I2C時鐘控制位*/

                                                 /*狀態(tài)標(biāo)志*/
bit ack;                 /*應(yīng)答標(biāo)志位*/
   /*******************************************************************
                     起動總線函數(shù)               
函數(shù)原型: void  Start_I2c();  
功能:       啟動I2C總線,即發(fā)送I2C起始條件.
  
********************************************************************/
void Start_I2c()
{
  SDA=1;   /*發(fā)送起始條件的數(shù)據(jù)信號*/
  _Nop();
  SCL=1;
  _Nop();    /*起始條件建立時間大于4.7us,延時*/
  _Nop();
  _Nop();
  _Nop();
  _Nop();   
  SDA=0;   /*發(fā)送起始信號*/
  _Nop();    /* 起始條件鎖定時間大于4μs*/
  _Nop();
  _Nop();
  _Nop();
  _Nop();      
  SCL=0;   /*鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù) */
  _Nop();
  _Nop();
}
/*******************************************************************
                      結(jié)束總線函數(shù)               
函數(shù)原型: void  Stop_I2c();  
功能:       結(jié)束I2C總線,即發(fā)送I2C結(jié)束條件.
********************************************************************/
void Stop_I2c()
{
  SDA=0;  /*發(fā)送結(jié)束條件的數(shù)據(jù)信號*/
  _Nop();   /*發(fā)送結(jié)束條件的時鐘信號*/
  SCL=1;  /*結(jié)束條件建立時間大于4μs*/
  _Nop();
  _Nop();
  _Nop();
  _Nop();
  _Nop();
  SDA=1;  /*發(fā)送I2C總線結(jié)束信號*/
  _Nop();
  _Nop();
  _Nop();
  _Nop();
}
/*******************************************************************
                 字節(jié)數(shù)據(jù)傳送函數(shù)               
函數(shù)原型: void  SendByte(uchar c);
功能:  將數(shù)據(jù)c發(fā)送出去,可以是地址,也可以是數(shù)據(jù),發(fā)完后等待應(yīng)答,并對
     此狀態(tài)位進(jìn)行操作.(不應(yīng)答或非應(yīng)答都使ack=0 假)     
     發(fā)送數(shù)據(jù)正常,ack=1; ack=0表示被控器無應(yīng)答或損壞。
********************************************************************/
void  SendByte(uchar c)
{
uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++)  /*要傳送的數(shù)據(jù)長度為8位*/
    {
     if((c<<BitCnt)&0x80)SDA=1;   /*判斷發(fā)送位*/
       else  SDA=0;               
     _Nop();
     SCL=1;               /*置時鐘線為高,通知被控器開始接收數(shù)據(jù)位*/
      _Nop();
      _Nop();               /*保證時鐘高電平周期大于4μs*/
      _Nop();
      _Nop();
      _Nop();         
     SCL=0;
    }
    _Nop();
    _Nop();
    SDA=1;               /*8位發(fā)送完后釋放數(shù)據(jù)線,準(zhǔn)備接收應(yīng)答位*/
    _Nop();
    _Nop();   
    SCL=1;
    _Nop();
    _Nop();
    _Nop();
    if(SDA==1)ack=0;     
       else ack=1;        /*判斷是否接收到應(yīng)答信號*/
    SCL=0;
    _Nop();
    _Nop();
}
/*******************************************************************
                 字節(jié)數(shù)據(jù)傳送函數(shù)               
函數(shù)原型: uchar  RcvByte();
功能:  用來接收從器件傳來的數(shù)據(jù),并判斷總線錯誤(不發(fā)應(yīng)答信號),
     發(fā)完后請用應(yīng)答函數(shù)。  
********************************************************************/      
uchar  RcvByte()
{
  uchar retc;
  uchar BitCnt;
  retc=0;
  SDA=1;             /*置數(shù)據(jù)線為輸入方式*/
  for(BitCnt=0;BitCnt<8;BitCnt++)
      {
        _Nop();           
        SCL=0;       /*置時鐘線為低,準(zhǔn)備接收數(shù)據(jù)位*/
        _Nop();
        _Nop();         /*時鐘低電平周期大于4.7μs*/
        _Nop();
        _Nop();
        _Nop();
        SCL=1;       /*置時鐘線為高使數(shù)據(jù)線上數(shù)據(jù)有效*/
        _Nop();
        _Nop();
        retc=retc<<1;
        if(SDA==1)retc=retc+1; /*讀數(shù)據(jù)位,接收的數(shù)據(jù)位放入retc中 */
        _Nop();
        _Nop();
      }
  SCL=0;   
  _Nop();
  _Nop();
  return(retc);
}
/*******************************************************************
                     應(yīng)答子函數(shù)
原型:  void Ack_I2c(bit a);
功能:主控器進(jìn)行應(yīng)答信號,(可以是應(yīng)答或非應(yīng)答信號)
********************************************************************/
void Ack_I2c(bit a)
{
  
  if(a==0)SDA=0;     /*在此發(fā)出應(yīng)答或非應(yīng)答信號 */
        else SDA=1;
  _Nop();
  _Nop();
  _Nop();      
  SCL=1;
    _Nop();
    _Nop();              /*時鐘低電平周期大于4μs*/
    _Nop();
    _Nop();
    _Nop();  
SCL=0;                /*清時鐘線,鉗住I2C總線以便繼續(xù)接收*/
    _Nop();
    _Nop();   
}
/*******************************************************************
                    向無子地址器件發(fā)送字節(jié)數(shù)據(jù)函數(shù)               
函數(shù)原型: bit  ISendByte(uchar sla,ucahr c);  
功能:     從啟動總線到發(fā)送地址,數(shù)據(jù),結(jié)束總線的全過程,從器件地址sla.
           如果返回1表示操作成功,否則操作有誤。
注意:    使用前必須已結(jié)束總線。
********************************************************************/
bit ISendByte(uchar sla,uchar c)
{
   Start_I2c();               /*啟動總線*/
   SendByte(sla);            /*發(fā)送器件地址*/
     if(ack==0)return(0);
   SendByte(c);               /*發(fā)送數(shù)據(jù)*/
     if(ack==0)return(0);
  Stop_I2c();                 /*結(jié)束總線*/
  return(1);
}
/*******************************************************************
                    向有子地址器件發(fā)送多字節(jié)數(shù)據(jù)函數(shù)               
函數(shù)原型: bit  ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);  
功能:     從啟動總線到發(fā)送地址,子地址,數(shù)據(jù),結(jié)束總線的全過程,從器件
          地址sla,子地址suba,發(fā)送內(nèi)容是s指向的內(nèi)容,發(fā)送no個字節(jié)。
           如果返回1表示操作成功,否則操作有誤。
注意:    使用前必須已結(jié)束總線。
********************************************************************/
bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
{
   uchar i;
   Start_I2c();               /*啟動總線*/
   SendByte(sla);            /*發(fā)送器件地址*/
     if(ack==0)return(0);
   SendByte(suba);            /*發(fā)送器件子地址*/
     if(ack==0)return(0);

   for(i=0;i<no;i++)
    {   
     SendByte(*s);               /*發(fā)送數(shù)據(jù)*/
       if(ack==0)return(0);
     s++;
    }
Stop_I2c();                 /*結(jié)束總線*/
  return(1);
}

/*******************************************************************
                    向無子地址器件讀字節(jié)數(shù)據(jù)函數(shù)               
函數(shù)原型: bit  IRcvByte(uchar sla,ucahr *c);  
功能:     從啟動總線到發(fā)送地址,讀數(shù)據(jù),結(jié)束總線的全過程,從器件地
          址sla,返回值在c.
           如果返回1表示操作成功,否則操作有誤。
注意:    使用前必須已結(jié)束總線。
********************************************************************/
bit IRcvByte(uchar sla,uchar *c)
{
   Start_I2c();                /*啟動總線*/
   SendByte(sla+1);           /*發(fā)送器件地址*/
     if(ack==0)return(0);
   *c=RcvByte();               /*讀取數(shù)據(jù)*/
     Ack_I2c(1);               /*發(fā)送非就答位*/
  Stop_I2c();                  /*結(jié)束總線*/
  return(1);
}
/*******************************************************************
                    向有子地址器件讀取多字節(jié)數(shù)據(jù)函數(shù)               
函數(shù)原型: bit  ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);  
功能:     從啟動總線到發(fā)送地址,子地址,讀數(shù)據(jù),結(jié)束總線的全過程,從器件
          地址sla,子地址suba,讀出的內(nèi)容放入s指向的存儲區(qū),讀no個字節(jié)。
           如果返回1表示操作成功,否則操作有誤。
注意:    使用前必須已結(jié)束總線。
********************************************************************/
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
   uchar i;

   Start_I2c();               /*啟動總線*/
   SendByte(sla);            /*發(fā)送器件地址*/
     if(ack==0)return(0);
   SendByte(suba);            /*發(fā)送器件子地址*/
     if(ack==0)return(0);

   Start_I2c();
   SendByte(sla+1);
      if(ack==0)return(0);

   for(i=0;i<no-1;i++)
    {   
     *s=RcvByte();               /*發(fā)送數(shù)據(jù)*/
      Ack_I2c(0);                /*發(fā)送就答位*/  
     s++;
    }
   *s=RcvByte();
    Ack_I2c(1);                 /*發(fā)送非應(yīng)位*/
Stop_I2c();                    /*結(jié)束總線*/
  return(1);
}



一.7.3 ZLG7290#include "REG52.h"
#include "viic_c51.h"

#define zlg7290 0x70 //ZLG7290的IIC地址

#define SubKey  0x01
#define SubCmdBuf 0x07
#define SubDpRam 0x10

** 函數(shù)名稱:         DelayNS
** 功能描述:         長軟件延時
** 輸 入: i :        延時參數(shù),值越大時延時越久
** 輸 出: 無
** 全局變量:        無
** 調(diào)用模塊:         無
void delayMS(unsigned char i)
{
        unsigned char j,k;
        for(k=0;k<i;k++)
                for(j=0;j<60;j++);
}
** 函數(shù)名稱:         ZLG7290_SendData
** 功能描述:         發(fā)送數(shù)據(jù)
** 輸 入:SubAdd :        輸入數(shù)據(jù)
**       DATA         :        輸入值
**         
** 輸 出: 0 : Fail
**        1 :  OK
** 全局變量:        無
** 調(diào)用模塊:         delayMS
unsigned char ZLG7290_SendData(unsigned char SubAdd,unsigned char Data)
{
        if(SubAdd>0x17)
                return 0;
        ISendStr(zlg7290,SubAdd,&Data,1);
        delayMS(10);
        return 1;
}
** 函數(shù)名稱:         ZLG7290_SendCmd
** 功能描述:         發(fā)送命令(對子地址7、8)
** 輸 入:DATA1  :        命令1
**       DATA2         :        命令2
** 輸 出: 0 : Fail
**        1 :  OK
** 全局變量:        無
** 調(diào)用模塊:         ISendStr、delayMS
unsigned char ZLG7290_SendCmd(unsigned char Data1,unsigned char Data2)
{
unsigned char Data[2];
        Data[0]=Data1;
        Data[1]=Data2;
        ISendStr(zlg7290,0x07,Data,2);
        delayMS(10);
        return 1;
}  
/*********************************************************************************************************
** 函數(shù)名稱:         ZLG7290_SendBuf
** 功能描述:         向顯示緩沖區(qū)發(fā)送數(shù)據(jù)
** 輸 入: * disp_buf          :        要發(fā)送數(shù)據(jù)的起始地址
**         num                 :        發(fā)送個數(shù)
** 輸 出: 無
** 全局變量:        無
** 調(diào)用模塊:         ZLG7290_SendCmd
********************************************************************************************************/
void ZLG7290_SendBuf(unsigned char * disp_buf,unsigned char num)
{
        unsigned char i;
        for(i=0;i<num;i++)
        {      
                ZLG7290_SendCmd(0x60+i,*disp_buf);
                disp_buf++;
        }
}
/*********************************************************************************************************
** 函數(shù)名稱:         ZLG7290_GetKey
** 功能描述:         讀取鍵值
** 輸 入: 無   
** 輸 出: >0  鍵值
**        =0  無鍵按下
** 全局變量:        無
** 調(diào)用模塊:         IRcvStr、delayMS
********************************************************************************************************/

unsigned char        ZLG7290_GetKey()
{
unsigned char rece;
        rece=0;
        IRcvStr(zlg7290,1,&rece,1);
        delayMS(10);
        return rece;
}
   
  實訓(xùn)心得    經(jīng)過這段時間的單片機(jī)課程設(shè)計,終于完成了波形發(fā)生器的設(shè)計,基本達(dá)到設(shè)計要求,從心底里來說,還是很高興的,畢竟這次設(shè)計把實物都做了出來。
  在本次設(shè)計的過程中,我發(fā)現(xiàn)很多的問題,雖然以前還做過這樣的設(shè)計但這次設(shè)計真的讓我長進(jìn)了很多。對于單片機(jī)設(shè)計,其硬件電路是比較簡單的,主要是解決程序設(shè)計的問題,而程序設(shè)計是一個很靈活的東西,它反映了你解決問題的邏輯思維和創(chuàng)新能力,它才是一個設(shè)計的靈魂所在。因此在整個設(shè)計過程中大部分時間是用在程序上面的。很多子程序是可以借鑒書本上的,但怎樣銜接各個子程序才是關(guān)鍵的問題所在,這需要對單片機(jī)的結(jié)構(gòu)很熟悉。因此可以說單片機(jī)的設(shè)計是軟件和硬件的結(jié)合,二者是密不可分的。
    同時在本次設(shè)計的過程中,我還學(xué)會了高效率的查閱資料、運(yùn)用工具書、利用網(wǎng)絡(luò)查找資料。我發(fā)現(xiàn),在我們所使用的書籍上有一些知識在實際應(yīng)用中其實并不是十分理想,各種參數(shù)都需要自己去調(diào)整。偶而還會遇到錯誤的資料現(xiàn)象,這就要求我們應(yīng)更加注重實踐環(huán)節(jié)。
  最后還要在此感謝指導(dǎo)老師們和我的同學(xué),他們在整個過程中都給予了我充分的幫助與支持。

參考文獻(xiàn)1、DAC08320的數(shù)據(jù)手冊。
2、參考《單片機(jī)實驗與實驗教程》實驗37內(nèi)容。
3、周立功《單片機(jī)應(yīng)用設(shè)計基礎(chǔ)》
4、網(wǎng)絡(luò)上一些資源
5、譚浩強(qiáng)《C 程序設(shè)計》







歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1