# Learning C

#### augustinetez

##### Active Member
I really need to learn to read properly, rjenkinsgb's last modification in post #38 is close enough to how it's done in the asm file - the ref+osc value is the DDS_FACTOR from his post

#### Pommie

##### Well-Known Member
Hi all,

Sorry for not getting back to you earlier, I was away for the (long) weekend helping my daughter.

Code all looks good except for a comment in the rotary encoder routine.
ANSELH &= 0xfc; /* RB2 and RB3 as digital I/O */
This actually sets RB0 and RB1 to digital which is correct but the comment is misleading.

Actually, as that is ANSELH (high) (misread that) then it depends on what chip is being used and is not compatible with the 1840.

Keep this in mind when it comes to implementing the encoder.

Mike.

#### augustinetez

##### Active Member
Thanks Mike.

Like you domestic stuff has left little time for this at the moment as well.

I was aware of the comments you make and the need to make changes to accommodate the chip being used.

#### augustinetez

##### Active Member
Somebody who should have known better has managed to pass on the dreaded lurgy, so if this thread falls off the edge and gets closed, I will ask Mods to reopen it when I have a more functional brain.

#### Pommie

##### Well-Known Member
Hope you feel better soon.

Mike.

#### augustinetez

##### Active Member
Thanks Mike.

While I am partially lucid, in the encoder routine:
Code:
/*--- Encoder function ---*/

void encoder_click(void)
{
static unsigned char previous = 0;
unsigned char temp;

temp = 5;

while(temp--){ /* debounce */
;
}

temp = PORTB;     /* Read port */
temp >>= 2;       /* Shift input to bit positions 1, 0 */
temp &= 0x03;     /* Mask out bits */
previous <<= 2;   /* shift the previous data left two places */
previous |= temp; /* OR in the two new bits */

encoder_count += table[(previous & 0x0f)];  /* Index into table */
}
On the basis that nearly nothing happens in my program unless the encoder moves, will the second half of the above (after while(temp--)) begin with - while(encoder_count==0) or is a do-while loop better?

Or am I totally missing something here.

#### Pommie

##### Well-Known Member
Your only while in that code is the delay. encoder_count will start at whatever is in it. Which is why you should declare it as , (assuming 16 bit integer)
int encoder_count=0;
So that it starts at zero - or any other value you choose.
What limits are on the encoder_count variable?
Note, int is 16 bit on a pic micro but can be any size on other machines - 32 bit on a P.C. or maybe even 64 now. Which is why I prefer to use the standard integer definitions, So, char becomes int8_t and unsigned int becomes uint16_t so there is no confusion. To use these alternative you #include <stdint> at the top of your code.

Mike.

#### augustinetez

##### Active Member
The encoder_count variable holds 0. +1 or -1 - uses the same table arrangement you showed me in the other thread when we did the asm encoder routine.

#### Pommie

##### Well-Known Member
In that case just do
encoder_count = table[(previous & 0x0f)];
Note the missing +.
Your mainloop will need to check encoder_count and use it if it's not zero and then set it to zero.
Also, define it as a signed char.
char encoder_count;
or
int8_t encoder_temp;

Mike.

#### augustinetez

##### Active Member
Feeling almost human again so trying to progress further with this.
There's still a lot of the minutiae of C I need to get my head around before doing any major writing of code.

So on that basis is this - PORTA=0 - in C the equivalent of - clrf PORTA - in asm in so much as it will clear any outputs to zero and just ignore any bit on the port that is an input?

#### augustinetez

##### Active Member
And having just written that, I realise it should have been - LATA=0

#### augustinetez

##### Active Member
Also, referring back a couple of posts could someone please explain the difference between ( '+=' and just the plain '=') and what it is actually doing:-

encoder_count += table[(previous & 0x0f)]

encoder_count = table[(previous & 0x0f)]

#### Pommie

##### Well-Known Member
Yes, LATA=0; will do the same as clrf LATA. Except, no bank switching instructions.

The instruction encoder_count+= table[(previous & 0x0f)] ;
is the same as encoder_count = encoder_count + table[(previous & 0x0f)] ;
It's just a shorthand way of writing it.
There are also -=, *=, /=, &=, |=, %= and any others I've forgotten.

Mike.
Edit, good to hear you're feeling better.

Last edited:

#### augustinetez

##### Active Member
Thanks Mike.

When I looked up '+=' in one of the C reference books, all it said was 'operator precedence' without any sort of explanation as to what that precedence was.

I didn't see an alternative explanation such as you explained, but I think I should check again to see if it shows up elsewhere.

#### Pommie

##### Well-Known Member
I don't see how operator precedence makes any difference. It's just an operator and precedence is another subject.

If you notice in the above code, there is
Code:
previous |= temp; /* OR in the two new bits */
Which is the OR equals.

Mike.

#### crutschow

##### Well-Known Member
C appears to have the most arcane syntax of any high level computer language.
Can some explain to me its popularity for hobbyists.

#### Pommie

##### Well-Known Member
C appears to have the most arcane syntax of any high level computer language.
That could be because it was written 50 years ago. However, I find it's syntax to be very simple.
Can some explain to me its popularity for hobbyists.
Doesn't that answer itself? C is closer to the hardware than many "higher" level languages and so is ideal to learn the hardware - especially of microcontrollers.

Many of the "new" languages are Object Orientated which adds a huge amount of extra complexity and code.

Can I ask why you don't use a more modern simulator rather than an arcane soldering iron?

Mike.

#### crutschow

##### Well-Known Member
However, I find it's syntax to be very simple.
Then your mind obviously works different than mine.
I worked on a modification a a C program at work a number of years ago and had to learn a little C.
I'm not sure of your definition of simple, but I found it difficult to remember the syntax.
Rather like trying to learn a foreign language as compared to a more easily understandable computer language such as Basic or Fortran (I know, I'm seriously dating myself).
Many of the "new" languages are Object Orientated which adds a huge amount of extra complexity and code.
I'm not referring to new languages, just those that use a less arcane syntax.
Can I ask why you don't use a more modern simulator rather than an arcane soldering iron?
I use LTspice.
Is that modern enough?
Haven't had my soldering on in several months.
And I don't see how a soldering iron is "arcane" ( understood by few; mysterious or secret).