今天在网上下载也一个仿真程序,我也照着它搭了电路,现在就来学习一波
这个电路就是通过压力检测元件M1检测外部压力,它会输出一个模拟电压,通过U3的AD09C32对模拟量进行转换得到数字量,然后显示在数码管中同时也把数据写在24C04上。今天我主要学习一下ADC09C32和24C04
现在先来看ADC09C32:
参数:
1、8位分辨率 2、0~5v的模拟电压输入 3、两路模拟输出
它的时序电路图是:
第一步:先拉低片选
第二步:选择转换通道,上面的时序图的箭头,1~3是上升沿有效,后面才是下降沿可读取
unsigned int Adc0832(unsigned char channel) //
{
unsigned char i=0;
unsigned char j;
unsigned int dat=0;
unsigned char ndat=0;
if(channel==0)channel=2;//电路图上面是选择了通道0,根据上面的表格就是要发送1 0,也就是2
if(channel==1)channel=3;
ADDI=1; //先拉高DI引脚,先发送起始位
_nop_();//空指令,只是用来延时而已
_nop_();
ADCS=0;//拉低片选
_nop_();
_nop_();
ADCLK=1;//拉高时钟,
_nop_();
_nop_();
ADCLK=0;//拉低时钟
_nop_();
_nop_();
ADDI=(channel>>1)&0x1; //先对DI进行操作,再拉高时钟
_nop_();
ADCLK=1;
_nop_();
_nop_();
ADCLK=0;
_nop_();
_nop_();
ADDI=channel&0x1;
_nop_();
ADCLK=1;
_nop_();
_nop_();
ADCLK=0; //通道选择结束,拉低时钟引脚
ADDI=1;
_nop_();
_nop_();
dat=0;
for(i=0;i<8;i++)
{
ADCLK=1;
_nop_();
_nop_();
ADCLK=0; //先拉低数据,再读取
_nop_();
_nop_();
dat<<=1;
dat= dat<<=1|ADDO;
}
ndat=0;
for(0=1;i<8;i++)
{
ndat |=ADDO<<i; //第0位上面已经转换过了,这里就不在继续转换了,直接读
ADCLK=1;
_nop_();
_nop_();
ADCLK=0;//先拉低数据,再读取
_nop_();
_nop_();
}
ADCS=1;//转换完成止呕,拉高片选
ADCLK=0;//拉低时钟
ADDI=1;//拉高输入
return (dat == ndat) ? dat:0;
//判断是否相等,相等的话那就返回dat,不相等的话返回0;
}
2、AT24C04A这款芯片是4Kb掉电可擦除存储芯片,它采用I2C的通讯协议,I2C的时序如下
1、空闲状态:
SDA和SCL都是高电平
2、启动信号
SCL为高电平的时候,SDA由高电平跳变成低电平
void Start()
{
SDA = 1;
DelayMs(1);
SCL = 1;
DelayMs(1);
SDA = 0;
DelayMs(1);
SCL = 0;
DelayMs(1);
}
3、停止信号
SCL为高电平的时候,SDA由低电平跳变成高电平
void Stop()
{
SCL = 0;
DelayMs(1);
SDA = 0;
DelayMs(1);
SCL = 1;
DelayMs(1);
SDA = 1;
DelayMs(1);
}
4、数据传送:
SCL为高电平的时候,SDA必须为稳定的状态
写
bit Write8bit(unsigned char input)
{
unsigned char tmp;
for(tmp =8;tmp!=0;tmp--)
{
SDA = (bit)(input&0x80);
DelayMs(1);
SCL = 1;
DelayMs(1);
SCL = 0;
DelayMs(1);
input = input << 1;
}
return 1;
}
读
unsigned char Read8Bit()
{
unsigned char tmp,rbyte = 0;
for(tmp=8;tmp!=0;tmp--)
{
SCL = 1;
DelayMs(1);
rbyte = rbyte << 1;
DelayMs(1);
rbyte = rbyte|((unsigned char)(SDA));
SCL = 0;
DelayMs(1);
}
5、应答信号
当发送第9个脉冲的时候,接收器会发送一个低电平表示应答
void Ack()
{
SDA = 0;
DelayMs(1);
SCL = 1;
DelayMs(1);
SCL = 0 ;
DelayMs(1);
SDA = 1;
DelayMs(1);
}
6、非应答
当发送第9个脉冲的时候,接收器会发送高电平表示应答
void NoAck()
{
SDA = 1;
DelayMs(1);
SCL = 1;
DelayMs(1);
SCL = 0 ;
DelayMs(1);
}
7、检测时候应答
bit TestAck()
{
bit ErrorBit;
SDA = 1;
DelayMs(1);
SCL = 1;
DelayMs(1);
ErrorBit = SDA;
DelayMs(1);
SCL = 0;
DelayMs(1);
return(ErrorBit);
}
芯片的写时序
void WriteI2C(unsigned char *Wdata, unsigned char RomAddress, unsigned char number)
{
Start();//先发送一个起始信号
Write8bit(WriteDeviceAddress);//发送0xA0(第0位为0表示写)
if (TestAck()){ //非应答的话那就直接停止返回
Stop();
return;
}
Write8bit(RomAddress); //发送你要存入的地址
if (TestAck()){
Stop();
}
for(;number!=0;number--){ //写入数据
Write8bit(*Wdata);
if (TestAck()){
Stop();
return;
}
Wdata++;
}
Stop(); //结束写操作
DelayMs(1);
}
芯片的读时序
根据9-2的时序代码如下:
void ReadI2C(unsigned char* RamAddress,unsigned char RomAddress,unsigned char bytes)
{
Start();
Write8bit(WriteDeviceAddress); //先发送的芯片地址0xa0
if (TestAck()){
Stop();
}
Write8bit(RomAddress);//在发送要读取的地址
if (TestAck()){
Stop();
}
Start(); //重新给个起始信号
Write8bit(ReadDeviceAddress); //发送0A1
if (TestAck()){
Stop();
}
while(bytes != 1)
{
*RamAddress = Read8Bit(); //读取数据
Ack();//然后给个应答
RamAddress++;
bytes--;
}
*RamAddress = Read8Bit();
NoAck();//读取结束,发出一个非应答信号
Stop();
}