|
摘要,本作品由增益放大與控制模塊、極性轉(zhuǎn)換模塊、觸發(fā)以及以aduc841/ aduc831為核心的單片機最小系統(tǒng)4個部分構(gòu)成,由單片機實現(xiàn)控制與波形存儲回放功能。
一、方案論證與設(shè)計
1. 增益放大與測量方案
方案一:將輸入信號經(jīng)放大后送入窗口比較器,上限1V,下限0.1V。若小于0.1V,則通過單片機(p0.2=1,p0.3=0)控制增益放大電路將信號放大10倍,再輸入到控制模塊與0.1V和1V比較,若仍小于0.1V,則通過單片機控制增益放大電路將信號放大100倍;若大于1V,則通過單片機(在一個周期內(nèi)出現(xiàn)p0.2=1,p0.3=0;p0.2=1,p0.3=1;p0.2=0,p0.3=1這幾種情況)控制增益放大電路將信號衰減10倍(當(dāng)前信號已經(jīng)放大100倍或10倍),如果信號放大1倍,則衰減為零,阻止通過;若在0.1V和1V之間,則通過單片機(在一個周期內(nèi)出現(xiàn)p0.2=1,p0.3=0;p0.2=1,p0.3=1這兩種種情況)控制增益放大電路將信號無增益的輸出。通過此電路使輸出信號幅度控制在0.2V至2V之間。
方案二:將放大后的信號其中一路轉(zhuǎn)換為直流信號,再將此信號給窗口比較器,上限2V,下限0.2V。若小于0.2V,則通過單片機(p0.2=1,p0.3=0)控制增益放大電路將信號放大10倍,再輸入到控制模塊與0.2V和2V比較,若仍小于0.2V,則通過單片機控制增益放大電路將信號放大100倍;若大于2V,則通過單片機(p0.2=0,p0.3=1)控制增益放大電路將信號衰減為零,阻止通過;若在0.2V和2V之間,則通過單片機(p0.2=1,p0.3=1)控制增益放大電路將信號無增益的輸出。通過此電路使輸出信號幅度控制在0.2V至2V之間。
對以上兩種方案進行比較,方案一雖在軟件控制方面稍繁,但也易于實現(xiàn),而方案二在將交流變?yōu)橹绷鞯挠布?SPAN style="COLOR: black">方面較為復(fù)雜,故采用方案二。
2. 采樣方案
方案一:通過觸發(fā)模塊提供給單片機一個周期信號,通過軟件實現(xiàn)定時采樣。
方案二:先將信號經(jīng)過100倍頻之后,送給單片機作為采樣觸發(fā)信號,也就是說每個周期固定采100個點。但是同步回放頻率難以控制。
對以上兩種方案進行比較,方案二雖然在采樣方面比較精準,但回放難以實現(xiàn),而方案一在兩方面均可兼顧。故采用方案一。
二、原理分析與硬件電路圖
根據(jù)題目要求,該調(diào)理系統(tǒng)包括增益放大與控制模塊、極性轉(zhuǎn)換模塊、觸發(fā)3個模塊,由于3個模塊相對獨立,其中增益放大與控制模塊是重點。以下分別對其進行原理分析與電路設(shè)計。
1.增益放大與循環(huán)取樣模塊
(1)原理分析
設(shè)輸入信號幅度為A,將輸入信號輸入循環(huán)取樣模塊與0.1V和1V比較:若小于0.1V,則通過單片機控制增益放大電路將信號放大10倍,再輸入到控制模塊與0.1V和1V比較,若仍小于0.1V,則通過單片機控制增益放大電路將信號放大100倍;若大于1V,則通過單片機控制增益放大電路將信號衰減10倍(當(dāng)前信號已經(jīng)放大100倍或10倍),如果信號放大1倍,則衰減為零,阻止通過;若在0.1V和1V之間,則通過單片機控制增益放大電路將信號無增益的輸出。通過此電路使輸出信號峰峰值控制在0.2V至2V之間。
(2)原理電路
①循環(huán)取樣模塊。本電路采用專用比較器LM339,使用三端穩(wěn)壓管TL431提供2.5V的穩(wěn)壓源,通過調(diào)節(jié)滑動變阻器使LM339的6腳和5腳分別得到0.1V和1V的電平。將取樣信號送給由LM339構(gòu)成的窗口比較器,可以從1腳和2腳得到隨信號變化的TTL電平,從而將比較結(jié)果送給單片機,以便單片機做出判決,發(fā)出控制信號。該增益控制模塊電路的基本原理如下圖所示。

