According to this reference, there are 32 keywords.The language itself has few instruction, maybe as few as one dozen
Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
According to this reference, there are 32 keywords.The language itself has few instruction, maybe as few as one dozen
Wait until you start C++.... You "think" you have seen operators...And umpteen operators not included in that list.
That list of 32 includes the variable types (E.G. int, char etc.) and keywords that shouldn't be used (E.G. goto). When you take out the variable types then it's less than 2 dozen - not as few as I thought but not a lot to learn. It can be obscure but most things can be done in a simpler way and should be so as to be understandable.
The umpteen operators I'll concede.
Mike.
On Sun, 12 Jan 2003, [redacted by request 12/3/2020] wrote:
>
> However, I have always been taught, and have always believed that
> "goto"s are inherently evil. They are the creators of spaghetti code
No, you've been brainwashed by CS people who thought that Niklaus Wirth
actually knew what he was talking about. He didn't. He doesn't have a
frigging clue.
> (you start reading through the code to understand it (months or years
> after its written), and suddenly you jump to somewhere totally
> unrelated, and then jump somewhere else backwards, and it all gets ugly
> quickly). This makes later debugging of code total hell.
Any if-statement is a goto. As are all structured loops.
Ans sometimes structure is good. When it's good, you should use it.
And sometimes structure is _bad_, and gets into the way, and using a
"goto" is just much clearer.
For example, it is quite common to have conditionals THAT DO NOT NEST.
In which case you have two possibilities
- use goto, and be happy, since it doesn't enforce nesting
This makes the code _more_ readable, since the code just does what
the algorithm says it should do.
- duplicate the code, and rewrite it in a nesting form so that you can
use the structured jumps.
This often makes the code much LESS readable, harder to maintain,
and bigger.
The Pascal language is a prime example of the latter problem. Because it
doesn't have a "break" statement, loops in (traditional) Pascal end up
often looking like total sh!t, because you have to add totally arbitrary
logic to say "I'm done now".
Linus
OK, dumb question time again - char encoder_count; - why char and not 'int' or something else? (bearing in mind encoder_count will hold 0, +1 or -1.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.
#include <xc.h>
#include <stdint.h>
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection->INTOSC oscillator: I/O function on CLKIN pin
#pragma config WDTE = SWDTEN // Watchdog Timer Enable->WDT controlled by the SWDTEN bit in the WDTCON register
#pragma config PWRTE = OFF // Power-up Timer Enable->PWRT disabled
#pragma config MCLRE = ON // MCLR Pin Function Select->MCLR/VPP pin function is MCLR
#pragma config CP = OFF // Flash Program Memory Code Protection->Program memory code protection is disabled
#pragma config CPD = OFF // Data Memory Code Protection->Data memory code protection is disabled
#pragma config BOREN = ON // Brown-out Reset Enable->Brown-out Reset enabled
#pragma config CLKOUTEN = OFF // Clock Out Enable->CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
#pragma config IESO = ON // Internal/External Switchover->Internal/External Switchover mode is enabled
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable->Fail-Safe Clock Monitor is enabled
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection->Write protection off
#pragma config PLLEN = ON // PLL Enable->4x PLL enabled
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable->Stack Overflow or Underflow will cause a Reset
#pragma config BORV = LO // Brown-out Reset Voltage Selection->Brown-out Reset Voltage (Vbor), low trip point selected.
#pragma config LVP = OFF // Low-Voltage Programming Enable->High-voltage on MCLR/VPP must be used for programming
#define AD9850 // Using the AD9850
//#define AD9851 // Using the AD9851
#ifdef AD9850
// For 125 MHz Oscillator =======
#define ref_osc 0x225C17D0L
#endif
#ifdef AD9851
// For 180 MHz (30 MHz clock and 6x multiplier)
#define ref_osc 0x17DC65DEL
#endif
//Limit contains the upper limit frequency as a 32 bit integer.
#define limit 0x0053EC60L
//Low_limit contains the lower frequency limit as a 32 bit integer
#define limit_low 0x004C4B40L
// Default contains the default startup frequency as a 32 bit integer.
// This will be overwritten by the frequency save routine in normal use.
#define default 0x004C4B40L
// Frequency at which Calibration will take place
#define cal_freq 0x00501BD0L
#define DDSdata AN0
#define DDSclock AN2
#define DDSload AN1
#define _XTAL_FREQ (32000000)
const signed char table[] = {0,-1,+1,0,+1,0,0,-1,-1,0,0,+1,0,+1,-1,0};
void sendDDSword(int);
void writeEEPROM(unsigned char,unsigned char);
volatile signed int encoder_count;
void main(void){
PORTA=0;
TRISA=0b00111100;
ANSELA=0;
// SCS FOSC; SPLLEN disabled; IRCF 8MHz_HF;
OSCCON = 0x70; //set osc to 32MHz
BORCON = 0x00;
while(PLLR == 0);
// WDTPS 1:65536; SWDTEN OFF;
WDTCON = 0x16;
WPUA = 0x00;
OPTION_REGbits.nWPUEN = 1;
// writeEEPROM(0,0x23);
while(1){
encoder_count = 0;
encoder_count = encoder_click(encoder_count);
//attach led to LATA0
if (encoder_count == 1){
LATAbits.LATA0 = 1;
__delay_ms(100);
LATAbits.LATA0 = 0;
encoder_count = 0;
return;
}
//attach led to LATA1
if (encoder_count == -1){
LATAbits.LATA1 = 1;
__delay_ms(100);
LATAbits.LATA1 = 0;
encoder_count = 0;
return;
}
}
}
int encoder_click(int encoder_count)
{
static unsigned char previous = 0;
unsigned char temp;
temp = 5;
while(temp--){ /* debounce */
;
}
temp = PORTA; /* Read port - encoder on bits 3 & 4*/
temp >>= 3; /* 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 */
return encoder_count;
}
/*
void writeEEPROM(unsigned char address,unsigned char data){
EEADRL = address;
EEDATL=data;
CFGS=0;
EEPGD=0;
WREN=1;
EECON2=0x55;
EECON2=0xAA;
WR=1;
WREN=0;
while(WR==1);
}*/
newmain.c:74:24: warning: implicit declaration of function 'encoder_click' is invalid in C99 [-Wimplicit-function-declaration]
encoder_count = encoder_click(encoder_count);
^
1 warning generated.
"C:\Program Files\Microchip\xc8\v2.32\bin\xc8-cc.exe" -mcpu=12F1840 -Wl,-Map=dist/default/production/Simple_VFO.X.production.map -DXPRJ_default=default -Wl,--defsym=__MPLAB_BUILD=1 -mdfp="C:/Program Files/Microchip/MPLABX/v5.45/packs/Microchip/PIC12-16F1xxx_DFP/1.2.63/xc8" -fno-short-double -fno-short-float -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -mwarn=-3 -Wa,-a -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-osccal -mno-resetbits -mno-save-resetbits -mno-download -mno-stackcall -std=c99 -gdwarf-3 -mstack=compiled:auto:auto -Wl,--memorysummary,dist/default/production/memoryfile.xml -o dist/default/production/Simple_VFO.X.production.elf build/default/production/newmain.p1
newmain.c:74:: warning: (1518) direct function call made with an incomplete prototype (encoder_click)
#include <xc.h>
#include <stdint.h>
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection->INTOSC oscillator: I/O function on CLKIN pin
#pragma config WDTE = SWDTEN // Watchdog Timer Enable->WDT controlled by the SWDTEN bit in the WDTCON register
#pragma config PWRTE = OFF // Power-up Timer Enable->PWRT disabled
#pragma config MCLRE = ON // MCLR Pin Function Select->MCLR/VPP pin function is MCLR
#pragma config CP = OFF // Flash Program Memory Code Protection->Program memory code protection is disabled
#pragma config CPD = OFF // Data Memory Code Protection->Data memory code protection is disabled
#pragma config BOREN = ON // Brown-out Reset Enable->Brown-out Reset enabled
#pragma config CLKOUTEN = OFF // Clock Out Enable->CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
#pragma config IESO = ON // Internal/External Switchover->Internal/External Switchover mode is enabled
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable->Fail-Safe Clock Monitor is enabled
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection->Write protection off
#pragma config PLLEN = ON // PLL Enable->4x PLL enabled
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable->Stack Overflow or Underflow will cause a Reset
#pragma config BORV = LO // Brown-out Reset Voltage Selection->Brown-out Reset Voltage (Vbor), low trip point selected.
#pragma config LVP = OFF // Low-Voltage Programming Enable->High-voltage on MCLR/VPP must be used for programming
#define DDSdata LATA0 //AN0
#define DDSload LATA1 //AN1
#define DDSclock LATA2 //AN2
#define _XTAL_FREQ (32000000)
char encoder_click (char);
//volatile signed char encoder_count;
char encoder_count = 0;
unsigned char temp;
static unsigned char previous = 0;
char dir = 0;
//const signed char table[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
const char table[] = {0,0xff,1,0,1,0,0,0xff,0xff,0,0,1,0,1,0xff,0};
void main(void){
PORTA=0;
TRISA=0b00111000;
ANSELA=0;
// SCS FOSC; SPLLEN disabled; IRCF 8MHz_HF;
OSCCON = 0x70; // set osc to 32MHz
BORCON = 0x00;
while(PLLR == 0);
// WDTPS 1:65536; SWDTEN OFF;
WDTCON = 0x16;
WPUA = 0x00;
OPTION_REGbits.nWPUEN = 1;
// previous = 0;
// encoder_count = 0;
while(1){
dir = encoder_click(encoder_count);
// attach led to LATA0
if (dir == 1){
//LATAbits.LATA0 = 1; // DDSdata
DDSdata = 1; // LATA0
__delay_ms(100);
//LATAbits.LATA0 = 0;
DDSdata = 0; // LATA0
//encoder_count = 0;
return;
}
//attach led to LATA1
if (dir == 0){
//LATAbits.LATA1 = 1; // DDSload
DDSload = 1; // LATA1
__delay_ms(100);
//LATAbits.LATA1 = 0;
DDSload = 0; // LATA1
//encoder_count = 0;
return;
}
//attach led to LATA2
if (dir == 0xff){
//LATAbits.LATA2 = 1; // DDSclock
DDSclock = 1; // LATA2
__delay_ms(100);
//LATAbits.LATA2 = 0;
DDSclock = 0; // LATA2
//encoder_count = 0;
return;
}
}
}
char encoder_click(char encoder_count)
{
temp = PORTA; /* Read port - encoder on bits 3 & 4*/
temp >>= 3; /* 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 */
encoder_count = table[previous]; /* Index into table */
return encoder_count;
}
#include <xc.h>
#include <stdint.h>
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection->INTOSC oscillator: I/O function on CLKIN pin
#pragma config WDTE = SWDTEN // Watchdog Timer Enable->WDT controlled by the SWDTEN bit in the WDTCON register
#pragma config PWRTE = ON // Power-up Timer Enable->PWRT enabled
#pragma config MCLRE = OFF // MCLR Pin Function Select->MCLR/VPP pin function is INPUT
#pragma config CP = OFF // Flash Program Memory Code Protection->Program memory code protection is disabled
#pragma config CPD = OFF // Data Memory Code Protection->Data memory code protection is disabled
#pragma config BOREN = OFF // Brown-out Reset Enable->Brown-out Reset disabled
#pragma config CLKOUTEN = OFF // Clock Out Enable->CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
#pragma config IESO = ON // Internal/External Switchover->Internal/External Switchover mode is enabled
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable->Fail-Safe Clock Monitor is enabled
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection->Write protection off
#pragma config PLLEN = ON // PLL Enable->4x PLL enabled
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable->Stack Overflow or Underflow will cause a Reset
#pragma config BORV = LO // Brown-out Reset Voltage Selection->Brown-out Reset Voltage (Vbor), low trip point selected.
#pragma config LVP = OFF // Low-Voltage Programming Enable->High-voltage on MCLR/VPP must be used for programming
#define DDSdata LATA0 //AN0
#define DDSload LATA1 //AN1
#define DDSclock LATA2 //AN2
#define _XTAL_FREQ (32000000)
char encoder_click (char);
//volatile signed char encoder_count;
char encoder_count = 0;
unsigned char temp;
static unsigned char previous = 0;
char dir = 0;
//const signed char table[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
const char table[] = {0,0xff,1,0,1,0,0,0xff,0xff,0,0,1,0,1,0xff,0};
void main(void){
PORTA=0;
TRISA=0b00111000;
ANSELA=0;
// SCS FOSC; SPLLEN disabled; IRCF 8MHz_HF;
OSCCON = 0x70; // set osc to 32MHz
BORCON = 0x00;
while(PLLR == 0);
// WDTPS 1:65536; SWDTEN OFF;
WDTCON = 0x16;
WPUA = 0x00;
OPTION_REGbits.nWPUEN = 1;
while(1){
dir = encoder_click(encoder_count);
// attach led to RA0
if (dir == 1){
DDSdata = 1; // LATA0
__delay_ms(100);
DDSdata = 0; // LATA0
return;
}
//attach led to RA2
if (dir == 0xff){
DDSclock = 1; // LATA2
__delay_ms(100);
DDSclock = 0; // LATA2
return;
}
}
}
char encoder_click(char encoder_count)
{
do {
__delay_ms(2);
temp = PORTA; /* Read port - encoder on bits 3 & 4*/
temp >>= 3; /* 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 */
}while (encoder_count == 0);
return(encoder_count);
}
char encoder_count = 0; // global (outside any function)
<snip>
dir = encoder_click(encoder_count); // always passes the function a 0
<snip>
char encoder_click(char encoder_count) // this 'encoder_count' isn't the same as the global one
{
uint8_t temp;
static uint8_t previous = 0;
<snip>
return(encoder_count); // this doesn't update your global 'encoder_count'
}
Thankyou.- move all the '#include' statements to after the '#pragma config' statements to avoid any possible conflicts.
I did ask that question earlier and is how most of the texts I've been reading tell you to use them.- only use 'char' for characters. use 'int8_t' or 'uint8_t' for 8-bit values.
Then what is being passed where to make the LED's light according to the direction the encoder is being turned?dir = encoder_click(encoder_count); // always passes the function a 0
I did try that and ended up with a load of warnings and build failure.Also, I moved the declarations for 'temp' and 'previous' so they're only visible to the routine that uses them.
You're not interested in passing anything to encoder_click(). All you're interested in is the return value of the function.Then what is being passed where to make the LED's light according to the direction the encoder is being turned?
uint8_t encoder_click(void);
encoder_count = encoder_click();
dir = encoder_click(encoder_count);