⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ad7746.c

📁 AD7746模数转换程序
💻 C
字号:
//======================================================================
//
// Author        : ADI - CAST 
//
// Date          : Sep 2006
//
// File          : i2c.c
//
// Description   : use the i2c function for MicroConverter(ADuC812) DEMO
//					to control the CDC AD7746
//
//
//					(1)use tmr2 in timer function to transmit CDC result in 1Hz;
//					(2)setup CDC's mode refers to AD7746EVB's software setup
//
//					Reference : ADuC812's example asm-code "i2cmstr.asm"           
//								Technical Note: uC001 - MicroConverter I2C Compatible Interface
//======================================================================
#include <stdio.h>
#include <ADuC812.h>

#define SLAVEADD 0x90
#define CDC_RESET_ADDR 0xBF
#define CDC_CAPDATA_ADDR 0x01

sbit LED = P3^4;
sbit RDY = P3^5;


volatile unsigned char I2C_Flag=0;
//bit0:ERR
//bit1:NOACK
#define ERR 0
#define NOACK 1

//Cap result
unsigned char CapResult_H,CapResult_M,CapResult_L;


////////////////////////////////////////////////////////////////////
void UART_Init()
{
	TMOD = 0x20;	//9600 baud assuming 11.0592MHz crystal
	TH1 = 0xFD;
	TL1 = 0xFD;
	SCON = 0x52;
	TR1 = 1;
}

//HEX2ASCII : converts ch into the hex character representing the value of ch's 
//least significant nibble
unsigned char HEX2ASCII(unsigned char ch)
{
	ch &= 0x0F;
	if(ch>=0x0A)
		ch += 7;
	ch += '0';
	return ch;
}


void UART_sendchar(unsigned char c)
{
	while(!TI);
	TI = 0;
	SBUF = c;
}

//UART_SendVar : converts the hex value of ch into two ASCII chars, and then spits 
//these two characters up the UART.
void UART_SendVar(unsigned char ch)
{
	unsigned char ch_temp = ch;
	ch_temp >>= 4;
	ch_temp = HEX2ASCII(ch_temp);
	UART_sendchar(ch_temp);
	ch = HEX2ASCII(ch);
	UART_sendchar(ch);
}

void I2C_Init()
{
	SPE = 0;			//enable i2c
	I2CCON = 0xA8;		//sets SDATA & SCLOCK, and
						//selects master mode
	I2C_Flag = 0;
}

//Delay5 : Short delay (5 machine cycles incl CALL time) for the main signals(SCLOCK , SDATA)
void Delay5()		
{}

//I2C_StartBit : Sends the start bit to initiate an I2C communication
void I2C_StartBit()	
{
	MDE = 1;			//enable SDATA pin as an output
	I2C_Flag = 0;
	MDO = 1;
	MCO = 1;
	MDO = 0;			//low O/P on SDATA 
	Delay5();			//delay 5 Machine cycles
	MCO = 0;			//start bit
}

//I2C_StopBit : Sends the stop bit to end an I2C transmission
void I2C_StopBit()	
{
	MDE = 1;			//to enable SDATA pin as an output
	MDO = 0;			//get SDATA ready for stop
	MCO = 1;			//set clock for stop
	Delay5();
	MDO = 1;			//this is the stop bit
}

//I2C_SendByte : Send 8-bits in ch to the slave
void I2C_SendByte(unsigned char ch)	
{
	unsigned char i;
	MDE = 1;			//to enable SDATA pin as an output
	MCO = 0;			//make sure that the clock line is low
	for(i=0;i<8;i++)
	{
		MDO = 0;		//put data bit on SDATA line
		if(ch&0x80)
			MDO = 1;
		MCO = 1;		//clock to send bit
		MCO = 0;		//clear clock 
		ch = ch<<1;		//move ch's bit
	}
	MDE = 0;			//release data line for acknowledge
	MCO = 1;			//send clock for acknowledge
	Delay5();
	if(MDI)				//no acknowledge, set flag
		I2C_Flag |= 1<<NOACK;
	MCO = 0;			//clear clock 
}

//I2C_RcvByte : receives one byte of data from an I2C slave device.
//ak refers to ackonwledge bit
unsigned char I2C_RcvByte(unsigned char ak)	
{
	unsigned char i,rr=0;
	MDE = 0;			//to enable SDATA pin as an input
	MCO = 0;			//make sure the clock line is low
	for(i=0;i<8;i++)
	{
		MCO = 1;		//clock to recieve bit
		rr = rr<<1;		//read data bit
		rr |= MDI;
		MCO = 0;		//clear clock
	}
	MDE = 1;			//Data pin of the master must be an..
               			//..output for the acknowledge	
	MDO = ak;			//Send (no) acknowledge bit
	MCO = 1;
	Delay5();
	MCO = 0;			//clear clock
	return rr;
}

