- #include <iom16v.h>
- #include <macros.h>
- #define uchar unsigned char
- #define uint unsigned int
- //I2C 状态定义
- //MT 主方式传输 MR 主方式接受
- ///////////////////////////////////////////////////
- #define START 0x08
- #define RE_START 0x10
- #define MT_SLA_ACK 0x18
- #define MT_SLA_NOACK 0x20
- #define MT_DATA_ACK 0x28
- #define MT_DATA_NOACK 0x30
- #define MR_SLA_ACK 0x40
- #define MR_SLA_NOACK 0x48
- #define MR_DATA_ACK 0x50
- #define MR_DATA_NOACK 0x58
- #define RD_DEVICE_ADDR 0xA1 //前4位器件固定,后三位看连线,最后1位是读写指令位
- #define WD_DEVICE_ADDR 0xA0
- //常用TWI操作(主模式写和读)
- #define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) //启动I2C
- #define Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) //停止I2C
- #define Wait() {while(!(TWCR&(1<<TWINT)));} //等待中断发生
- #define TestAck() (TWSR&0xf8) //观察返回状态
- #define SetAck (TWCR|=(1<<TWEA)) //做出ACK应答
- #define SetNoAck (TWCR&=~(1<<TWEA)) //做出Not Ack应答
- #define Twi() (TWCR=(1<<TWINT)|(1<<TWEN)) //启动I2C
- #define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} //写数
- unsigned char smg_du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
- unsigned char smg_we[]={0x08,0x18,0x28,0x38,0x48,0x58,0x68,0x78};
- uchar table[8]={0,0,0,0,0,0,0,0};
- void init(void)
- {
- DDRB=0xff;
- PORTB=0;
-
- DDRC=0x78;//01111000
- PORTC=0;
- }
- void delay(void)
- {
- uint a;
- for(a=0;a<300;a++);
- }
- void display(uchar *p)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- PORTB=smg_du[*p];
- p++;
- PORTC=smg_we[i];
- delay();
- }
-
- }
- void twi_init(void)
- {
- TWBR=0x20;
- TWCR=0x04;
- TWSR=0;
- }
- uchar IIC_Write(uchar wdata,uchar addr)
- {
- Start();
- Wait();
- if(TestAck()!=START)
- return 1;
-
- Write8Bit(WD_DEVICE_ADDR);
- Wait();
- if(TestAck()!=MT_SLA_ACK)
- return 1;
-
- Write8Bit(addr);
- Wait();
- if(TestAck()!=MT_DATA_ACK)
- return 1;
-
- Write8Bit(wdata);
- Wait();
- if(TestAck()!=MT_DATA_ACK)
- return 1;
-
- Stop();
- return 0;
-
- }
- uchar IIC_Read(uchar addr)
- {
- uchar temp;
-
- Start();
- Wait();
- if(TestAck()!=START)
- return 1;
-
- Write8Bit(WD_DEVICE_ADDR);
- Wait();
- if(TestAck()!=MT_SLA_ACK)
- return 1;
-
- Write8Bit(addr);
- Wait();
- if(TestAck()!=MT_DATA_ACK)
- return 1;
-
- Start();
- Wait();
- if(TestAck()!=RE_START)
- return 1;
-
- Write8Bit(RD_DEVICE_ADDR);
- Wait();
- if(TestAck()!=MR_SLA_ACK)
- return 1;
-
- Twi();
- Wait();
- if(TestAck()!=MR_DATA_NOACK)
- return 1;
-
- temp=TWDR;
- Stop();
- return temp;
-
- }
- void main(void)
- {
- uchar i;
- init();
- twi_init();
- i=IIC_Read(0x03);
- table[1]=i;
- i++;
- i=i%10;
- IIC_Write(i,0x03);
- table[0]=i;
我修改成以下的样子,其实就是加了两行代码,原来是IIC_READ→IIC_WRITE,现在改成IIC_READ→IIC_WRITE→IIC_READ结果就不行了
- #include <iom16v.h>
- #include <macros.h>
- #define uchar unsigned char
- #define uint unsigned int
- //I2C 状态定义
- //MT 主方式传输 MR 主方式接受
- ///////////////////////////////////////////////////
- #define START 0x08
- #define RE_START 0x10
- #define MT_SLA_ACK 0x18
- #define MT_SLA_NOACK 0x20
- #define MT_DATA_ACK 0x28
- #define MT_DATA_NOACK 0x30
- #define MR_SLA_ACK 0x40
- #define MR_SLA_NOACK 0x48
- #define MR_DATA_ACK 0x50
- #define MR_DATA_NOACK 0x58
- #define RD_DEVICE_ADDR 0xA1 //前4位器件固定,后三位看连线,最后1位是读写指令位
- #define WD_DEVICE_ADDR 0xA0
- //常用TWI操作(主模式写和读)
- #define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) //启动I2C
- #define Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) //停止I2C
- #define Wait() {while(!(TWCR&(1<<TWINT)));} //等待中断发生
- #define TestAck() (TWSR&0xf8) //观察返回状态
- #define SetAck (TWCR|=(1<<TWEA)) //做出ACK应答
- #define SetNoAck (TWCR&=~(1<<TWEA)) //做出Not Ack应答
- #define Twi() (TWCR=(1<<TWINT)|(1<<TWEN)) //启动I2C
- #define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} //写数
- unsigned char smg_du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
- unsigned char smg_we[]={0x08,0x18,0x28,0x38,0x48,0x58,0x68,0x78};
- uchar table[8]={0,0,0,0,0,0,0,0};
- void init(void)
- {
- DDRB=0xff;
- PORTB=0;
-
- DDRC=0x78;//01111000
- PORTC=0;
- }
- void delay(void)
- {
- uint a;
- for(a=0;a<300;a++);
- }
- void display(uchar *p)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- PORTB=smg_du[*p];
- p++;
- PORTC=smg_we[i];
- delay();
- }
-
- }
- void twi_init(void)
- {
- TWBR=0x20;
- TWCR=0x04;
- TWSR=0;
- }
- uchar IIC_Write(uchar wdata,uchar addr)
- {
- Start();
- Wait();
- if(TestAck()!=START)
- return 1;
-
- Write8Bit(WD_DEVICE_ADDR);
- Wait();
- if(TestAck()!=MT_SLA_ACK)
- return 1;
-
- Write8Bit(addr);
- Wait();
- if(TestAck()!=MT_DATA_ACK)
- return 1;
-
- Write8Bit(wdata);
- Wait();
- if(TestAck()!=MT_DATA_ACK)
- return 1;
-
- Stop();
- return 0;
-
- }
- uchar IIC_Read(uchar addr)
- {
- uchar temp;
-
- Start();
- Wait();
- if(TestAck()!=START)
- return 9;
-
- Write8Bit(WD_DEVICE_ADDR);
- Wait();
- if(TestAck()!=MT_SLA_ACK)
- return 8;
-
- Write8Bit(addr);
- Wait();
- if(TestAck()!=MT_DATA_ACK)
- return 7;
-
- Start();
- Wait();
- if(TestAck()!=RE_START)
- return 6;
-
- Write8Bit(RD_DEVICE_ADDR);
- Wait();
- if(TestAck()!=MR_SLA_ACK)
- return 5;
-
- Twi();
- Wait();
- if(TestAck()!=MR_DATA_NOACK)
- return 4;
-
- temp=TWDR;
- Stop();
- return temp;
-
- }
- void main(void)
- {
- uchar i;
- init();
- twi_init();
- i=IIC_Read(0x03);
- table[1]=i;
- i++;
- i=i%10;
- IIC_Write(i,0x03);
- table[0]=i;
- i=IIC_Read(0x03); ☆
- table[2]=i; ☆
-
-
-
- while(1)
- {
- display(table);
- }
-
- }
就是五角星的那两行,从返回的代码上看是第二次IIC_READ函数里的(TestAck()!=START)返回错误,
是不是IIC当前非空闲所以不能再读啊?
求解决方法