②增益控制模塊。根據(jù)單片機發(fā)出的控制信號送給CD4051,選擇X0,X1,X2,X3導(dǎo)通,從而改變運放U2B的放大倍數(shù)。通過滑動變阻器的微調(diào)使放大倍數(shù)達到指標(biāo)(1倍、10倍、100倍)。該增益放大模塊電路的基本原理如下圖所示。

2.極性轉(zhuǎn)換模塊
(1)原理分析
將輸入信號通過極性轉(zhuǎn)換模塊(含有一加法器和一提供穩(wěn)定電壓的穩(wěn)壓源),使信號幅度均抬高1.25V,從而將輸入的雙極性信號轉(zhuǎn)換成單極性信號輸出。
(2)原理電路
使用三端穩(wěn)壓管TL431向TL084的正極提供1.25V的穩(wěn)壓源,由TL084組成加法器,使輸入信號與1.25V相加。該極性轉(zhuǎn)換模塊電路的基本原理如下圖所示。

3.觸發(fā)模塊
(1)原理分析
將輸入信號通過觸發(fā)模塊(含有比較器),一周期的輸入信號得到一上升沿觸發(fā)。
(2)原理電路
將輸入信號接入比較器LM339的正極,負極接入一可通過滑動變阻器微調(diào)的電壓,通過與8腳電壓比較,得到一個周期與輸入信號相同的方波,作為觸發(fā)信號送給單片機。該觸發(fā)模塊電路的基本原理如下圖所示。

三、軟件設(shè)計與流程
 
