Hackster will be offline on Monday, June 15 from 5pm to 7pm PDT to perform some scheduled maintenance.
blinkenlight
Published

Fast Counter

How fast can you toggle an IO pin?

Full instructions provided5,603
Fast Counter

Things used in this project

Story

Read more

Code

arduino_pins___avr_ports.c

C/C++
arduino_pins___avr_ports.c
//
//  www.blinkenlight.net
//
//  Copyright 2012 Udo Klein
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program. If not, see http://www.gnu.org/licenses/
 
 
const uint8_t bit_0 = 1<<0;
const uint8_t bit_1 = 1<<1;
const uint8_t bit_2 = 1<<2;
const uint8_t bit_3 = 1<<3;
const uint8_t bit_4 = 1<<4;
const uint8_t bit_5 = 1<<5;
const uint8_t bit_6 = 1<<6;
const uint8_t bit_7 = 1<<7;
 
#define COUNT_1                PIND = bit_0;
#define COUNT_3    COUNT_1;    PIND = bit_1; COUNT_1;
#define COUNT_7    COUNT_3;    PIND = bit_2; COUNT_3;
#define COUNT_15   COUNT_7;    PIND = bit_3; COUNT_7;
#define COUNT_31   COUNT_15;   PIND = bit_4; COUNT_15;
#define COUNT_63   COUNT_31;   PIND = bit_5; COUNT_31;
#define COUNT_127  COUNT_63;   PIND = bit_6; COUNT_63;
#define COUNT_255  COUNT_127;  PIND = bit_7; COUNT_127;
#define COUNT_511  COUNT_255;  PINB = bit_0; COUNT_255;
#define COUNT_1023 COUNT_511;  PINB = bit_1; COUNT_511;
#define COUNT_2047 COUNT_1023; PINB = bit_2; COUNT_1023;
#define COUNT_4095 COUNT_2047; PINB = bit_3; COUNT_2047;
 
void count_8191() { COUNT_4095; PINB = bit_4; COUNT_4095; }
 
#define COUNT_16383  count_8191(); PINB = bit_5; count_8191();
#define COUNT_32767  COUNT_16383;  PINC = bit_0; COUNT_16383;
#define COUNT_65535  COUNT_32767;  PINC = bit_1; COUNT_32767;
#define COUNT_131071 COUNT_65535;  PINC = bit_2; COUNT_65535;
#define COUNT_262143 COUNT_131071; PINC = bit_3; COUNT_131071;
#define COUNT_524287 COUNT_262143; PINC = bit_4; COUNT_262143;
#define COUNT_524288 COUNT_524287; PINC = bit_5;
 
#define TWICE(a) a a
 
void setup() {
    DDRD = 0b11111111; // set digital  0- 7 to output
    DDRB = 0b00111111; // set digital  8-13 to output
    DDRC = 0b00111111; // set digital 14-19 to output (coincidences with analog 0-5)
 
    // ensure we do not get interrupted during prescaler manipulation
    cli();
 
/*  
    // activate this block by removing the previous comment
    // set clock prescaler as desired to slow down the timer
    const uint8_t clock_prescaler_1   = 0;
    const uint8_t clock_prescaler_2   = 1;
    const uint8_t clock_prescaler_4   = 2;
    const uint8_t clock_prescaler_8   = 3;
    const uint8_t clock_prescaler_16  = 4;
    const uint8_t clock_prescaler_32  = 5;
    const uint8_t clock_prescaler_64  = 6;
    const uint8_t clock_prescaler_128 = 7;
    const uint8_t clock_prescaler_256 = 8;
 
    // prepare to set clock prescaler: write CLKPCE bit to one and all the other to zero
    CLKPR = 1<<CLKPCE;
    // set clock prescaler immediately after preparing to do so
    CLKPR = clock_prescaler_256;
/**/
    // do not enable interrupts again because we do not want
    // interrupts to slow us any down
}
 
void loop() {
    l0:
        TWICE(TWICE(TWICE(TWICE(TWICE(COUNT_524288)))));
    goto l0;
}

Credits

blinkenlight
1 project • 1 follower

Comments