Pages: 1 2 [3]   Go Down
Author Topic: Port manipulation PINx commands with Arduino Due ?  (Read 15327 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi guys,
I would like to ask if is possible to generate square waves with digitalWriteDirect?
this code
Code:
void loop() {
  digitalWriteDirect(9, HIGH);          
  digitalWriteDirect(9, LOW);        
}
produces these waves (sry for bad quality)
http://imageshack.us/f/838/19052013i.jpg/
thanks
« Last Edit: May 19, 2013, 02:29:34 pm by blazek » Logged

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

The squarewave is uneven because of function call overhead. You can lessen this by making your own loop:

Code:
void loop() {
  for(;;){
    digitalWriteDirect(9, HIGH);           
    digitalWriteDirect(9, LOW);         
  }
}
Logged


More Cowbell
Offline Offline
Edison Member
*
Karma: 11
Posts: 1025
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
void loop() {
  for(;;){
    digitalWriteDirect(9, HIGH);           
    digitalWriteDirect(9, LOW);   
    digitalWriteDirect(9, HIGH);           
    digitalWriteDirect(9, LOW);   
    digitalWriteDirect(9, HIGH);           
    digitalWriteDirect(9, LOW);   
... repeat many times      
  }
}

Even with the tighter loop the square wave will be uneven because of the looping overhead of 3 or 4 machine cycles.  You can cheat by repeating that block of code a bunch of times (feel free to hold ctrl-v down and paste it in a few hundred times).  The more there is before the eventual hiccup, the better chance your scope will have at stabilizing the wave.
Logged

Vexatious Sampler

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks a lot =) now I have nice sinus wave about 20MHz =)
and one more question:
I want to make frequency generator with this utility so is there any documentation about counting ticks? because with msDelay I can do freq. about several thousand KHz (not enough for me =/)..
thanks
Logged

Mainz
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I want to make frequency generator with this utility so is there any documentation about counting ticks?

=> Timer Counter (TC)!
You can count the clocks of MCK/2 (=42MHz)

Quote
ATMELSAM(datasheet) 37.1 Description
The Timer Counter (TC) includes three identical 32-bit Timer Counter channels.

Start the counter, read the counter (Counter Value register)  or generate an interrupt (Interrupt Enable Register) and react
to your choosen number of counts.

Sound easy, but its a it lot of register manipulation. Maybe  you can find a lib for he TC?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Could you be a bit more concrete please? I with code above I have got 32Mhz max... At the moment I think there is no working counter for Due, or am I wrong?
thanks
Logged

Mainz
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry, haven't been here for some time.
I dunno understand what exactly you want, so here just a short example of running Timer counter TC0
at 42 MHz. Maybe this is something that can fit your needs.
Sketch starts and reads (CV = counter value) counter.

Code:
void setup(){  Serial.begin(9600); }

void loop()
{
unsigned long v[10];
int i;
  PMC->PMC_PCER0 = 1<<27;  // PMC: Enable Timer TC0
  TC0->TC_CHANNEL[0].TC_CMR = 0;  // Control mode reg.: set Clock to MCK/2 = 42 MHz 
  TC0->TC_CHANNEL[0].TC_CCR = 4 + 1;  // activate Timer:  // Start + Enable
  Serial.println("---------------------------------------------------------");
  Serial.println("-------       delay is not exackt, TC0 is!      ---------");
  Serial.println("---------------------------------------------------------");
  Serial.println("Delayed Readout (24 us -> ~1000 Ticks)");
  TC0->TC_BCR = 1;  // restart(sync)
  for(i=0; i<10; i++) { v[i]= TC0->TC_CHANNEL[0].TC_CV;  delayMicroseconds(24); }
  for(i=0; i<10; i++) { Serial.print(i); Serial.print(": "); Serial.println(v[i]); }
  delay(5000); 
  Serial.println("---------------------------------------------------------");
  Serial.println("Endless Readout (1s -> +42 000 000)");
  TC0->TC_BCR = 1;  // restart(sync)
  while(1==1)  { Serial.println(TC0->TC_CHANNEL[0].TC_CV); delay(1000); }
}
Logged

Innsbruck
Offline Offline
Newbie
*
Karma: 0
Posts: 2
"Demand of yourself, even when no one else demands of you"
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The squarewave is uneven because of function call overhead. You can lessen this by making your own loop:

Code:
void loop() {
  for(;;){
    digitalWriteDirect(9, HIGH);           
    digitalWriteDirect(9, LOW);         
  }
}


To make HIGH and LOW phases simmetric, just add a cuple of NOP (No Operation) after the digitalWriteDirect(9, HIGH) :

Code:
#define NOP __asm__ __volatile__ ("nop\n\t");

...

void loop() {
  for(;;){
    digitalWriteDirect(9, HIGH);
    NOP
    ...
    NOP   
    digitalWriteDirect(9, LOW);         
  }
}


Each NOP extends the HIGH phase by  1 clock cycle, i.e. 12 ns on DUE (1/84 MHz).
Logged

Pages: 1 2 [3]   Go Up
Jump to: