0

I have an electronic card that contains the AVR atmega64A connect with DS3231 but when I try to read the time and date and assign them to the 7 SEGMENTS nothing is displayed (i think no communication between the components).

here you are my code :

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);  
}

And my main program :

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;
}

I put this instruction: output_high(PORTG, LED); to see where the program hangs.

Because I do not have a JTAG that allows me to debug the program at the time of its execution   I found that the program hangs when reading data. In this instruction : RTC_GetTime(&t);

Why ?

Thank's

khaloud1980
  • 43
  • 1
  • 7
  • You will have to narrow down your problem some more. Pasting your whole project here and asking why it's not working is specifically not what should be done. Besides, this is more of a problem for http://electronics.stackexchange.com/. – JimmyB Dec 10 '16 at 10:18

1 Answers1

1

Disable "ATmega103 Compatibility" Fuse bit. ATmega64A is by default shipped in ATmega103 compatibility mode and I2C (TWI) is not supported in this mode.