Problem with simulataneous working of SPI and UART in ATmega168A

Go To Last Post
20 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Recently I tried to interface Atmega168A microcontroller with 25LC256 SPI EEPROM. The hex file I created using Atmel Studio 7 work as expected in Proteus simulation. But when I interfaced it with real EEPROM the UART in not working properly. When I comment out the SPI initialization function and do UART communication alone every thing work fine.  The AVR is working in internal 8Mhz crystal oscillator with CLKDIV8 fuse bit unprogrammed to get full 8MHZ clock speed. UART work properly without initializing the SPI protocol. At first I used setbaud.h library to initialize UART, later after finding problem I commented out and manually enter baud rate by reffering to datasheet given value for baud rate of 9600. One thing to notice is that without calling SPI initialization function the UART work very well when using setbaud.h and by manually setting baud rate. I attached all codes *.c files including main, SPI and UART header files and the *.hex file too. So any body can test this circuit or can run a simulation on any other software. I tried several ways but cannot find any clue. Need Help from you guys.

 

Below is the image showing EEPROM data read and write successfully in Proteus simulation.

Attachment(s): 

avr freaky

Last Edited: Mon. Aug 12, 2019 - 07:33 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do any body have any Idea, Please comment below section.

avr freaky

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does your "live" circuit have all the power pins connected, with bypass caps?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I doubled Checked the power pins, and the circuit is powered via AVR ASP programmer directly through USB. One thing I didn't do is adding a bypass capacitor across VCC and GND pin of my microcontroller. I actually directly soldered IC with base on a perf/dot board. Since Powering from USB, which I think free of any noise I didn't add the capacitor. I will look in to it. Do that will really cause any issue?? Because when I uploaded UART program alone it worked fine. I also interfaced ADXL335 accelerometer with this setup by displaying it's X,Y,Z axis value through UART interface. Until I tested along with SPI, it never give me any issues. All other code even blinking and shifting led works fine(I tested several time during debugging my current issue)..

 

Thanks for your reply...

avr freaky

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

You aren't seriously trying to use the uart in the '168 without an accurate clock?  A crystal is required if you hope to have stable results.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

RAM_EV wrote:
and the circuit is powered via AVR ASP programmer directly through USB.

 

I don't know why people do this.  NOT a good idea!  Apply a proper power source for starters.

 

Post your code...how is anyone going to be able to see whats going on inside the AVR?

 

Jim

 

 

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

The AVR generates the ‘noise’, not the power source. Bypass caps are critical for correct operation.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I already attached all *.c files and *.h files on this post. Any way I will copy paste each file once again.

avr freaky

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SPI_LIB.c file (Spi library source file):
 

/*
 * SPI_LIB.c
 *
 * Created: 10-Aug-19 1:34:58 PM
 *  Author: RAM
 */

