Pages: [1]   Go Down
Author Topic: Change shiftOut() Clock Speed  (Read 1055 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 58
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've put the following code in my sketch to speed up the shiftOut() function. I'm using the typical MC74HC595 shift register but the maximum  clock frequency for my application is (conservatively) 4 MHz. If my code works, my clock frequency will be considerably faster (see thread below - I'm using Stimmer's code; it takes about 24 nS to write a pin high). I need a "delay" of say ... 250 nS between each clock write cycle. So ... can I modify an existing (e.g. micros()) or write my own function to have better 100 nS resolution? Or a better way to accomplish what I want?

Code:
inline void digitalWriteDirect(int pin, boolean val){
  if(val) g_APinDescription[pin].pPort -> PIO_SODR = g_APinDescription[pin].ulPin;
  else    g_APinDescription[pin].pPort -> PIO_CODR = g_APinDescription[pin].ulPin;
}

inline int digitalReadDirect(int pin){
  return !!(g_APinDescription[pin].pPort -> PIO_PDSR & g_APinDescription[pin].ulPin);
}

//High speed shift register function
void shiftOutFast( uint32_t ulDataPin, uint32_t ulClockPin, uint32_t ulBitOrder, uint32_t ulVal )
{
  uint8_t i ;
  for ( i=0 ; i < 8 ; i++ ){
    if ( ulBitOrder == LSBFIRST ){
      digitalWriteDirect( ulDataPin, !!(ulVal & (1 << i)) );
    }
    else{
      digitalWriteDirect( ulDataPin, !!(ulVal & (1 << (7 - i))) );
    }
    digitalWriteDirect( ulClockPin, HIGH );
    //need to delay 200 nS
    digitalWriteDirect( ulClockPin, LOW );
   //need to delay 200 nS
  }
}


http://arduino.cc/forum/index.php/topic,129868.15.html
« Last Edit: January 15, 2013, 12:32:20 pm by tms8c8 » Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 437
Posts: 23699
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I think the best you can do is use SPI.transfer( ) instead of shiftclk( ).
There are some clock divisors you can use, fastest is 1/2 processor clock speed, or 133nS.
http://arduino.cc/en/Reference/SPI

[Edit - right answer, wrong processor]
« Last Edit: January 15, 2013, 04:16:33 pm by CrossRoads » Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Offline Offline
God Member
*****
Karma: 32
Posts: 506
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here's a useful macro:
Code:
#define MNOP(x) asm volatile (" .rept " #x "\n\t nop \n\t .endr \n\t")
It outputs nop instructions - each nop wastes approx. 1 clock cycle which is about 12nS. So use MNOP(16); for about 200nS.

Beware that doing delays this way isn't very deterministic, you might find that you add a line somewhere completely different in the code and it changes the length of the delay!
Logged


Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 437
Posts: 23699
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

How is 1 clock cycle 12nS when  ...
Ah, never mind, didnt realize this was a Due question.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Offline Offline
Jr. Member
**
Karma: 0
Posts: 58
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here's a useful macro:
Code:
#define MNOP(x) asm volatile (" .rept " #x "\n\t nop \n\t .endr \n\t")
It outputs nop instructions - each nop wastes approx. 1 clock cycle which is about 12nS. So use MNOP(16); for about 200nS.

Beware that doing delays this way isn't very deterministic, you might find that you add a line somewhere completely different in the code and it changes the length of the delay!

Thanks Stimmer. Saved me twice today! The digitalWriteDirect() is super handy and the MNOP is exactly what I needed.
Logged

Pages: [1]   Go Up
Jump to: