Lucas499 2019-08-24 19:23 采纳率: 0%
浏览 394

用ATMEGA8开发GY-273,IIC无应答信号

用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,猜测不是上拉电阻的问题

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 streamingtool
    • ¥15 MATLAB图像问题
    • ¥20 树莓派5做人脸情感识别与反馈系统
    • ¥15 selenium 控制 chrome-for-testing 在 Linux 环境下报错 SessionNotCreatedException
    • ¥15 使用pyodbc操作SQL数据库
    • ¥15 MATLAB实现下列
    • ¥30 mininet可视化打不开.mn文件
    • ¥50 C# 全屏打开Edge浏览器
    • ¥80 WEBPACK性能优化
    • ¥30 python拟合回归分析