#include "SPI_LIB.h"

 /* Initialization function for SPI communication. Here SPI initialized in MODE 0  */
 void initSPI(void)
 {
     SPI_SS_DDR |= (1<<SPI_SS); /* Set SS pin as output */
     SPI_SS_PORT |= (1<<SPI_SS); /* SS Initially set to HIGH*/
    
     SPI_MOSI_DDR |= (1<<SPI_MOSI); /* MOSI as OUTPUT */
    
     SPI_MISO_PORT |= (1<<SPI_MISO); /* Turn PUll up */
    
     SPI_SCK_DDR |= (1<<SPI_SCK); /* SCK as OUTPUT */
    
     /* Setting SPI MASTER IN MODE 0 WITH FOSC/16 SCK */
     SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
    
 }

 /* Write relatedFUnction will goes here */

 /* SPI communication byte send function */
 void SPITradeByte(uint8_t byte)
 {
     SPDR = byte; /* Starts sending data immediately */
     loop_until_bit_is_set(SPSR,SPIF); /* Wait Until SPI transmission is completed */
    
 }
 
 /*EEPROM 16 bit address send*/
 void EEPROM_send16BitAddress(uint16_t address)
 {
     SPITradeByte( (uint8_t) (address>>8) ); /* Send MSB 8 bit first */
     SPITradeByte( (uint8_t) address ); /* Send LSB next */
 }

 /* EEPROM api for enabling write latch */
 void EEPROM_WriteEnable(void)
 {
     SLAVE_SELECT;
     SPITradeByte(EEPROM_WREN); /* Send WREN command */
     SLAVE_DESELECT;
 }

 /* EEPROM api for Writing Byte into memory array */
 void EEPROM_WriteByte(uint16_t address, uint8_t byte)
 {
     EEPROM_WriteEnable();
     SLAVE_SELECT;
     SPITradeByte(EEPROM_WRITE); /* Send Write Command */
     EEPROM_send16BitAddress(address);
     SPITradeByte(byte);
     SLAVE_DESELECT;
     EEPROM_waitWrite();
    
 }

 /* EEPROM api for writing word in to memory*/
 void EEPROM_WriteWord(uint16_t address, uint16_t word)
 {
    EEPROM_WriteEnable();
    SLAVE_SELECT;
    SPITradeByte(EEPROM_WRITE); /* Send Write Command */
    EEPROM_send16BitAddress(address);
    SPITradeByte( (uint8_t) (word>>8) );
    SPITradeByte( (uint8_t) word );
    SLAVE_DESELECT;
    EEPROM_waitWrite();
 }

 /* EEPROM api to clear all memory */
 void EEPROM_ClearAll(void)
 {
     uint8_t i;
     uint16_t pageAddress = 0;
     while (pageAddress < EEPROM_BYTES_MAX)
      {
         EEPROM_WriteEnable();
         SLAVE_SELECT;
         SPITradeByte(EEPROM_WRITE);
         EEPROM_send16BitAddress(pageAddress);
         for (i = 0; i < EEPROM_BYTES_PER_PAGE; i++)
         {
             SPITradeByte(0);
         }
         SLAVE_DESELECT;
         pageAddress += EEPROM_BYTES_PER_PAGE;
         EEPROM_waitWrite();
         }
 }
 

 /* Read related FUnction will goes here */

 /* EEPROM api to read value of status register*/
 uint8_t EEPROM_readStatus(void)
 {
     SLAVE_SELECT;
     SPITradeByte(EEPROM_RDSR); /* Send ReadStatusReg Command */
     SPITradeByte(0);
     SLAVE_DESELECT;
     return SPDR;
 }

 /* EEPROM api to read a Byte from EEPROM*/
uint8_t EEPROM_readByte(uint16_t address)
 {
     SLAVE_SELECT;
     SPITradeByte(EEPROM_READ); /* Send Read Command */
     EEPROM_send16BitAddress(address);
     SPITradeByte(0);
     SLAVE_DESELECT;
     return SPDR;
 }

 /* EEPROM api to read a word from EEPROM*/
 uint16_t EEPROM_readWord(uint16_t address)
 {
     uint16_t eepromWord;
     SLAVE_SELECT;
     SPITradeByte(EEPROM_READ); /* Send Read Command */
     EEPROM_send16BitAddress(address);
     SPITradeByte(0);
     eepromWord = SPDR;
     eepromWord = (eepromWord<<8);
     /* Getting LSB */
     SPITradeByte(0);
     eepromWord += SPDR;
     SLAVE_DESELECT;
     return eepromWord;
 }

/* EEPROM api for waiting to Write Operation */
void EEPROM_waitWrite(void)
{
    while(EEPROM_readStatus() & (1<<EEPROM_WRITE_IN_PROGRESS) );
}

 

 

 

avr freaky

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SPI_LIB.h file (header file which contain macro definitions)

 

/*
 * SPI_LIB.h
 *
 * Created: 10-Aug-19 1:34:41 PM
 *  Author: RAM
 */

#ifndef SPI_LIB_H_
#define SPI_LIB_H_

/* Library Functions for proper working of Driver */

#include <avr/io.h>
#include <avr/sfr_defs.h> // library for loop_until_bit_set() and other functions

 

/* Macro definitions for SPI pins, There port reg and ddr regs*/

#define SPI_SS PB2
#define SPI_SS_PORT PORTB
#define SPI_SS_PIN PINB
#define SPI_SS_DDR DDRB

#define SPI_MOSI PB3
#define SPI_MOSI_PORT PORTB
#define SPI_MOSI_PIN PINB
#define SPI_MOSI_DDR DDRB

