📄 公交语音提示(2) (i2c驱动程序).txt
字号:
公交语音提示(2)
//****************************I2C驱动程序****************************//
void Set_SCL(uchar i) //定义MAX6959时钟线为PA^7
{if(i) PORTA |=0x80;
else PORTA &=0x7f;
}
void Set_SDA(uchar i) //定义MAX6959数据线为PA^6
{if(i) PORTA |=0x40;
else PORTA &=0xbf;
}
void Start() //I2C总线的开始条件
{Set_SDA(1); //SDA=1;
Set_SCL(1); //SCL=1;
delay(100); //等待时钟信号变高
Set_SDA(0); //SDA=0;
delay(100);
Set_SCL(0); // SCL=0;
}
void Stop() //I2C总线结束条件
{Set_SDA(0); //SDA=0;
delay(100);
Set_SCL(1); //SCL=1;
delay(100); //等待时钟信号变低
Set_SDA(1); //SDA=1;
delay(100);
Set_SCL(0); //SCL=0;
}
void Ack() //I2C总线应答
{Set_SDA(0); //SDA=0;
delay(50);
Set_SCL(1); //SCL=1;
delay(100);
Set_SCL(0); //SCL=0;
delay(50);
Set_SDA(1); //SDA=1;
}
void Nack() //I2C总线应答非
{Set_SDA(1); //SDA=1;
delay(50);
Set_SCL(1); //SCL=1;
delay(100);
Set_SCL(0); //SCL=0;
delay(50);
Set_SDA(0); //SDA=0;
}
void Check_Ack() //I2C总线应答检查
{Set_SDA(1); //SDA=1;
Set_SCL(1); //SCL=1;
Ack_Flag=0; //清除应答标志;
DDRA&=0xbf; //设置SDA为输入
if(!((PINA & 0x40)>>6))
{delay(50);
Set_SCL(0); //SCL=0;
delay(100);}
else
{Ack_Flag=1; //收到应答;
delay(50);
Set_SCL(0); //SCL=0;
delay(100);}
DDRA |=0xff; //重新设置SDA为输出
}
void Write_Bit0() //写1bit数据:0
{Set_SDA(0); //SDA=0;
Set_SCL(1); //SCL=1;
delay(100);
Set_SCL(0); //SCL=0;
}
void Write_Bit1() //写1bit数据:1
{Set_SDA(1); //SDA=1;
Set_SCL(1); //SCL=1;
delay(100);
Set_SCL(0); //SCL=0;
Set_SDA(0); //SDA=0;
}
void Write_Byte(uchar Data) //写一字节数据Data
{uchar i;
for(i=0;i<8;i++)
{if(Data & 0x80) Write_Bit1(); //传输位从高位到低位,先传最高位
else Write_Bit0();
Data <<=1;} //数据左移
}
uchar Read_Byte() //读一字节数据:返回值即读的数据
{uchar Read_Data=0xff; // Read_Data为读入的数据,初始值为0xff
uchar j;
for (j=0;j<8;j++)
{Set_SDA(1);
Set_SCL(1);
DDRA &=0xbf;
if((PINA & 0x40)==0)
{Read_Data <<=1;
Read_Data=(Read_Data & 0xfe);
Set_SCL(0);}
else
{Read_Data <<=1;
Read_Data =( Read_Data | 0x01);
Set_SCL(0);}}
DDRA |=0x40;
return(Read_Data);
}
//***************************写一字节数据****************************//
//向从地址为Slave的IIC器件的Address地址写一字节数据Data
void Write_1byte(uchar Slave,uchar Address,uchar Data)
{Start(); //开始
Write_Byte(Slave); //写I2C器件地址
do Check_Ack(); //检查应答位
while(Ack_Flag==1);
Write_Byte(Address); //送寄存器地址
do Check_Ack(); //检查应答位
while(Ack_Flag==1);
Write_Byte(Data); //写入一字节数据
do Check_Ack(); //检查应答位
while(Ack_Flag==1);
Stop(); //停止
}
//***************************写两字节数据****************************//
//向从地址为Slave的IIC器件的Address地址开始写两字节数据Data0,Data1
void Write_2byte(uchar Slave,uchar Address,uchar Data0,uchar Data1)
{Start(); //开始
Write_Byte(Slave); //写I2C器件地址
do Check_Ack(); //检查应答位
while(Ack_Flag==1);
Write_Byte(Address); //送寄存器地址
do Check_Ack(); //检查应答位
while(Ack_Flag==1);
Write_Byte(Data0);
do Check_Ack(); //检查应答位
while(Ack_Flag==1);
Write_Byte(Data1);
do Check_Ack(); //检查应答位
while(Ack_Flag==1);
Stop(); //停止信号
}
//***************************读一字节数据****************************//
//从从地址为Slave的IIC器件的Address地址处读一字节数据
uchar Read_1byte(uchar Slave,uchar Address)
{uchar data0,x;
do{
Start(); //开始信号
Write_Byte(Slave); //写I2C器件地址
Check_Ack(); //检查应答位
}while(Ack_Flag);
do{
Write_Byte(Address); //写寄存器地址
Check_Ack(); //检查应答位
}while(Ack_Flag);
do{
Start(); //开始
Write_Byte(Slave+1); //写I2C器件地址(+1表示为读操作)
Check_Ack(); //检查应答位
}while(Ack_Flag);
data0=Read_Byte(); //读1字节
Nack(); //读完发送一个Not Ack应答
Stop(); //停止
return data0; //返回读取数据
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -