📄 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 + -