#define SPI_MISO PB4
#define SPI_MISO_PORT PORTB
#define SPI_MISO_PIN PINB
#define SPI_MISO_DDR DDRB

#define SPI_SCK PB5
#define SPI_SCK_PORT PORTB
#define SPI_SCK_PIN PINB
#define SPI_SCK_DDR DDRB

/* Macro operation for SS Pin Select and De-select */

#define SLAVE_SELECT SPI_SS_PORT &= ~(1<<SPI_SS)
#define    SLAVE_DESELECT SPI_SS_PORT |= (1<<SPI_SS)

/* Macro definition for instruction to EEPROM */

#define EEPROM_READ      0b00000011                     /* read memory */
#define EEPROM_WRITE     0b00000010                 /* write to memory */

#define EEPROM_WRDI      0b00000100                   /* write disable */
#define EEPROM_WREN      0b00000110                    /* write enable */

#define EEPROM_RDSR      0b00000101            /* read status register */
#define EEPROM_WRSR      0b00000001           /* write status register */

/* Macro definition for Bits in EEPROM status register */

#define EEPROM_WRITE_IN_PROGRESS    0
#define EEPROM_WRITE_ENABLE_LATCH   1
#define EEPROM_BLOCK_PROTECT_0      2
#define EEPROM_BLOCK_PROTECT_1      3

/* Below definition are for EEPROM clear api */
#define EEPROM_BYTES_PER_PAGE       64
#define EEPROM_BYTES_MAX            0x7FFF

/* Driver Function for SPI communication and EEPROM access operations */

 /* Initialization function for SPI communication. Here SPI initialized in MODE 0  */
void initSPI(void);

/* Write relatedFUnction will goes here */

/* SPI communication byte send function */
void SPITradeByte(uint8_t byte);

/*EEPROM 16 bit address send*/
void EEPROM_send16BitAddress(uint16_t address);

/* EEPROM api for enabling write latch */
void EEPROM_WriteEnable(void);

/* EEPROM api for Writing Byte into memory array */
void EEPROM_WriteByte(uint16_t address, uint8_t byte);

/* EEPROM api for writin word in to memory*/
void EEPROM_WriteWord(uint16_t address, uint16_t word);

/* EEPROM api to clear all memory */
void EEPROM_ClearAll(void);

/* Read related FUnction will goes here */

/* EEPROM api to read value of status register*/
uint8_t EEPROM_readStatus(void);

/* EEPROM api to read a Byte from EEPROM*/
uint8_t EEPROM_readByte(uint16_t address);

/* EEPROM api to read a word from EEPROM*/
uint16_t EEPROM_readWord(uint16_t address);

/* EEPROM api for waiting to Write Operation */
void EEPROM_waitWrite(void);

#endif /* SPI_LIB_H_ */

 

avr freaky

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

UART.c file

 

/*
 * UART.c
 *
 * Created: 3/13/2019 10:52:05 PM
 *  Author: RAM
 */
#include <avr/io.h>
#include <avr/sfr_defs.h> // library for loop_until_bit_set() and other functions
#include "UART.h"// this should be declared before calling setbaud.h
/* This is done due to the fact that if baud macro is defined inside this uart.h. lib */
#define  F_CPU 8000000
//#include <util/setbaud.h>
#include <math.h>

void init_UART(void)
{
    /* Using library based macros
    UBRR0H = UBRRH_VALUE;
    UBRR0L = UBRRL_VALUE;
     */
    /* Using datasheet provided value to set
     * baud rate to 9600 */
    
    UBRR0H =0x00;
    UBRR0L = 51;
    
    /*
     * An additional macro USE_2X will be defined. Its value is set to 1 if the desired
     * BAUD rate within the given tolerance could only be achieved by setting the U2X bit
     * in the UART configuration.It will be defined to 0 if U2X is not needed.
    */
    
        

    UCSR0A &= (1<<U2X0);
    UCSR0B = (1<< TXEN0) | (1<< RXEN0); /* ENABLE TX AND RX */
    //UCSR0C &= ( ~(1<<7) | ~(1<<6) );// SETTING IN ASYNCHRONOUS MODE
    UCSR0C &= ( ~(1<<UMSEL01) | ~(1<<UMSEL00) );
    UCSR0C |= (1<< UCSZ01) | (1<< UCSZ00);/* 8 DATA BITS, 1 STOP BITS */
    
}

