atmega64a引脚SCL/SDA无响应



我有一张包含AVR ATMEGA64A的电子卡与DS3231连接,但是当我尝试阅读时间和日期并将它们分配给7个部分时(我认为没有任何通信)组件)。

这是我的代码:

i2c.h

#ifndef I2C_H_
#define I2C_H_
#include <avr/io.h>
#include <util/twi.h>
#define     F_SCL    400000UL
#define     TWBRX0   (((F_CPU/F_SCL)-16)/2)
#define     TWBRX1   TWBRX0/4
#define     TWBRX2   TWBRX0/16
#define     TWBRX3   TWBRX0/64
#define     NACK    0
#define     ACK     1
#if     (TWBRX0<=0xFF)
    #define     TWBRX   TWBRX0
    #define     TWPSX   0
#elif   (TWBRX1<=0xFF)
    #define     TWBRX   TWBRX1
    #define     TWPSX   1
#elif   (TWBRX2<=0xFF)
    #define     TWBRX   TWBRX2
    #define     TWPSX   2
#elif   (TWBRX3<=0xFF)
    #define     TWBRX   TWBRX3
    #define     TWPSX   3
#else
    #define     TWBRX   0
    #define     TWPSX   0
#endif
void        I2C_Init(void);
uint8_t     I2C_Start(void);
uint8_t     I2C_ReStart(void);
void        I2C_Stop(void);
uint8_t     I2C_Write(uint8_t );
uint8_t     I2C_Read(uint8_t );
#endif /* I2C_H_ */

i2c.c

#include "i2c.h"
void    I2C_Init(void)
{
    TWBR = TWBRX;
    TWSR = TWPSX;       
}

uint8_t I2C_Start( void )
{
    TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
    while (!(TWCR & (1<<TWINT)));
    if ((TWSR & 0xF8) != TW_START)
        return 0;
    return 1;
}

uint8_t I2C_ReStart( void )
{
    TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
    while (!(TWCR & (1<<TWINT)));
    if ((TWSR & 0xF8) != TW_REP_START)
        return 0;
    return 1;
}

void I2C_Stop( void )
{
    TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
    while(TWCR & (1<<TWSTO));
}
uint8_t I2C_Write( uint8_t data)
{
    TWDR = data;
    TWCR = (1<<TWINT)|(1<<TWEN) ;
    while (!(TWCR & (1<<TWINT)));
    if ((TWSR & 0xF8) != TW_MT_SLA_ACK)
        return 0;
    return 1;
}

uint8_t I2C_Read( uint8_t ACK_NACK)
{
    while (!(TWCR & (1<<TWINT)));
    TWCR = (ACK_NACK)?((1<<TWINT)|(1<<TWEN)|(1<<TWEA)):((1<<TWINT)|(1<<TWEN));
    while (!(TWCR & (1<<TWINT)));
    return  TWDR;
}

rtc.h

#ifndef RTC_H_
#define RTC_H_
#include "i2c.h"
typedef struct
{
    uint8_t Second; /* 0..59 */
    uint8_t Minute; /* 0..59 */
    uint8_t Hour;   /* 1..7 */
}Hora_t;
typedef struct
{
    uint8_t Day;    /* 1.. 31 */
    uint8_t Month;  /* 1..12 */
    uint8_t Year;   /* 00..99 */    
}Fecha_t;
typedef struct
{
        Hora_t  hora;
        Fecha_t fecha;  
}RTC_t;
#define     DS3231_SECONDS          0x00
#define     DS3231_MINUTES          0x01
#define     DS3231_HOURS            0x02
#define     DS3231_WEEKDAY          0x03
#define     DS3231_DAYS             0x04
#define     DS3231_MONTHS           0x05
#define     DS3231_YEARS            0x06
#define     MASK_SEC            0b01111111
#define     MASK_MIN            0b01111111
#define     MASK_HORA           0b00111111
#define     MASK_DIA            0b00111111
#define     MASK_MES            0b00011111
#define     MASK_ANIO           0b11111111
#define     DS3231_READ         0b11010001
#define     DS3231_WRITE        0b11010000

void    RTC_Init();
uint8_t DS3231_GetReg(uint8_t );
void    DS3231_SetReg(uint8_t , uint8_t );
void    RTC_SetHora (Hora_t* );
void    RTC_SetFecha(Fecha_t* );
void    RTC_GetHora (Hora_t* );
void    RTC_GetFecha(Fecha_t* );
void    RTC_GetTime(RTC_t *);
void    RTC_SetTime(RTC_t * );
#endif /* RTC_H_ */

rtc.c

#include "rtc.h"