四、總結(jié)
在這個電路中,通過模擬處理模塊和單片機配合實現(xiàn)對輸入信號的自動放大,當(dāng)輸入信號在0.002V至2V之間,
使單片機采樣信號始終保持在0.2V至2V之間。同時利用ADuC842內(nèi)部的AD和DA對信號采樣并同步輸出,
在這個過程中,把采樣值保存在數(shù)組中,通過按鍵實現(xiàn)回放。
附件: 主程序
#include "zlg7290b.h"
//SCLK--SCL MOSI--SDA INT--INT0
#define uchar unsigned char
#define uint unsigned int
bit con_caiji=0;
bit tongb_hf=0;
sbit P0_0=P2^0;
sbit P0_1=P2^1;
sbit P0_2=P0^2;
sbit P0_3=P0^3;
unsigned int k,tb_shuzu;
unsigned int j=0,i=0;
unsigned char caiji_2=100;
unsigned char panduan,panduan1;
unsigned int xdata tongbu[4000]={0};
/******************************************
函數(shù):void DispValue(unsigned char x, unsigned char dat)
功能:通過ZLG7290 顯示一個字符型數(shù)據(jù)
說明:顯示范圍:0--255
參數(shù):x,顯示起始位置。dat,需要顯示的數(shù)據(jù)
******************************************/
void DispValue(unsigned char x, unsigned char dat)
{
unsigned char d;
d =dat / 10;
ZLG7290_Download(x,0,0,d);
d =dat - d * 10;
ZLG7290_Download(x+1,0,0,d);
}
/******************************************
函數(shù):unsigned int ADC(unsigned char channel)
功能:控制單片機的AD的工作
說明:無
參數(shù): channel,AD通道選擇
******************************************/
unsigned int ADC(unsigned char channel)
{
ADCCON2 =channel; //選擇通道
SCONV =1; //啟動轉(zhuǎn)換
while(SCONV); //等待轉(zhuǎn)換完成
return((ADCDATAH & 0x0F) * 256 + ADCDATAL);
}
/******************************************
函數(shù):void DAC1(unsigned int da_data)
功能:控制單片機DA1的工作
說明:無
參數(shù):da_data,AD轉(zhuǎn)換的數(shù)字量
******************************************/
void DAC1(unsigned int da_data)
{
DAC1H =da_data >> 8;
DAC1L =da_data;
}
/******************************************
函數(shù):INT0_SVC()
功能:ZLG7290 鍵盤中斷服務(wù)程序
說明:中斷觸發(fā)方式選擇負邊沿觸發(fā),
因此不必等待中斷請求信號恢復(fù)為高電平
參數(shù):無
******************************************/
void INT0_SVC() interrupt 2
{
unsigned char KeyValue=1;
unsigned char RepeatCnt=0;
unsigned char FunctionKey=0;
EA=0;
FunctionKey=gets2(ZLG7290_FunctionKey); //讀功能計數(shù)器的值
KeyValue=gets2(ZLG7290_Key); //讀鍵值
RepeatCnt=gets2(ZLG7290_RepeatCnt); //讀連擊計數(shù)器
DispValue(0,KeyValue); //顯示連鍵值
if(KeyValue==1)
{
tongb_hf=0;
caiji_2=0;
}
if(KeyValue==2)
{
tongb_hf=1;
j=0;
}
P0_0=P0_0;
P0_1=P0_1;
EA=1;
}
/******************************************
函數(shù):caiji_data()
功能:數(shù)據(jù)采集觸發(fā)
說明:無
參數(shù):無
******************************************/
void caiji_data() interrupt 0
{
EA=0;
caiji_2++;
panduan++;
panduan1++;
if(caiji_2==4)
{
con_caiji=1;
i=0;
}
if(caiji_2==60)
{
con_caiji=0;
tb_shuzu=i;
}
if(caiji_2>=200)
{
caiji_2=80;
}
if(panduan==30)
{
panduan=0;
}
EA=1;
}
/******************************************
函數(shù):ad_start()
功能:AD轉(zhuǎn)換,同時DA進行,實現(xiàn)同步輸出
說明:無
參數(shù):無
******************************************/
void ad_start() interrupt 1
{
uint temp_data;
EA=0;
TH0=(65536-1800)/256;
TL0=(65536-1800)%256;
temp_data =ADC(5);
if(tongb_hf==0)
{
DAC1(temp_data);
if(con_caiji==1)
{
tongbu[i]=temp_data;
i++;
}
}
if(tongb_hf==1)
{
DAC1(tongbu[j]);
j++;
if(j==tb_shuzu)
{
j=1;
}
}
EA=1;
}
void main()
{
uint k;
uchar x1,x2,x3,x4;
uchar fanda;
SystemInit(); //7290復(fù)位
PLLCON =0x00; //for 842
I2CCON=0xa8; //I2C初始化
I2C_Init(); //I2C初始化 7290用
ClearAll(); //7290全部清除
ADCCON1 =0xBC; //ADC上電,內(nèi)部基準,clk 8分頻
DACCON =0x16; //DAC采用內(nèi)部ref做基準
TMOD=0x01; //定時器0方式1
TH0=(65536-1000)/256;
TL0=0;
IT0 =1; //負邊沿觸發(fā)中斷
EX0 =1; //允許外部中斷
EA =1; //開中斷
ET0=1; //開c0的中斷
EX1=1; //開中斷 int1
TR0=1; //啟動c0記時
PT0=1; //同步回放中斷優(yōu)先
k=5000;
while(k--)
{
P2=0x00;
}
while(1)
{
while(panduan!=28)
{
if(P0_3!=1)
{
x1++;
}
if(P0_2!=0)
{
x2++;
}
}
if(panduan==29)
{
x3=x1;
x4=x2;
x1=0;
x2=0;
}
if((fanda==10)&&(x4==0)&&(x3==0))
{
P0_0=1;
P0_1=0;
fanda=100;
}
if(P0_2==1)
{
P0_0=0;
P0_1=0;
}
if(x4==0&&x3==0)
{
if(P0_0==1&& P0_1==0)
{
P0_0=1;
P0_1=0;
}
else
{
P0_0=0;
P0_1=1;
fanda=10;
}
}
}
}
頭文件1
/********************************************************************
ZLG7290.c
數(shù)碼管顯示與鍵盤管理芯片ZLG7290 的標(biāo)準80C51 驅(qū)動程序C 文件
Copyright (c) 2005,廣州周立功單片機發(fā)展有限公司
All rights reserved.
本程序僅供學(xué)習(xí)參考,不提供任何可靠性方面的擔(dān)保;請勿用于商業(yè)目的
******************************************************************/
#include "i2c.h"
#include "zlg7290.h"
/****************************************************
函數(shù):ZLG7290_WriteReg()
功能:向ZLG7290 的某個內(nèi)部寄存器寫入數(shù)據(jù)
參數(shù):
RegAddr:ZLG7290 的內(nèi)部寄存器地址
dat:要寫入的數(shù)據(jù)
返回:
0:正常
1:訪問ZLG7290 時出現(xiàn)異常
*************************************************/
/*bit ZLG7290_WriteReg(unsigned char RegAddr, char dat)
{
bit b;
b =I2C_Puts(ZLG7290_I2C_ID,RegAddr,1,&dat,1);
return b;
}*/
/***********************************************
函數(shù):ZLG7290_cmd()
功能:向ZLG7290 發(fā)送控制命令
參數(shù):
cmd0:寫入CmdBuf0 寄存器的命令字(第1 字節(jié))
cmd1:寫入CmdBuf1 寄存器的命令字(第2 字節(jié))
返回:
0:正常
1:訪問ZLG7290 時出現(xiàn)異常
**************************************************/
bit ZLG7290_cmd(char cmd0, char cmd1)
{
bit b;
char buf[2];
buf[0] =cmd0;
buf[1] =cmd1;
b =I2C_Puts(ZLG7290_I2C_ID,ZLG7290_CmdBuf,1,buf,2);
return b;
}
/******************************************************
函數(shù):ZLG7290_SegOnOff()
功能:段尋址,單獨點亮或熄滅數(shù)碼管(或LED)中的某一段
參數(shù):
seg:取值0~63,表示數(shù)碼管(或LED)的段號
b:0 表示熄滅,1 表示點亮
返回:
0:正常
1:訪問ZLG7290 時出現(xiàn)異常
說明:
在每一位數(shù)碼管中,段號順序按照“a,b,c,d,e,f,g,dp”進行
*******************************************************/
/*bit ZLG7290_SegOnOff(char seg, bit b)
{
char cmd;
cmd =seg & 0x3F;
if ( b ) cmd |=0x80;
return ZLG7290_cmd(0x01,cmd);
}*/
/*************************************************
函數(shù):ZLG7290_Download()
功能:下載數(shù)據(jù)并譯碼
參數(shù):
addr:取值0~7,顯示緩存DpRam0~DpRam7 的編號
dp:是否點亮該位的小數(shù)點,0-熄滅,1-點亮
flash:控制該位是否閃爍,0-不閃爍,1-閃爍
dat:取值0~31,表示要顯示的數(shù)據(jù)
返回:
0:正常
1:訪問ZLG7290 時出現(xiàn)異常
說明:
顯示數(shù)據(jù)具體的譯碼方式請參見ZLG7290 的數(shù)據(jù)手冊
*************************************************/
bit ZLG7290_Download(char addr, bit dp, bit flash, char dat)
{
char cmd0;
char cmd1;
cmd0 =addr & 0x0F;
cmd0 |=0x60;
cmd1 =dat & 0x1F;
if ( dp ) cmd1 |=0x80;
if ( flash ) cmd1 |=0x40;
return ZLG7290_cmd(cmd0,cmd1);
}
/********************
函數(shù):SystemInit()
功能:系統(tǒng)初始化
********************/
void SystemInit() //等待7290初始化完畢
{
unsigned int i;
for(i =0;i < 60000;i ++);
}
/*************************
函數(shù):ClearAll()
功能:清除所有顯示
*************************/
void ClearAll()
{
unsigned char x;
for ( x=0; x<8; x++ )
{
ZLG7290_Download(x,0,0,31); //00011111,表示不顯示,循環(huán)8次,將8個數(shù)碼管顯示都清除
}
}
頭文件2
#include<ADuC842.h>
#include <stdio.h>
#define I2C_SCL MCO //ADUC831的I2CCON寄存器中的1位,時鐘位
#define I2C_SDA_O MDO //ADUC831的I2CCON寄存器中的1位,數(shù)據(jù)輸出
#define I2C_SDA_I MDI //ADUC831的I2CCON寄存器中的1位,數(shù)據(jù)輸入
#define IO_ENABLE MDE //ADUC831的I2CCON寄存器中的1位,數(shù)據(jù)輸入/輸出的使能
#define ZLGWR 0x70 //ZLG7290的寫地址
#define ZLGRD 0x71 //ZLG7290的讀地址
/*************************
I2C延時程序
*************************/
void I2C_Delay()
{
char i;
for(i=0;i<50;i++);
}
/*********************************************************
函數(shù):I2C_Init()
功能:I2C 總線初始化,使總線處于空閑狀態(tài)
說明:在main()函數(shù)的開始處,通常應(yīng)當(dāng)要執(zhí)行一次本函數(shù)
************************************************************/
void I2C_Init()
{
IO_ENABLE=1; //使能為1,則為輸出;為0,則為輸入
I2C_SCL =1;
I2C_Delay();
I2C_SDA_O =1;
I2C_Delay();
}
/**************************************************************
函數(shù):I2C_Start()
功能:產(chǎn)生I2C 總線的起始狀態(tài)
說明:
SCL處于高電平期間,當(dāng)SDA 出現(xiàn)下降沿時啟動I2C 總線
不論SDA 和SCL 處于什么電平狀態(tài),本函數(shù)總能正確產(chǎn)生起始狀態(tài)
本函數(shù)也可以用來產(chǎn)生重復(fù)起始狀態(tài)
本函數(shù)執(zhí)行后,I2C 總線處于忙狀態(tài)
******************************************************************/
void I2C_Start()
{
IO_ENABLE=1;
I2C_SDA_O =1;
I2C_Delay();
I2C_SCL =1;
I2C_Delay();
I2C_SDA_O =0;
I2C_Delay();
I2C_SCL =0;
I2C_Delay();
}
/*****************************************
函數(shù):I2C_Write()
功能:向I2C 總線寫1 個字節(jié)的數(shù)據(jù)
參數(shù):
dat:要寫到總線上的數(shù)據(jù)
********************************************/
void I2C_Write(char dat)
{
unsigned char t =8;
IO_ENABLE=1;
do
{
I2C_SDA_O =(bit)(dat & 0x80);
dat <<=1;
I2C_SCL =1;
I2C_Delay();
I2C_SCL =0;
I2C_Delay();
} while ( --t !=0 );
}
/**************************************
函數(shù):I2C_Read()
功能:從從機讀取1 個字節(jié)的數(shù)據(jù)
返回:讀取的一個字節(jié)數(shù)據(jù)
**************************************/
char I2C_Read()
{
char dat=0;
unsigned char t =8;
do
{
I2C_SCL =0;
I2C_Delay();
I2C_SCL =1;
I2C_Delay();
dat <<=1;
IO_ENABLE=0;
if ( I2C_SDA_I ) dat |=0x01;
I2C_SCL =0;
I2C_Delay();
} while ( --t !=0 );
return dat;
}
/******************************************************
函數(shù):I2C_GetAck()
功能:讀取從機應(yīng)答位
返回:
0:從機應(yīng)答
1:從機非應(yīng)答
說明:
從機在收到每個字節(jié)的數(shù)據(jù)后,要產(chǎn)生應(yīng)答位
從機在收到最后1 個字節(jié)的數(shù)據(jù)后,一般要產(chǎn)生非應(yīng)答位
***********************************************************/
bit I2C_GetAck()
{
bit ack;
IO_ENABLE=1;
I2C_SDA_O =1;
I2C_Delay();
I2C_SCL =1;
I2C_Delay();
IO_ENABLE=0;
ack =I2C_SDA_I;
I2C_SCL =0;
I2C_Delay();
return ack;
}
/********************************************************
函數(shù):I2C_PutAck()
功能:主機產(chǎn)生應(yīng)答位或非應(yīng)答位
參數(shù):
ack=0:主機產(chǎn)生應(yīng)答位
ack=1:主機產(chǎn)生非應(yīng)答位
說明:
主機在接收完每一個字節(jié)的數(shù)據(jù)后,都應(yīng)當(dāng)產(chǎn)生應(yīng)答位
主機在接收完最后一個字節(jié)的數(shù)據(jù)后,應(yīng)當(dāng)產(chǎn)生非應(yīng)答位
*********************************************************/
void I2C_PutAck(bit ack)
{
IO_ENABLE=1;
I2C_SDA_O =ack;
I2C_Delay();
I2C_SCL =1;
I2C_Delay();
I2C_SCL =0;
}
/***************************************************************
函數(shù):I2C_Stop()
功能:產(chǎn)生I2C 總線的停止?fàn)顟B(tài)
說明:
SCL處于高電平期間,當(dāng)SDA 出現(xiàn)上升沿時停止I2C 總線
不論SDA 和SCL 處于什么電平狀態(tài),本函數(shù)總能正確產(chǎn)生停止?fàn)顟B(tài)
本函數(shù)執(zhí)行后,I2C 總線處于空閑狀態(tài)
******************************************************************/
void I2C_Stop()
{
unsigned int t =1;
IO_ENABLE=1;
I2C_SDA_O =0;
I2C_Delay();
I2C_SCL =1;
I2C_Delay();
I2C_SDA_O= 1;
I2C_Delay();
while ( --t !=0 ); //在下一次產(chǎn)生Start 之前,要加一定的延時
}
/*****************************************************
函數(shù)?
功能:將I2C總線置于空閑狀態(tài),即將時鐘線和數(shù)據(jù)線都拉高
******************************************************/
void idle()
{
I2C_SCL=1;
IO_ENABLE=1;
I2C_SDA_O=1;
IO_ENABLE=0;
}
/********************************************************************
函數(shù):I2C_Puts()
功能:I2C 總線綜合發(fā)送函數(shù),向從機發(fā)送多個字節(jié)的數(shù)據(jù)
參數(shù):
SlaveAddr:從機地址(7 位純地址,不含讀寫位)
SubAddr:從機的子地址
SubMod:子地址模式,0-無子地址,1-單字節(jié)子地址,2-雙字節(jié)子地址
*dat:要發(fā)送的數(shù)據(jù)
Size:數(shù)據(jù)的字節(jié)數(shù)
返回:
0:發(fā)送成功
1:在發(fā)送過程中出現(xiàn)異常
說明:
本函數(shù)能夠很好地適應(yīng)所有常見的I2C 器件,不論其是否有子地址
當(dāng)從機沒有子地址時,參數(shù)SubAddr 任意,而SubMod 應(yīng)當(dāng)為0
**********************************************************************/
bit I2C_Puts(unsigned char SlaveAddr,unsigned int SubAddr,unsigned char SubMod,char *dat,unsigned int Size)
{
unsigned char i; //定義臨時變量
char a[3];
if ( Size ==0 ) return 0; //檢查長度
a[0] =(SlaveAddr << 1); //準備從機地址
if ( SubMod > 2 ) SubMod =2; //檢查子地址模式
switch ( SubMod ) //確定子地址
{
case 0:break;
case 1:a[1] =(char)(SubAddr);break;
case 2:a[1] =(char)(SubAddr >> 8);a[2] =(char)(SubAddr);break;
default:break;
}
a[1] =(char)(SubAddr);
SubMod++; //發(fā)送從機地址,接著發(fā)送子地址
I2C_Start();
for ( i=0; i<SubMod; i++ )
{
I2C_Write(a[i]);
if ( I2C_GetAck() )
{
I2C_Stop();idle();
return 1;
}
}
do //發(fā)送數(shù)據(jù)
{
I2C_Write(*dat++);
if ( I2C_GetAck() ) break;
} while ( --Size !=0 );
I2C_Stop(); idle(); //發(fā)送完畢,停止I2C 總線,并返回結(jié)果
if ( Size ==0 ) return 0;
else return 1;
}
/********************************************************************
函數(shù):I2C_Gets()
功能:I2C 總線綜合接收函數(shù),從從機接收多個字節(jié)的數(shù)據(jù)
參數(shù):
SlaveAddr:從機地址(7 位純地址,不含讀寫位)
SubAddr:從機的子地址
SubMod:子地址模式,0-無子地址,1-單字節(jié)子地址,2-雙字節(jié)子地址
*dat:保存接收到的數(shù)據(jù)
Size:數(shù)據(jù)的字節(jié)數(shù)
返回:
0:接收成功
1:在接收過程中出現(xiàn)異常
說明:
本函數(shù)能夠很好地適應(yīng)所有常見的I2C 器件,不論其是否有子地址
當(dāng)從機沒有子地址時,參數(shù)SubAddr 任意,而SubMod 應(yīng)當(dāng)為0
********************************************************************/
/*bit I2C_Gets(unsigned char SlaveAddr,unsigned int SubAddr,unsigned char SubMod,char *dat,unsigned int Size)
{
unsigned char i; //定義臨時變量
char a[3];
if ( Size ==0 ) return 0; //檢查長度
a[0] =(SlaveAddr << 1); //準備從機地址
if ( SubMod > 2 ) SubMod =2; //檢查子地址模式
if ( SubMod !=0 ) //如果是有子地址的從機,則要先發(fā)送從機地址和子地址
{
if ( SubMod ==1 ) //確定子地址
{
a[1] =(char)(SubAddr);
}
else
{
a[1] =(char)(SubAddr >> 8);
a[2] =(char)(SubAddr);
}
}
SubMod++;
t0=1; //發(fā)送從機地址,接著發(fā)送子地址
I2C_Start();
for ( i=0; i<=SubMod; i++ )
{
I2C_Write(a[i]);
}
}
I2C_PutAck(1);
I2C_Stop();
t0=0;
I2C_Start(); //這里的I2C_Start()對于有子地址的從機是重復(fù)起始狀態(tài)
//對于無子地址的從機則是正常的起始狀態(tài)
I2C_Write(a[0]+1); //發(fā)送從機地址
if ( I2C_GetAck() )
{
I2C_Stop();
return 1;
}
for (;;) //接收數(shù)據(jù)
{
while( I2C_GetAck() );
*dat =I2C_Read();
if ( --Size ==0 )
{
I2C_PutAck(1);
I2C_PutAck(0);
break;
}
}
I2C_Stop(); //接收完畢,停止I2C 總線,并返回結(jié)果
return 0;
}*/
char gets2(unsigned char subaddr)
{
char i,dat;
I2C_Start();
I2C_Write(ZLGWR);
I2C_GetAck();
I2C_Write(subaddr);
I2C_SCL=1;
for(i=0;i<2;i++){;}
I2C_SCL=0;
I2C_Stop();
for(i=0;i<5;i++){;}
I2C_Start();
I2C_Write(ZLGRD);
I2C_GetAck();
dat=I2C_Read();
I2C_PutAck(1);
I2C_Stop();
idle();
return dat;
} |