void IIC_Delay(void)
{
_NOP();
_NOP();
_NOP();
}
// 启动I2C模块
void start_IIC(void) // 启动I2
{
P2OUT&=0f9; //设置P2输出
P2DIR&=0FD; //SDA=1, 上拉电阻使得P2.1为H,FD=1111,1101
P2DIR&=0FB; //SCL=1 FB="1111",1011
P2DIR|=002; // SDA="0"
P2DIR|=004; // SCL="0"
}
// 停止I2C模块
void stop_IIC(void) //
{
P2DIR|=002;//SDA=0
IIC_Delay();
P2DIR&=0FB;//SCL=1 FB="1111",1011
P2DIR&=0FD;//SDA=1, 上拉电阻使得P2.1为H,FD=1111,1101
IIC_Delay();
P2DIR|=004;// SCL="0"
}
// 发送 “ 0”模块
void send_zero(void) //
{
P2DIR|=002;// SDA="0"
IIC_Delay();
P2DIR&=0FB;//SCL=1 FB="1111",1011
IIC_Delay();
P2DIR|=004;// SCL="0"
}
// 发送 1模块
void send_one(void) //
{
P2DIR&=0FD;//SDA=1, 上拉电阻使得P2.1为H,FD=1111,1101
IIC_Delay();
P2DIR&=0FB;//SCL=1 FB="1111",1011
IIC_Delay();
P2DIR|=004;// SCL="0"
}
// 发送单字符数据
void send _cha(unsigned char data_out) //
{
unsigned char i,tmp=080;
for(i=0;i<8;i++)
{
if((data_out & tmp)>0)
send_one();
else
send_zero();
tmp/=2;
}
}
// 读单字符数据
unsigned char read_cha(void)
{
unsigned char i,tmp=080;
unsigned char data1=0;
for (i=0;i<8;i++)
{
P2DIR&=0FD;//SDA=1, 11111101
IIC_Delay();//
P2DIR&=0FB;//SCL=1 FB="1111",1011
IIC_Delay();
if((P2IN&002)>000)
{
data1|=tmp;
}
P2DIR|=004;// SCL="0"
IIC_Delay();
tmp/=2;
}
return data1;
}
// & 检查应答信号模块
void iic_ACK(void)
{
ack_flag=000;
P2DIR&=0FD;//SDA=1, FD="1111",1101
IIC_Delay();
P2DIR&=0FB;//SCL=1 FB="1111",1011
IIC_Delay();
while((P2IN&BIT1)==BIT1);
P2DIR|=004;// SCL="0"
IIC_Delay();
}
// 拒绝应答模块
void iic_NACK(void) & nbsp; {
P2DIR&=0FD;//SDA=1,
IIC_Delay();
P2DIR&=0FB;//SCL=1 FB="1111",1011
IIC_Delay();
P2DIR|=004;// SCL="0"
IIC_Delay();
P2DIR|=002;// SDA="0"
IIC_Delay();//
}
// 写连续数据模块
void WriteNbyte(unsigned char *p,unsigned int addr,unsigned char number)
{
start_IIC();
send_cha(0a2);
iic_ACK();
send_cha(addr/256); //high address byte
iic_ACK();
send_cha(addr%256);
iic_ACK();
do
{
send_cha(*p);
p++;
iic_ACK();
}
while(--number);
stop_IIC();
delay(10);
}
// 发送应答模块:ACK (LOW)
void S_ACK(void)
{
P2DIR|=002;// SDA="0"
;IIC_Delay();
P2DIR&=0FB;//SCL=1 FB="1111",1011
IIC_Delay();
P2DIR|=004;// SCL="0"
IIC_Delay();
}
// 连续读字符模块
void ReadNbyte(unsigned char *p,unsigned int addr,unsigned char number)
{
start_IIC();
send_cha(0a2);
iic_ACK();
send_cha(addr/256);
iic_ACK();
send_cha(addr%256);
iic_ACK();
start_IIC();
send_cha(0a3);
iic_ACK();
do
{
*p=read_cha();
p++;
if(number!=1)
S_ACK(); //send ACK
}
while(--number);
iic_NACK();
stop_IIC();
}
数据的传输
数据传输是存储在EEPROM中的数据到达计算机的有效途径,数据上传到计算机常用的是串行(RS232)接口,
现在由于USB计数的不断成熟,通过USB可以方便快捷实现数据传输,而且可以满足速率和设备外观的要求,但是USB的驱动程序设计是比较复杂的工作,本例中使用简单的桥接电路,把UART接口的数据经过CP2102的桥接,直接实现数据的USB转换,从430F449异步串口输出的数据自动转化为符合USB协议的数据直接连接到计算机的USB口,上位机应用程序通过CP2102的驱动程序可以象操作串口一样直接读写端口数据。
结论
以上的硬件设计比较简单可靠,可以照搬到同类型的控制芯片上,软件代码也同样具有较好的移植性,只要把控制时钟和数据端口和程序软件设置相一致即可。