/*
 * ANOTHER METHOD TO INIT_UART_9600() FUNCTION
 * but here 9600 baud rate can only be achieved
*/

/*
static void INIT_UART_9600(void)
{
    #define BAUD 9600; // should define BAUD macro before proceeding
    #include <util/setbaud.h> // Include setbaud.h after defining BAUD macro
    UBRRH = UBRRH_VALUE;    // Load setbaud.h generated value to UBRRnX registers
    UBRRL = UBRRL_VALUE;
    #if USE_2X            // Check the need of USE_2X bit to achieve desired baud rate
    UCSRA |= (1<<U2X);
    #else
    UCSRA &= ~(1<<U2X);
    #endif
}
*/

 void transmitByte(uint8_t data)
{
    /*
     *    while(!(UCSR0A & (1<<UDRE0))); // THIS IS ALSO POSSIBLE //
    */
    loop_until_bit_is_set(UCSR0A,UDRE0);
    UDR0 =data;
}

uint8_t receiveByte(void)
{
    /*
     *    while(!(UCSR0A & (1<<RXC0))); // THIS IS ALSO POSSIBLE //
    */
    loop_until_bit_is_set(UCSR0A,RXC0);
    return UDR0;
}

void printString(const char *myString)
{
    while(*myString)
    {
        transmitByte(*myString++);
    }
}

/* Function to send a byte number through Serial port */

void sendByte(uint8_t Byte)
{
    transmitByte('0'+((Byte/100)%10));
    transmitByte('0'+((Byte/10)%10));
    transmitByte('0'+(Byte%10));
}

/* Function that will send a 4 digit number in character form through uart */

void sendWord(uint16_t num)
{
    transmitByte('0'+(num/1000));
    transmitByte('0'+((num/100)%10));
    transmitByte('0'+((num/10)%10));
    transmitByte('0'+(num%10));
    
}

/* Function to send binary value of a byte  */

void sendBinByte(uint8_t bin)
{
    int8_t i=0;  /* This should be integer so that it can have value -1 which makes the loop condition false */
                /* if we use datatype uint8_t then after reaching zero, on next for loop control variable decrement
                 * this will rollback to 255 and this trigger an infinite loop since the condition will always be
                 * true i>=0 ie  i>=255, i>=254 and so on.. */

    /* Here if we follow this method we can use uin8_t i=0, since after last decrement i value will be 255 and condition
     * i<255 will become false since i value is 255 itself   */        
            
    //for(i=7;i<255;i--)
    //{
        //if (bin & (1<<i))
        //{
            //transmitByte('1');
        //}
        //else
        //{
            //transmitByte('0');
        //}
    //}
    
    /* To follow normal logic, you should be declaring i as int8_t, more information refer above comments */
    for (i=7;i>=0;i--)
    {
        transmitByte((((bin&(1<<i)))>>i)+'0');
    }
    transmitByte(0x0d); // send a new line
}

void readString(char strIn[], uint8_t maxLength)
{
    char response;
    uint8_t i=0;
    while(i<(maxLength-1))
    {
        response = receiveByte();
        if (response == '\r')
        {
            break;
        }
        else
        {
            strIn[i]= response;
            i++;
        }
    }
    strIn[i]='\0'; // null terminating the string
    
}

uint8_t getNumber(void)
{
    // Gets a numerical 0-255 from the serial port.
    // Converts from string to number.
    char hundreds = '0';
    char tens = '0';
    char ones = '0';
    char thisChar = '0';
    do {                                                   /* shift over */
        hundreds = tens;
        tens = ones;
        ones = thisChar;
        thisChar = receiveByte();                   /* get a new character */
        //transmitByte(thisChar);                                    /* echo */
        } while (thisChar != '\r');                     /* until type return */
        return (100 * (hundreds - '0') + 10 * (tens - '0') + ones - '0');
}

 

