本帖最后由 dapollo2014 于 2014-9-30 10:33 编辑
小弟正在学习AVR,这两天在看TWI,用两个ATmega16板,编了一个主发从接,然后同步闪烁LED的小程序,可是从机怎么都没反应,看Error函数貌似主机没有收到发送地址的反馈,论坛里的高手能否指教一下,问题出在哪里,不胜感激!
主机
#include <util/delay.h>
#include <compat/twi.h>
unsigned char runlight[7]={0x10,0x30,0x70,0xf0,0x70,0x30,0x10};
unsigned char status;
#define ADDRESS 0X33
void TWI_IO_Initial()
{
DDRA=0XF0;//set IO port PA4~7 to light on LED
PORTA=0XF0;
_delay_ms(300);
}
void TWI_Initial()
{
DDRC&=~((1<<0)|(1<<1));//set TWI port PC0~1
PORTC|=(1<<0)|(1<<1);
TWBR=0X64;
TWSR=0X00;
}
void TWI_Error1()
{
while(1)
{
PORTA=0X10;
_delay_ms(1000);
PORTA=0X00;
_delay_ms(1000);
}
}
void TWI_Error2()
{
while(1)
{
PORTA=0X20;
_delay_ms(1000);
PORTA=0X00;
_delay_ms(1000);
}
}
void TWI_Error3()
{
while(1)
{
PORTA=0X40;
_delay_ms(1000);
PORTA=0X00;
_delay_ms(1000);
}
}
unsigned char TWI_Start()
{
TWCR|=(1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
while(!(TWCR&(1<<TWINT)))
;
status=TWSR&0XF8;
TWCR&=~(1<<TWSTA);//TWSTA清零
}
void TWI_SendByte(unsigned char data)
{
TWDR=data;
TWCR|=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)))
;
status=TWSR&0XF8;
}
void TWI_Stop()
{
TWCR|=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}
int main(void)
{
TWI_Initial();
TWI_IO_Initial();
while(1)
{
TWI_Start();
if(status!=TW_START)
TWI_Error1();
TWI_SendByte((ADDRESS<<1)|TW_WRITE);
if(status!=TW_MT_SLA_ACK)
TWI_Error2();
unsigned char i;
for(i=0;i<7;i++)
{
TWI_SendByte(runlight);
if(status!=TW_MT_DATA_ACK)
TWI_Error3();
PORTA=runlight;
_delay_ms(1000);
}
TWI_Stop();
}
}
从机
#include <util/delay.h>
#include <compat/twi.h>
#define ADDRESS 0X33
void TWI_IO_Initial()
{
DDRA=0XF0;//set IO port PA4~7to light on LED
PORTA=0XF0;
}
void TWI_Initial()
{
DDRC&=~((1<<0)|(1<<1));//set TWI port PC0~1
PORTC|=(1<<0)|(1<<1);
TWCR=0X00;
TWBR=0X64;
TWAR=ADDRESS<<1;
TWCR|=(1<<TWEN)|(1<<TWEA)|(1<<TWIE);
}
int main(void)
{
TWI_Initial();
TWI_IO_Initial();
while(1)
{
TWCR|=(1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while(!(TWCR&(1<<TWINT)))
;
unsigned char status=TWSR&0XF8;
switch(status)
{
case TW_SR_SLA_ACK:
break;
case TW_SR_DATA_ACK:
PORTA=TWDR;
break;
break;
case TW_SR_STOP:
break;
default:break;
}
}
}
|