Shift Register 74HC595 attiny13 not Behaving

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

Hello Fellow AVRfreaks,

My issue is as follows. Got some code to drive a shift reg with my attiny13, but when I compile the code, it seems like the compiler (microchip studio) is making changes to the bits.. Here is the code...

 

#include <avr/io.h>

//#define F_CPU 1000000

#include <util/delay.h>

/***************************************

Configure Connections

****************************************/

#define HC595_PORT   PORTB
#define HC595_DDR    DDRB

#define HC595_DS_POS PB0      //Data pin (DS) pin location

#define HC595_SH_CP_POS PB1      //Shift Clock (SH_CP) pin location 
#define HC595_ST_CP_POS PB2      //Store Clock (ST_CP) pin location
#define HC595_OE_POS	PB3		 //Output Enable
/***************************************
Configure Connections ***ENDS***
****************************************/

//Initialize HC595 System

void HC595Init()
{
   //Make the Data(DS), Shift clock (SH_CP), Store Clock (ST_CP) lines output
   HC595_DDR|=((1<<HC595_OE_POS)|(1<<HC595_SH_CP_POS)|(1<<HC595_ST_CP_POS)|(1<<HC595_DS_POS));
}


//Low level macros to change data (DS)lines and (OE) lines
#define HC595DataHigh() (HC595_PORT|=(1<<HC595_DS_POS))
#define HC595DataLow() (HC595_PORT&=(~(1<<HC595_DS_POS)))

#define HC95_OE_High() (HC595_PORT|=(1<<HC595_OE_POS))
#define HC95_OE_Low() (HC595_PORT&=(~(1<<HC595_OE_POS)))

//Sends a clock pulse on SH_CP line
void HC595Pulse()
{
   //Pulse the Shift Clock

   HC595_PORT|=(1<<HC595_SH_CP_POS);//HIGH
   _delay_loop_1(1);
   HC595_PORT&=(~(1<<HC595_SH_CP_POS));//LOW

}

//Sends a clock pulse on ST_CP line
void HC595Latch()
{
   //Pulse the Store Clock

   HC595_PORT|=(1<<HC595_ST_CP_POS);//HIGH
   _delay_loop_1(1);

   HC595_PORT&=(~(1<<HC595_ST_CP_POS));//LOW
   _delay_loop_1(1);
}

void HC595Write(uint8_t data)
{
   //Send each 8 bits serially

   //Order is MSB first
   for(uint8_t i=0;i<8;i++)
   {
      //Output the data on DS line according to the
      //Value of MSB
      if(data & 0b10000000)
      {
         //MSB is 1 so output high

         HC595DataHigh();
      }
      else
      {
         //MSB is 0 so output high
         HC595DataLow();
      }

      HC595Pulse();  //Pulse the Clock line
      data=data<<1;  //Now bring next bit at MSB position

   }

   //Now all 8 bits have been transferred to shift register
   //Move them to output latch at one
   HC595Latch();
}

/*

Simple Delay function approx 0.5 seconds

*/

void Wait()
{
   for(uint8_t j = 0; j < 5;j++)
   for(uint8_t i=0;i<=200;i++)
   {
      _delay_loop_1(0);
   }
}

int main()
{
   uint8_t led_pattern[8]={
                        0b10000000,
                        0b01000000,
                        0b00100000,
                        0b00010000,
                        0b00001000,
                        0b00000100,
                        0b00000010,
                        0b00000001,
   };
   uint8_t led_pattern2[8]={					
			0b00000010,
			0b00000100,
			0b00001000,
			0b00010000,
			0b00100000,
			0b01000000,
			0b10000000,
			0b00000000
  };
					 
   uint8_t led_pattern3[8]={
	   	   0b10000000,
	   	   0b11000000,
	   	   0b11100000,
	   	   0b11110000,
	   	   0b11111000,
	   	   0b11111100,
	   	   0b11111110,
	   	   0b11111111,
   };
   
   uint8_t led_pattern4[8]={		  
	   0b11111110,
	   0b11111100,
	   0b11111000,
	   0b11110000,
	   0b11100000,	//<<<<<<<<<<< HERE IS THE ISSUE <<<<<<<<<<<<<<
	   0b11000000,
	   0b10000000,
	   0b00000000

   };					 

   //Initialize HC595 system

   HC595Init();
   HC95_OE_Low();
   uint8_t i=0;	

   while(1)
   {
      for(i=0;i<8;i++)
      {
         HC595Write(led_pattern[i]);	//Write the data to HC595
         Wait();						//Wait 
      }
      
      for(i=0;i<8;i++)
      {
	HC595Write(led_pattern2[i]);		//Write the data to HC595
	Wait();							//Wait
     }
     
     for(i=0;i<8;i++)
     {
	HC595Write(led_pattern3[i]);	//Write the data to HC595
	Wait();						//Wait
     }

     for(i=0;i<8;i++)
     {
	HC595Write(led_pattern4[i]);		//Write the data to HC595
	Wait();							//Wait
     }  
  }

  return 0;
}

 

The issue is in led_pattern4. It clearly states what i want my bits to do, but when it gets to array location 4 it goes AWOL. Here is the watch window for that array:

 

if we compare the the bits in the array with the bits in the watch window, something does not add-up. WHAT AM I DOING WRONG? I have tested it with Proteus and physically with the attiny13 and they behave in this way. WHY?

 

uint8_t led_pattern4[8]={

    0b11111110,    //     = fe       OK

    0b11111100,    //     = fc       OK

    0b11111000,    //     = f8       OK

    0b11110000,    //     = f0       OK

    0b11100000,    //     = 80      NOT OK       <<<<<<<<<<< HERE IS THE ISSUE <<<<<<<<<<<<<<     

    0b11000000,    //     = 40      NOT OK

    0b10000000,    //     = 20      NOT OK

    0b00000000     //     = 10      NOT OK

};

 

Any assistance in this issue will very much be appreciated.

 

 

 

This topic has a solution.
Last Edited: Sun. Apr 10, 2022 - 09:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Welcome to AVRFreaks!

 

Do exchange printing led_pattern//ledpattern4 to see if led_pattern4 is printed.

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


As you are not using your data in flash you are running out of memory (only 64 bytes), I rebuilt the code for a larger chip (tiny2313) and it's all well.

 

So look at the progmem attributes or the newfangled __flash or whatever it is called, as it is now the data is being copied into RAM at startup and you don't have enough.

 

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Why are you oring?

HC595_DDR|=

init should really use , so you know exactly all the bits are at that point.  

 

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

As I see it. This should work. The led_pattern[], led_pattern2[] etc. are allocated on the stack and should only take 32 bytes. The other functions called don't really use much stack. There are no global variables. There should be plenty of SRAM.

 

OP says led_pattern4[4] gets corrupted. His screenshot shows a valid memory location.

I don't understand this one.

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As you can see the last 4 bytes of led_pattern4 are a repeat of the beginning of the 1st pattern led_pattern in the ram, so something is wrapping around. Isn't there some limits to each type of data from the compiler?? Dunno need Mr Lawson here.....

 

No problems with the Tint2313 with a huge 128 bytes of ram.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Thank you all for your responses. JS Thank you specially for your response. I Used:

 

const uint8_t led_pattern4[8] PROGMEM =

{
       0b11111110,
       0b11111100,
       0b11111000,
       0b11110000,
       0b11100000,   
       0b11000000,
       0b10000000,
       0b00000000

};

 

int read_var (int i)
{
    return (int) pgm_read_word (& led_pattern4[i]);
}

 

And it works as expected. Thank You All again.