/*
uint8_t getNumber(void)
{
    char dummy;//,hundred, ten , one;
    uint8_t out=0,count = 2;
    
    while (count<255)
    {
        dummy = receiveByte();
        if (dummy == '\r')
        {
            break;
        }
        uint8_t tenPow= pow(10,count);
        out +=((dummy-'0')*tenPow) ;
        count--;
        
    }
    
    return out;
    
}
*/

 

 

 

avr freaky

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

USART.h file

 

 

/*
 * UART.h
 *
 * Created: 3/13/2019 10:51:44 PM
 *  Author: RAM
 */

#ifndef UART_H_
#define UART_H_

#ifndef BAUD /* if not defined in makefile define one */
#define BAUD 9600 /* define a safe default baud rates*/
#endif

#define  USART_HAS_DATA bit_is_set(UCSR0A, RXC0) /* Checks whether any data is arrived on UDR*/
#define  USART_READY    bit_is_set(UCSR0A,UDRE0) /* Checks whether UDR is free to write some data to it */

/* Function to setup UART */
void init_UART(void);
/* Blocking function to transmit and receive
*  This code will hang either in rx or tx mode
*/
void transmitByte(uint8_t data);

uint8_t receiveByte(void);

/* Function to transmit entire string */

void printString(const char *myString);

/* Function that will send a 4 digit number in character form through uart */

void sendWord(uint16_t num);

/* Function to send a byte number through Serial port */
void sendByte(uint8_t Byte);

/* Function to send binary value of a byte  */

void sendBinByte(uint8_t bin);

/* Function to get a 3 digit number from serial port */

uint8_t getNumber(void);

/* Function to read a definite length string from serial port */

void readString(char strIn[], uint8_t maxLength);

#endif /* UART_H_ */

 

 

 

 

 

avr freaky

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Finally main.c file

 

 

 

 

#include <avr/io.h>
#include <avr/sfr_defs.h> // library for loop_until_bit_set() and other functions
#define  F_CPU 8000000
#include <util/delay.h>
#include "UART.h" // this should be declared before calling setbaud.h
/* This is done due to the fact that if baud macro is defined inside this uart.h. lib */
#include <util/setbaud.h>
#include "SPI_LIB.h"

int main (void)
{
    uint8_t i, address;
    initSPI();
    init_UART();
    
    
    while (1)
    {
        //transmitByte(receiveByte());
        printString("Data inside EEPROM in First 10 memory location:\r\n");
        //printString("THE TEST STRING 22\r\n");
        for (i=0;i<10;i++)
        {
            printString("Data in ");
            transmitByte(i+'0');
            printString(" is: ");
            sendByte(EEPROM_readByte(i));
            transmitByte(0x0d);
        }
        //
        printString("Press E to erase or D to write data to EEPROM: ");
        
        switch(receiveByte())
        {
            case 'E':
                printString("\r\nErasing EEPROM!\r\n");
                EEPROM_ClearAll();
            break;
            case 'D':
                printString("\r\nPlease Enter the number you want to store:  ");
                i=getNumber();
                printString("\r\nEnter the address location in EEPROM: ");
                address=getNumber();
                EEPROM_WriteByte(address,i);
                printString("\r\n Number Store Successfully!!\r\n");
            break;
            default:
                printString("\r\nUse recognizable options!!\r\n");
            break;
            
        }
        
        //_delay_ms(2000);
    }
    return 0;
}

 

avr freaky

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But the UART based programs are working fine, I tested several times with many peripherals. Only when I add/ call iniSpi() function or start spi communication the problem arise.

avr freaky

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

The first step when working with the UART is to get an accurate & stable clock source.  Otherwise, sometimes it might work, or later work erratically, or even not at all...eliminate all this possible uncertainty.  Same goes with bypass caps & a solid supply.   While these may very well not be your issue, you can waste a lot of time--3 days later you find they were part of the problem & wonder why you didn't make it easy for yourself from the beginning.

 

the UART in not working properly.

Why be so vague?...what exactly do you see? Nothing?  Sometimes OK?  Garbage?  Third char is always "R"?, TX bad, RX good?

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It seems unwise to #define F_CPU in lots of different places? Either have one common header, define it in that then #include that in all the places the symbol must be visible or just do it as a -D ("Symbols").

 

But anyway, like avrcadies I'd like to here a better thought out description of what is actually wrong.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your 25LC256 has pagesize = 64.