void RTC_Init()
{
    I2C_Init(); 
}
uint8_t DS3231_GetReg( uint8_t address)
{
    uint8_t ret;
    I2C_Start();
    I2C_Write(DS3231_WRITE);
    I2C_Write(address);
    I2C_ReStart();
    I2C_Write(DS3231_READ);
    ret = I2C_Read(NACK);
    I2C_Stop(); 
    return ret;
}
void DS3231_SetReg( uint8_t address, uint8_t val)
{
    I2C_Start();
    I2C_Write(DS3231_WRITE);
    I2C_Write(address);
    I2C_Write(val);
    I2C_Stop(); 
}
void RTC_SetHora( Hora_t * hora)
{
    I2C_Start();
    I2C_Write(DS3231_WRITE);
    I2C_Write(DS3231_SECONDS);
    I2C_Write(hora->Second);
    I2C_Write(hora->Minute);
    I2C_Write(hora->Hour);
    I2C_Stop();
}
void RTC_SetFecha( Fecha_t * fecha)
{
    I2C_Start();
    I2C_Write(DS3231_WRITE);
    I2C_Write(DS3231_DAYS);
    I2C_Write(fecha->Day);
    I2C_Write(fecha->Month);
    I2C_Write(fecha->Year);
    I2C_Stop();
}
void RTC_GetHora( Hora_t* hora)
{
    I2C_Start();
    I2C_Write(DS3231_WRITE);
    I2C_Write(DS3231_SECONDS);
    I2C_ReStart();
    I2C_Write(DS3231_READ);
    hora->Second = (I2C_Read(ACK))& MASK_SEC;
    hora->Minute = (I2C_Read(ACK))& MASK_MIN;
    hora->Hour   = (I2C_Read(NACK))& MASK_HORA;
    I2C_Stop();
}
void RTC_GetFecha( Fecha_t* fecha )
{
    I2C_Start();
    I2C_Write(DS3231_WRITE);
    I2C_Write(DS3231_DAYS);
    I2C_ReStart();
    I2C_Write(DS3231_READ);
    fecha->Day   = (I2C_Read(ACK)) & MASK_DIA;
    fecha->Month = (I2C_Read(ACK)) & MASK_MES;
    fecha->Year  = (I2C_Read(NACK)) & MASK_ANIO;
    I2C_Stop();
}
void RTC_GetTime( RTC_t * rtc)
{
    RTC_GetHora(&rtc->hora);
    RTC_GetFecha(&rtc->fecha);
}
void RTC_SetTime( RTC_t * rtc)
{
    RTC_SetHora(&rtc->hora);
    RTC_SetFecha(&rtc->fecha);  
}

和我的主要程序:

main.c

#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "rtc.h"
static const uint8_t Pattern[] = {
    0b00010100, // 0
    0b00111111, // 1
    0b10011000, // 2  0b00100010
    0b00011010, // 3
    0b00110011, // 4
    0b01010010, // 5
    0b01010000, // 6  0b00000100
    0b00011111, // 7
    0b00010000, // 8
    0b00010010, // 9
0b11111111}; // BLANK
#define LED PG3  // pin 18
#define output_low(port,pin) port &= ~(1<<pin)
#define output_high(port,pin) port |= (1<<pin)
#define set_input(portdir,pin) portdir &= ~(1<<pin)
#define set_output(portdir,pin) portdir |= (1<<pin)
#define HC595_DS_POS PC4      //Data pin (DS) pin location
#define HC595_SH_CP_POS PC5      //Shift Clock (SH_CP) pin location
#define HC595_ST_CP_POS PC6     //Store Clock (ST_CP) pin location
#define HC595_PORT   PORTC
#define HC595_DDR    DDRC
void IE74595_Out(uint8_t *p, unsigned char n)
{
    unsigned char i, j;
    uint8_t b;
    output_low(HC595_PORT,HC595_ST_CP_POS);
    output_low(HC595_PORT,HC595_SH_CP_POS);

    for(j=0;j<n;j++)
    {
        b = Pattern[*(p+n-j-1)];        // Lay byte cao nhat truoc
        //  b = Pattern[*(p+j)];        // Lay byte cao nhat truoc
        for(i=0;i<8;i++)
        {
            output_low(HC595_PORT,HC595_SH_CP_POS);
            if(b & 0b00000001)
            {
                //MSB is 1 so output high
                output_high(HC595_PORT,HC595_DS_POS);
            }
            else
            {
                //MSB is 0 so output low
                output_low(HC595_PORT,HC595_DS_POS);
            }
            _delay_us(100);
            output_high(HC595_PORT,HC595_SH_CP_POS);
            b=b>>1;  //Now bring next bit at MSB position
        }
    }
    //_delay_us(5);
    output_high(HC595_PORT,HC595_ST_CP_POS);
}
int main(void)
{   

    set_output(DDRC,HC595_DS_POS);
    set_output(DDRC,HC595_SH_CP_POS);
    set_output(DDRC,HC595_ST_CP_POS);
    set_output(DDRG, LED);
    //uint8_t Tempurature_C[2];
    uint8_t Date_Clock[40]={5,9,1,6,1,1,0,9,1,7,1,5,4,2,6,2,8,7,0,7,1,2,3,5,1,5,4,2,1,7,5,9,1,9,4,8,1,5,2,3};
    RTC_t t ;
    RTC_Init();
    uint8_t Annee;
    uint8_t Mois;
    uint8_t Jour;
    uint8_t Heure;
    uint8_t Munites;
    uint8_t Secondes;
    while (1) 
    {
        RTC_GetTime(&t);
        Annee = t.fecha.Year;
        Mois = t.fecha.Month;
        Jour = t.fecha.Day;
        Heure =  t.hora.Hour;
        Munites = t.hora.Minute;
        Secondes = t.hora.Second;
        Date_Clock[40] = 2;
        Date_Clock[39] = 0;
        Date_Clock[38] = Annee/10;
        Date_Clock[37] = Annee%10;
        Date_Clock[36] = Mois/10;
        Date_Clock[35] = Mois%10;
        Date_Clock[34] = Jour/10;
        Date_Clock[33] = Jour%10;
        Date_Clock[32] = Heure/10;
        Date_Clock[31] = Heure%10;
        Date_Clock[30] = Munites/10;
        Date_Clock[29] = Munites%10;
        Date_Clock[28] = Secondes/10;
        Date_Clock[27] = Secondes%10;
        IE74595_Out(Date_Clock,40);


    }
    return 1;
}

我放了此指令:output_high(portg,led);查看程序挂在哪里。

因为我没有JTAG,可以在执行时调试程序我发现该程序在阅读数据时会悬挂。在此说明中: rtc_getTime(&amp; t);

为什么?

谢谢的

禁用" atmega103兼容性"保险丝位。ATMEGA64A默认是在Atmega103兼容模式下运送的,并且在此模式下不支持I2C(TWI)。

最新更新