这段程序主模式运行在32.768KHz。能观察到SDA和SCL上有信号输出,但从机无 响应(可以肯定从机无问题)。手上没有存储示波器,找不到问题,请帮助为谢 #include <iot24v.h> #include <macros.h> // 函数原型 void IICstart(void);//I2C开始条件 void IICstop(void); //I2C停止条件 void delay(unsigned int x);//延时 void EEPROM_write(unsigned char ucAddress,unsigned char ucData);//写EEPROM函数 unsigned char EEPROM_read(unsigned char ucAddress);//读EEPROM函数 void USI_TWI_Master_Transfer( unsigned char dat); //定义全局变量 unsigned char i=0; unsigned char ACK=0xff; //主函数开始================================== void main() {PORTB= 0xff; DDRB = 0x00; //B口内部上拉,输入口 PORTA= 0x50; DDRA = 0xff; //SDA,SCL推挽输出高电平,其余输出低电平 USICR=0x2a;//禁止中断,设置成两线软件触发时钟 USIDR=0xff;// 用释放电平装载数据寄存器 USISR=0xf0; //清除标志,复位计数器 EEPROM_write(0,0x55);//写1字节到EEPROM i=EEPROM_read(0); //从EEPROM读出1字节 IICstart();//产生开始条件 //USISR=0xf0;//清除标志, USI_TWI_Master_Transfer( 0x88); USI_TWI_Master_Transfer( 0x11); USI_TWI_Master_Transfer( 0x10); //delay(4676);//延时1秒 IICstop(); USISR=0xf0; //清除开始条件标志 while (1) { delay(18703);//延时4秒 } } //====================================== //在SCL高的情况下,SDA从高变到低,是为 //I2C的开始条件。 //======================================== void IICstart(void) { PORTA|=(1<<6); //置位SDA PORTA|=(1<<4); //SCL上升沿 PORTA&=~(1<<6);//清零SDA //delay(9352);//延时2秒 PORTA&=~(1<<4);//SCL下降沿 //delay(9352);//延时2秒 PORTA|=(1<<6); //置位SDA,该语句似乎是必须的,否则SDA将持续数出 //低电平???? }
void USI_TWI_Master_Transfer( unsigned char dat ) { unsigned char temp = (0<<USISIE)|(0<<USIOIE)|// 禁止中断 (1<<USIWM1)|(0<<USIWM0)|// 设置成两线模式 (1<<USICS1)|(0<<USICS0)|// 软件产生时钟 (1<<USICLK)|(1<<USITC); // 触发时钟端口 USIDR = dat; //建立欲传数据 USISR = 0xf0;//清除标志,复位计数器 do { USICR = temp;// 产生 SCL 上升沿 //delay(14027);//延时3秒 USICR = temp;// 产生 SCL 下降沿 //delay(14027);//延时3秒 }while( !(USISR & (1<<USIOIF)) );// 检查传输是否完成? PORTA|=(1<<6); //释放SDA PORTA|=(1<<4); //释放SCL DDRA &=~(1<<6);// SDA设置为输入 ACK=PINA & 0x40; DDRA = 0xff; //SDA设置为输出 PORTA&=~(1<<4);//SCL下降沿 USIDR = 0xFF;// Release SDA. } //======================================= //在SCL高的情况下,SDA从低变到高,是为 //I2C的停止条件。 //===================================== void IICstop(void) { PORTA &=~(1<<6);//清零SDA PORTA |=(1<<4); //SCL上升沿 //delay(4676);//延时1秒 PORTA |=(1<<6); //置位SDA } //=================== //延时函数 //=================== void delay(unsigned int x) { while(x--) ; // Empty } //=================== //写EEPROM函数 //=================== void EEPROM_write(unsigned char ucAddress,unsigned char ucData) {//等待前一次写操作结束 while(EECR & (1<<EEPE)) ; //设置编程模式 EECR = (0<<EEPM1)|(0>>EEPM0); //设置地址和数据寄存器 EEARL = ucAddress; EEDR = ucData; //写逻辑1到EEMPE EECR |= (1<<EEMPE); //设置EEPE后开始编程 EECR |= (1<<EEPE); } //=================== //读EEPROM函数 //=================== unsigned char EEPROM_read(unsigned char ucAddress) {//等待前一次写操作结束 while(EECR & (1<<EEPE)) ; //设置地址寄存器 EEARL = ucAddress; //写EERE后开始读EEPROM EECR |= (1<<EERE); //返回读出数据 return EEDR; } |