I have read through the documentation at: Macros (The C Preprocessor) but am new to using Macros and so may have missed it in the documentation, but nothing in there shows how it could be done.
Then maybe an example is best. This is from w5100.h. I just modified it, so I knew where to find an example. It is a bit difficult to follow at first, but the defines replace __SOCKET_REGISTER8 with these functions.
Thanks Tim,
The edit certainly helped but I am still a little confused as to what is being achieved.
How would you actually call the functions from the code body.
I guess it would help if I knew what socket register are.
I may have bitten off more than I can chew.
Note it replaced the "write##name" and "read##name" with the first parameter, and the address in writeSn() with the second parameter (0000 on the first set).
I think it is starting to get clearer, I can see a light at the end of the tunnel, I just hope it is not an on coming train.
Basically what I need then is the Concatenation function ## and create something like:
#define TMR_CLR(TIMER) /
TCCR TIMER ## A = 0; /
TCCR TIMER ## B = 0; /
TCCR TIMER ## C = 0;
This compiles OK, but I have not weird up the board to test the sketch yet:
#include <avr/io.h>
#include <avr/interrupt.h>
// PWM - PWC - Period analiser / counter
//
// Measure: Mark and Space 16bits each with 0.5uS reselution on 16MHz clock
#define ICP4 49
#define TMR_SETUP(TIMER) \
TCCR##TIMER##A = 0; \
TCCR##TIMER##B = 0; \
TCCR##TIMER##C = 0; \
TCCR##TIMER##B |= (1<<ICNC##TIMER); \
bitSet(TIMSK##TIMER, ICIE##TIMER); \
TCCR##TIMER##B |= (0<<CS##TIMER##0); \
TCCR##TIMER##B |= (1<<CS##TIMER##1); \
TCCR##TIMER##B |= (0<<CS##TIMER##2); \
pinMode(ICP##TIMER, INPUT);
unsigned int Period = 0; // Rising Edge to Rising Edge value
unsigned int StartEdge = 0; // First Rising Edge Timer value
unsigned int DCEdge = 0; // Falling Edge Timer value
unsigned int DutyCycle = 0; // Rising Edge to Falling Edge value
ISR(TIMER4_CAPT_vect)
{
TCCR4B ^= (1<<ICES4); // togge ICES (Input Counter Edge Select)
if(bitRead(TCCR4B, ICES4))
{
StartEdge = ICR4;
Period = StartEdge - DCEdge + DutyCycle;
}
else
{
DCEdge = ICR4;
DutyCycle = DCEdge - StartEdge;
}
bitSet(TIFR4, ICF4); //clear flag
}
void setup()
{
Serial.begin(115200);
TMR_SETUP(4)
}
void loop()
{
delay(1000);
analogWrite(4, 256 * (analogRead(0) / 1023.0));
analogWrite(5, 256 * (analogRead(1) / 1023.0));
Serial.print("F1");
Serial.println(2000000.0 / Period);
Serial.print("DC");
Serial.println(100 - (DutyCycle * 100.0 / Period));
Serial.print("TM");
Serial.println((Period - DutyCycle) / 2);
Serial.print("TS");
Serial.println(DutyCycle / 2);
Serial.print("TP");
Serial.println((Period) / 2);
}
Thanks a lot Tim, I have learnt a lot today and feel more confidant working with Macros now.
The above looks like a Macro is redundant but is just a substitution into code that I already had working, to act as a test.
Ultimately I want to have all the timer functions extracted to a library so that the user can decide which timers to use depending on the target AVR chip and board, so ultimately it is not Arduino specific.
in answer to your question they are declared in avr/io.h
Glad I could help a little. Here is the reason you cannot set that variable.
TCCR4A is a define, not a variable. It won't let you set that value. Here is the define:
To be honest I have no idea where to find avr/io.h I just blindly used it without ever actually reading it
I normally work in PIC Assembler and am used to just including the register defines, maybe I just got lucky in this case.
A client just called so I have to drop this for now, but I will wire up my breadboard this evening, test the code, and report back if it works.
Thanks again,
Cheers
Chris