|
附部分程序
-----------------------------------------------------------------------------------------------------------------
IIC:
void Delay10us() //@24.000MHz
{
unsigned char i;
i = 78;
while (--i);
}
void I2C_Start()
{
I2C_SDA=1;
I2C_SCL=1; //保持高電平
Delay10us();
I2C_SDA=0; //SLC高電平SDA下降沿是起始信號(hào)
Delay10us();
I2C_SCL=0; //SCL只有為低電平的時(shí)候SDA可以改變,SCL高電平時(shí)讀取SDA
}
bit I2C_Write(uchar dat)
{
bit ack;
uchar mask;
for(mask=0x80;mask!=0;mask>>=1)
{
if((mask&dat)==0) //按位取值,最高位先取
I2C_SDA=0;
else
I2C_SDA=1;
Delay10us();
I2C_SCL=1; //從機(jī)讀取SDA
Delay10us();
I2C_SCL=0;
}
I2C_SDA=1; //釋放總線,位從機(jī)產(chǎn)生應(yīng)答做準(zhǔn)備
Delay10us();
I2C_SCL=1;
ack=I2C_SDA; //讀取產(chǎn)生的應(yīng)答信號(hào)
Delay10us();
I2C_SCL=0;
return ack;
}
void I2C_Stop()
{
I2C_SCL=0;
I2C_SDA=0; //結(jié)束前都保持低電平
Delay10us();
I2C_SCL=1;
Delay10us();
I2C_SDA=1;
Delay10us(); //防止影響到下一次的起始信號(hào)
}
bit I2C_Addresing(uchar addr) //尋址,成功返回0否則返回1
{
bit ack=0;
I2C_Start();
ack=I2C_Write(addr<<1); //習(xí)慣上高七位時(shí)地址,lsb是讀寫
I2C_Stop();
return ack; //返回應(yīng)答信號(hào)
}
//主機(jī)從從機(jī)讀取一個(gè)字節(jié)(不是最后一個(gè)字節(jié)),從機(jī)發(fā)送應(yīng)答信號(hào),主動(dòng)權(quán)還在從機(jī)上
uchar I2C_ReadAck()
{
uchar mask;
uchar dat;
I2C_SDA=1; //保持高電平
for(mask=0x80;mask!=0;mask>>=1) //高位到低位依次讀取
{
Delay10us();
I2C_SCL=1; //拉高準(zhǔn)備讀取SDA
if(I2C_SDA==0)
{
dat&=~mask; //SDA==dat對(duì)應(yīng)位
}
else
dat|=mask;
Delay10us();
I2C_SCL=0; //使從機(jī)準(zhǔn)備下一位數(shù)據(jù)發(fā)送
}
I2C_SDA=0; //拉低SDA發(fā)送應(yīng)答信號(hào),SDA控制權(quán)仍然在從機(jī)手里
Delay10us();
I2C_SCL=1; //讀取應(yīng)答信號(hào),從機(jī)繼續(xù)向主機(jī)發(fā)送信號(hào)
Delay10us();
I2C_SCL=0; //準(zhǔn)備下一位數(shù)據(jù)的發(fā)送
return dat;
}
//主機(jī)從從機(jī)讀取最后一個(gè)字節(jié),從機(jī)發(fā)送非應(yīng)答信號(hào),將SDA主動(dòng)權(quán)交給主機(jī)
uchar I2C_ReadNack()
{
uchar mask;
uchar dat;
I2C_SDA=1;
for(mask=0x81;mask!=0;mask>>=1)
{
Delay10us();
I2C_SCL=1;
if(I2C_SDA==0)
dat&=~mask;
else
dat|=mask;
Delay10us();
I2C_SCL=0;
}
I2C_SDA=1; //拉高SDA,發(fā)送非應(yīng)答信號(hào),將SDA主動(dòng)權(quán)交給主機(jī)
Delay10us();
I2C_SCL=1; //讀取非應(yīng)答信號(hào),停止從機(jī)向主機(jī)發(fā)送信號(hào)
Delay10us();
I2C_SCL=0;
return dat;
}
---------------------------------------------------------------------------------------------------------------
EEPROM(AT24C04)://讀寫單字節(jié)數(shù)據(jù)uchar E2_ReadByte(uchar addr)
{
uchar dat;
I2C_Start();
I2C_Write(0x50<<1); //起始信號(hào)+首字節(jié)(0寫1讀)0x50是at24c04的高七位地址
I2C_Write(addr); //送入要讀取的地址 addr是器件中的某個(gè)存儲(chǔ)地址
I2C_Start(); //再次發(fā)送起始信號(hào)
I2C_Write((0x50<<1)|0x01); //發(fā)送器件地址+讀操作
dat=I2C_ReadNack(); //讀取后就發(fā)送非應(yīng)答信號(hào)停止讀取
I2C_Stop();
return dat;
}
void E2_WriteByte(uchar addr,uchar dat)
{
I2C_Start();
I2C_Write(0x50<<1); //寫操作,因?yàn)榻酉聛?lái)還要向E2里面發(fā)送數(shù)據(jù)
I2C_Write(addr);
I2C_Write(dat);
I2C_Stop();
}
//讀寫多字節(jié)數(shù)據(jù)
void E2_ReadNByte(uchar *buf,uchar addr,uchar len)
{
do
{
I2C_Start();
if(!I2C_Write(0x50<<1)) //應(yīng)答0,即從機(jī)準(zhǔn)備ok,跳出等待
{
break;
}I2C_Stop();
}while(1);
I2C_Write(addr); //內(nèi)部存儲(chǔ)地址
I2C_Start();
I2C_Write((0x50<<1)|0x01);
while(len>1) //操作的不是最后一個(gè)字節(jié),返回ack
{
*buf++=I2C_ReadAck();
len--;
}
*buf=I2C_ReadNack(); //讀最后一個(gè)字節(jié),返回nack,停止讀
I2C_Stop();
}
void E2_WriteNByte(uchar *buf,uchar addr,uchar len)
{
//等待忙信號(hào)結(jié)束???
while(len--) //等待寫的數(shù)據(jù)從ram搬移到rom???
{
do
{
I2C_Start();
if(!I2C_Write(0x50<<1))
{
break;
}
I2C_Stop();
}while(1);
I2C_Write(addr++); //發(fā)送要寫入數(shù)據(jù)的地址
I2C_Write(*buf++); //發(fā)送要寫入得數(shù)據(jù)
I2C_Stop();
}
}
-----------------------------------------------------------------------------------------------------------------
PCF8591:
uchar GetADCValue(uchar chn) //讀取模擬信號(hào)
{
uchar val;
I2C_Start();
if(I2C_Write(0x48<<1)) //pcf8591高七位地址
{
I2C_Stop(); //沒(méi)有應(yīng)答則停止
return 0;
}
I2C_Write(0x40|chn); //如果有應(yīng)答位,則寫入控制字節(jié),確定寫入的是哪一個(gè)通道
I2C_Start(); //重啟動(dòng)
I2C_Write(0x48<<1|0x01); //讀操作(讀取模擬量)
I2C_ReadAck(); //提供SCL時(shí)鐘,時(shí)模擬量開始轉(zhuǎn)換
val=I2C_ReadNack();
I2C_Stop();
return val;
}
void ValueToFigure(uchar val) //將模擬信號(hào)轉(zhuǎn)化為數(shù)字
{
val=(val*25)/255;
str[0]=val/10;
str[1]=val%10; //實(shí)際電壓值
smg_dis[0]=str[0];
smg_dis[1]=str[1];
}
--------------------------------------------------------------------------------------------------------------
DS1302:
uchar Write_Addr_Ds1302[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//寫數(shù)據(jù)命令
uchar Read_Addr_Ds1302[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};//讀數(shù)據(jù)命令
uchar Time[7]={0x11,0x36,0x18,0x23,0x11,0x06,0x19}; //秒分時(shí)日月周年
void Write_Data_Ds1302(uchar addr,uchar dat) //寫數(shù)據(jù)
{
uchar idata i;
CE=0;
_nop_();
SCLK=0;
_nop_();
CE=1;
_nop_();
for(i=0;i<8;i++)
{
IO=addr&0x01;//傳輸最低位
addr>>=1;//
SCLK=1;
_nop_();
SCLK=0;
_nop_();
}
for(i=0;i<8;i++)
{
IO=dat&0x01;//傳輸最低位
dat>>=1;//
SCLK=1;
_nop_();
SCLK=0;
_nop_();
}
CE=0;//傳輸數(shù)據(jù)完成
_nop_();
}
uchar Read_Data_Ds1302(uchar addr) //讀取該地址對(duì)應(yīng)的數(shù)據(jù)
{
uchar xdata i,dat,dat1;
CE=0;
_nop_();
SCLK=0;
_nop_();
CE=1;
_nop_();
for(i=0;i<8;i++)
{
IO=addr&0x01;//傳輸最低位
addr>>=1;//
SCLK=1;
_nop_();
SCLK=0;
_nop_();
}
for(i=0;i<8;i++)
{
dat1=IO;//傳輸最低位
// dat>>=1;//
dat=(dat>>1)|(dat1<<7);
SCLK=1;
_nop_();
SCLK=0;
_nop_();
}
CE=0;//傳輸數(shù)據(jù)完成
_nop_(); //以下為DS1302復(fù)位的穩(wěn)定時(shí)間,必須的。
SCLK= 1;
_nop_();
IO = 0;
_nop_();
IO = 1;
_nop_();
return dat;
}
void Init_Ds1302()
{
uchar i;
Write_Data_Ds1302(0x8e,0x00); //關(guān)閉寫保護(hù)
for(i=0;i<7;i++)
{
Write_Data_Ds1302(Write_Addr_Ds1302[i],Time[i]);
}
}
void Read_Time_Ds1302() //讀取時(shí)鐘信息
{
uchar i;
for(i=0;i<7;i++)
{
Time[i]=Read_Data_Ds1302(Read_Addr_Ds1302[i]); //輸入地址,返回?cái)?shù)據(jù),賦值給Time[i]
Delay1ms();
}
}
---------------------------------------------------------------------------------------------------------------------------
|
-
-
8a8k例程噠噠噠.zip
2019-11-30 21:26 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
456.84 KB, 下載次數(shù): 142, 下載積分: 黑幣 -5
|