I only tested with a 25LC1024 which has pagesize = 256.

I will have to dig out a 25LC640 with pagesize = 32.

 

My main point is that you just need a single SPI_transfer() function.

It is unwise (tm) to use separate SPI_read() and SPI_write().   And definitely unwise to randomly read SPDR.

 

uint8_t SPI_transfer(uint8_t c)
{
    SPDR = c;
    loop_until_bit_is_set(SPSR,SPIF);
    return SPDR;
}

void write_25xx_bum(uint32_t loc, uint8_t *buf, int n, int pagesize)
{
    uint32_t pagemask = pagesize - 1;
    while (n > 0) {
        SLAVE_SELECT;
        SPI_transfer(0x05);      //RDSR
        while (SPI_transfer(0x00) & 1) ;  //WIP
        SLAVE_DESELECT;
        SLAVE_SELECT;
        SPI_transfer(0x01);      //WRSR  overrule the /WP pin
        SPI_transfer(0x80);      //WPEN
        SLAVE_DESELECT;
        SLAVE_SELECT;
        SPI_transfer(0x06);      //WREN
        SLAVE_DESELECT;
        SLAVE_SELECT;
        SPI_transfer(0x02);      //WRITE
        if (pagesize > 128) SPI_transfer(loc >> 16);
        SPI_transfer(loc >> 8);
        SPI_transfer(loc >> 0);
        while (n) {
            SPI_transfer(*buf++);
            n--;
            if ((++loc & (pagemask)) == 0)  // page boundary
            break;
        }
        SLAVE_DESELECT;
        _delay_ms(10);                       // STOP starts actual page-write.
    }
}

void read_spi_mem(uint32_t loc, uint8_t *buf, int16_t n, int pagesize)
{
    SLAVE_SELECT;
    SPI_transfer(0x05);      //RDSR
    while (SPI_transfer(0x00) & 1) ;  //WIP
    SLAVE_DESELECT;
    SLAVE_SELECT;
    SPI_transfer(0x03);
    if (pagesize > 128) SPI_transfer(loc >> 16);
    SPI_transfer(loc >> 8);
    SPI_transfer(loc >> 0);
    //    SPI_transfer_block(buf, n);
    while (n--) *buf++ = SPI_transfer(0);
    SLAVE_DESELECT;
}

int main (void)
{
    uint8_t i, address;
    initSPI();
    init_UART();

    uint8_t buf[20];
    write_25xx_bum(0x000000, "David Prentice", 15, 256);   //25LC1024
    read_spi_mem(0x000000, buf, 16, 256);
    ...

David.

Last Edited: Tue. Aug 13, 2019 - 01:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I placed a bypass capacitor between VCC and GND. Tested but same result. Now UART is not working at all, when I call Spi_init() function. As you said I am trying every possible mistakes one by one. Only thing that left to test is to add a crystal oscillator. I so far didn't do it only because of the reason it's consume 2 more GPIO pins of ATMEGA168. Also tinkering with Fuse bit of AVR is really a mess and confusing.

 

Can you tell me how to find  the fuse bit value for setting a 20Mhz crystal( Which I have in my lab) for ATmega168. So far with several experiments I done the UART ALONE work without any problem even without adding an external crystal oscillator. Any way I will test it with by adding crystal oscillator too. Thanks for your replies.

avr freaky

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

RAM_EV wrote:
Can you tell me how to find  the fuse bit value for setting a 20Mhz crystal( Which I have in my lab) for ATmega168.

AVRFreaks use this site: http://www.engbedded.com/fusecalc/

for fuse settings on classic AVRs.

So for a 20MHz xtal:  Low:0xFF  High:0xDC  Ext:0xF9  = 8MHz and up xtal, + BOD 4.3v

 

Good luck

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
stack gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I found the 25LC640 after a lot of digging.

    write_25xx_bum(0x000000, "David Prentice", 15, 32);   //25LC640
    read_spi_mem(0x000000, buf, 16, 32);

Your "Data inside EEPROM in First 10 memory location:\r\n" loop reads the 25LC640 ok.

 

Your "software" works but it is very UNWISE to omit 100nF capacitors.   And unwise to read SPDR at random.    It is unwise to have random F_CPU defines.

 

David.