用ATMEGA8开发GY-273,IIC无应答信号。
经过逐步调试,程序卡在了
if(TestAck()!=MT_SLA_ACK)
return 1; //ACK
Send_Char(0x33);//测试用
也就是说,第一次写操作就进行不了
附上全部代码**___
//ICC-AVR application builder : 2009-3-12 17:05:04
// Target : M8
// Crystal: 8.0000Mhz
#include <avr/io.h>
#include <avr/interrupt.h>
#include <macros.h>
#include "usart.h"
void port_init(void)
{
DDRB|=0X04;//B2,LED_DOWN,PIN16
DDRC|=0X02;//C1,LED_LEFT,PIN24
DDRC|=0X08;//C3,LED_RIGHT,PIN26
DDRC|=0X20;//C5,LED_UP,PIN28
DDRB|=0X01;//B0,LED_OK,PIN14
DDRD|=0X40;//D6,TEST,PIN12
DDRC&=~0X01;//C0,KEY_LEFT,PIN23
DDRC&=~0X04;//C2,KEY_RIGHT,PIN25
DDRC&=~0X10;//C4,KEY_UP,PIN27
DDRB&=~0X02;//B1,KEY_DOWN,PIN15
DDRD&=~0X80;//D7,KEY_OK,PIN13
PORTC |= 0xFF;
PORTB |= 0xFF;
PORTD |= 0xFF;
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
cli(); //disable all interrupts
port_init();
MCUCR = 0x00; //MCU Control Register
GICR = 0x00; //General Interrupt Control Register
TIMSK = 0x00; //timer interrupt sources
sei(); //re-enable interrupts
//all peripherals are now initialized
}
/*************************************************************************
用 途:iic发送接收
Taget :mega8
crystal :8M
介 绍:PC4-SDA
PC5-SCK/SCL
//***********************************************************************
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 0x3c //前4位器件固定,后三位看连线,最后1位是读写指令位
#define WD_DEVICE_ADDR 0x3d
#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);} //写数据到TWDR
/*延时子程序*/
void delay_ms(int time)
{
int i;
for(;time>0;time--)
for(i=0;i<1000;i++);
}
//初始化
void iic_init()
{
TWBR= 0x20; //设置波特率
TWSR= 0x00; //设置预分频比
TWCR= 0x44; //使能应答,使能TWI
DDRC|=(1<<PC4)|(1<<PC5);
PORTC|=(1<<PC4)|(1<<PC5);
}
/*********************************************
I2C总线写一个字节
返回0:写成功
返回1:写失败
**********************************************/
unsigned char iic_write(unsigned char Wdata,unsigned char RegAddress)
{
Start(); //I2C启动
Wait();
if(TestAck()!=START)
return 1; //ACK
Send_Char(0x11);//测试用
Write8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式
Wait();
Send_Char(0x22);//测试用
## ** if(TestAck()!=MT_SLA_ACK)
## return 1; //ACK
## Send_Char(0x33);//测试用**
Write8Bit(RegAddress); //写器件相应寄存器地址
Wait();
if(TestAck()!=MT_DATA_ACK)
return 1; //ACK
Write8Bit(Wdata); //写数据到器件相应寄存器
Wait();
if(TestAck()!=MT_DATA_ACK)
return 1; //ACK
Stop(); //I2C停止
delay_ms(100); //延时
return 0;
}
/*********************************************
I2C总线读一个字节
返回非0:读成功
返回0:读失败
**********************************************/
unsigned char iic_read(unsigned RegAddress)
{
unsigned char temp;
Start();//I2C启动
Wait();
if (TestAck()!=START)
return 1; //ACK
Write8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式
Wait();
if (TestAck()!=MT_SLA_ACK)
return 1; //ACK
Write8Bit(RegAddress); //写器件相应寄存器地址
Wait();
if (TestAck()!=MT_DATA_ACK)
return 1;
Start(); //I2C重新启动
Wait();
if (TestAck()!=RE_START)
return 1;
Write8Bit(RD_DEVICE_ADDR); //写I2C从器件地址和读方式
Wait();
if(TestAck()!=MR_SLA_ACK)
return 1; //ACK
Twi(); //启动主I2C读方式
Wait();
if(TestAck()!=MR_DATA_NOACK)
return 1; //ACK
temp=TWDR; //读取I2C接收数据
Stop(); //I2C停止
return temp;
}
//****************************************************************************
void main()
{
unsigned char i,j;
port_init();
init_devices();
usart_Init();
iic_init();
i=iic_write(0xaa,0X10);//在0X10地址写入数据0XAA
if (i==1)
PORTB=0x1;//若写入失败(i=1),B口0x01;若写入成功,B口输出0X02
else
PORTB=0x2;
j=iic_read(0X10);//读出0x10地址的数据
if(j==1)
PORTD=0xff; //若读出失败(j=1),D口全灭;若读出成功,D口输出0XAA
else
PORTD=j;
while(1)
{
;
}
}
检测过SCL 和 SDA 的IO口输出电压为3.3V,猜测不是上拉电阻的问题