//CDC_Reset : Reset the CDC, after send SLAVEADD, send CDC_RESET_B(0xBF)
void CDC_Reset()	
{
	unsigned char i;
	I2C_StartBit();
	I2C_SendByte(SLAVEADD);
	if(!(I2C_Flag&(1<<NOACK)))
		I2C_SendByte(CDC_RESET_ADDR);
	else
		I2C_Flag |= 1<<ERR;
	I2C_StopBit();
	
	for(i=0;i<254;i++);	//wait for CDC reset
}

//CDC_WRREG : write reg to CDC's addr register
void CDC_WRREG(unsigned char addr, unsigned char reg)	
{
	I2C_StartBit();
	I2C_SendByte(SLAVEADD);
	if(!(I2C_Flag&(1<<NOACK)))
		I2C_SendByte(addr);
	if(!(I2C_Flag&(1<<NOACK)))
		I2C_SendByte(reg);
	I2C_StopBit();
	if(I2C_Flag&(1<<NOACK))
		I2C_Flag |= 1<<ERR;
}

//CDC_RDREG : read CDC's addr register
unsigned char CDC_RDREG(unsigned char addr)
{
	unsigned char rr;
	I2C_StartBit();
	I2C_SendByte(SLAVEADD);
	if(!(I2C_Flag&(1<<NOACK)))
		I2C_SendByte(addr);
	if(!(I2C_Flag&(1<<NOACK)))
	{
		I2C_StartBit();				//re-start
		I2C_SendByte(SLAVEADD+1);	//read function
	}
	if(!(I2C_Flag&(1<<NOACK)))
		rr = I2C_RcvByte(1);		//read 1 byte, no ack
	I2C_StopBit();
	if(I2C_Flag&(1<<NOACK))
		I2C_Flag |= 1<<ERR;
	return rr;
}

//CDC_RDCAP : read CDC's convert cap result
void CDC_RDCAP()
{
	I2C_StartBit();
	I2C_SendByte(SLAVEADD);
	if(!(I2C_Flag&(1<<NOACK)))
		I2C_SendByte(CDC_CAPDATA_ADDR);
	if(!(I2C_Flag&(1<<NOACK)))
	{
		I2C_StartBit();				//re-start
		I2C_SendByte(SLAVEADD+1);	//read function
	}
	if(!(I2C_Flag&(1<<NOACK)))
		CapResult_H = I2C_RcvByte(0);	//read cap data reg
	if(!(I2C_Flag&(1<<NOACK)))
		CapResult_M = I2C_RcvByte(0);
	if(!(I2C_Flag&(1<<NOACK)))
		CapResult_L = I2C_RcvByte(1);		
	I2C_StopBit();
	if(I2C_Flag&(1<<NOACK))
		I2C_Flag |= 1<<ERR;
}

void CDC_Init()
{
	CDC_Reset();
	//REG SETUP refs to AD7746EVB's software
	CDC_WRREG(0x0A,0x31);	//CON REG,CAPF=110,MD=001
	CDC_WRREG(0x0B,0xB7);	//CAP DAC A
	CDC_WRREG(0x09,0x0B);	//EXC REG,EXCA,EXCLVL=11
	CDC_WRREG(0x07,0xC1);	//CAP SET-UP,start
	if(I2C_Flag&(1<<ERR))
	{
		I2C_Flag = 0;
		UART_sendchar('#');
	}
}

void tmr2_interrupt () interrupt 5	//tmr2
{
	static unsigned int cc = 1000;
	TF2 = 0;

	cc--;
	if(!cc)				//UART trasmit CDC result in 1Hz
	{
		cc = 1000;
		LED ^= 1;
		while(RDY);		//wait for CDC convert ready
		CDC_RDCAP();	//read CDC convert result
		if(I2C_Flag&(1<<ERR))
		{
			I2C_Flag = 0;
			UART_sendchar('$');
		}
		else
		{
			UART_sendchar(13);
			UART_SendVar(CapResult_H);	//trasmit result
			UART_sendchar(' ');
			UART_SendVar(CapResult_M);
			UART_sendchar(' ');
			UART_SendVar(CapResult_L);
			//UART_sendchar(' ');
			//UART_SendVar((CapResult_H>>2)-5);
		}
	}
    
    

}

void main()
{
	UART_Init();
	I2C_Init();
	CDC_Init();
	
	RDY = 1;	//P3.5 input
	ET2 = 1;
	
	RCAP2H = 0xFC;	
	RCAP2L = 0x66;
	TH2 = 0xFC;
	TL2 = 0x66;		

	EA = 1;
	T2CON = 0x04;	//tmr2 in timer function, 1kHz, auto reload


	while(1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -