/* PROJECT NAME: ELECTRONIC SCALE. */
/* CAMPANY : Chipsea technologies Co., LTD. */
/* LANGUAGE : C */
/* EDITOR : */
/* DATE : 2014.07.24 */
/*----------------------------------------------------------------------------
CODE NAME : AD_Communication.C
- description
- MCU与ADC通讯相关子程序
-----------------------------------------------------------------------------*/
//整个通讯时序的时间必须小于1个数据转换周期
//推荐每个CLK的时间长度:2uS ~ 15uS
/*-----------------------------------------------------------------------------
Name : F_AD_Clock
Function: ADC时序时钟
-----------------------------------------------------------------------------*/
#include <SH79F166A.H>
sbit IO_CLK_AD=P3^2;
sbit IO_Data_AD=P3^3;
unsigned long ADC_data=0;
void F_Delay(void)
{
unsigned char i=0;
i=20;
while(i--);
}
void F_AD_Clock(void)
{
P3CR|=0x04;
IO_CLK_AD = 1;
F_Delay();
IO_CLK_AD = 0;
F_Delay();
}
/*-----------------------------------------------------------------------------
Name : F_Read_AD_Byte
Function: 读3字节AD值
-----------------------------------------------------------------------------*/
unsigned long F_Read_AD(void)
{
unsigned char i;
ADC_data = 0;
P3CR&=0xf7;
//EIC20_EIE0 = 0; //关闭MCU_DAT管脚的外部中断(防止读写时误触发)
while(IO_Data_AD);
for(i = 0; i < 24; i++) //发送24个CLK,接收数据
{
ADC_data <<= 1;
F_AD_Clock();
if(IO_Data_AD)
{
ADC_data ++;
}
}
F_AD_Clock();
F_AD_Clock();
F_AD_Clock(); //CLK27,拉高DRDY
//如果一个数据转换周期内对ADC进行两次或以上的读写操作,则需要发送46个CLK,而不是27个CLK
//(即:发送24个CLK读取数据,然后再发送22个CLK)
//EIC20_EIE0 = 1; //重新开启MCU_DAT管脚的外部中断
return ADC_data;
}
/*-----------------------------------------------------------------------------
Name : F_Rd_AdReg
Function: 读取ADC寄存器
-----------------------------------------------------------------------------*/
unsigned char F_Rd_AdReg(void)
{
unsigned char i;
unsigned char send_data=0;
// union _UCHAR_BIT R_Temp;
//----------------------------------
//EIC20_EIE0 = 0; //关闭MCU_DAT管脚的外部中断(防止读写时误触发)
//----------------------------------
//1 ~ 3:clk1-clk27
//----------------------------------
for(i = 0; i < 27; i++)
{
F_AD_Clock();
}
//----------------------------------
//4:clk28-clk29
//----------------------------------
P3CR|=0x08;
//IO_Data_AD_Dir = 1; //把MCU_Data管脚设为输出
F_AD_Clock();
F_AD_Clock();
//----------------------------------
//5:clk30-clk36(发送读命令)
//----------------------------------
send_data = 0xAC; //读命令(0x56)左移1位
for(i = 0; i < 7; i ++)
{
if(send_data&0x80) //MSB
{
IO_Data_AD = 1;
}
else
{
IO_Data_AD = 0;
}
send_data = send_data << 1;
F_AD_Clock();
}
//----------------------------------
//6:clk37
//----------------------------------
// IO_Data_AD_Dir = 0; //把MCU_Data管脚设为输入
P3CR&=0xf7;
F_AD_Clock();
//----------------------------------
//7:clk38-clk45(读取寄存器)
//----------------------------------
send_data = 0;
for(i = 0; i < 8; i++)
{
send_data <<= 1;
F_AD_Clock();
if(IO_Data_AD)
{
send_data ++;
}
}
//----------------------------------
//8:clk46
//----------------------------------
F_AD_Clock();
//----------------------------------
//EIC20_EIE0 = 1; //重新开启MCU_DAT管脚的外部中断
return send_data;
}
/*-----------------------------------------------------------------------------
Name : F_Wr_AdReg
Function: 写入ADC寄存器
-----------------------------------------------------------------------------*/
void F_Wr_AdReg(unsigned char R_AdReg)
{
unsigned char i;
unsigned char send_data1=0;
//----------------------------------
//EIC20_EIE0 = 0; //关闭MCU_DAT管脚的外部中断(防止读写时误触发)
//----------------------------------
//1 ~ 3:clk1-clk27
//----------------------------------
for(i = 0; i < 27; i++)
{
F_AD_Clock();
}
//----------------------------------
//4:clk28-clk29
//----------------------------------
P3CR|=0x08;
// IO_Data_AD_Dir = 1; //把MCU_Data管脚设为输出
F_AD_Clock();
F_AD_Clock();
//----------------------------------
//5:clk30-clk36(发送写命令)
//----------------------------------
send_data1 = 0xCA; //写命令(0x65)左移1位
for(i = 0; i < 7; i ++)
{
if(send_data1&0x80) //MSB
{
IO_Data_AD = 1;
}
else
{
IO_Data_AD = 0;
}
send_data1 = send_data1 << 1;
F_AD_Clock();
}
//----------------------------------
//6:clk37
//----------------------------------
F_AD_Clock();
//----------------------------------
//7:clk38-clk45(写入寄存器)
//----------------------------------
send_data1 = R_AdReg;
for(i = 0; i < 8; i ++)
{
if(send_data1&0x80) //MSB
{
IO_Data_AD = 1;
}
else
{
IO_Data_AD = 0;
}
send_data1 = send_data1 << 1;
F_AD_Clock();
}
//----------------------------------
//8:clk46
//----------------------------------
//IO_Data_AD_Dir = 0; //把MCU_Data管脚设为输入
P3CR&=0xf7;
F_AD_Clock();
//----------------------------------
//EIC20_EIE0 = 1; //重新开启MCU_DAT管脚的外部中断
}