Also, the original source code. You should share this. As the logic in your code provided does not make sense to me. 'if (enc_new > 1) <> (enc_last & 1) then' this makes no sense. It will compile but the outcome is not what you need.
This surely should be a bitwise inspections. The code may not work as expected.
Post the C source.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
High-Level Cheat Sheet for PIC16F628A (MikroC → GCBASIC))
1. Chip & Clock
MikroC C
GCBASIC
#pragma config FOSC = HS
#chip 16F628A, 20
(any config)
#option explicit(recommended)
Rule: Always start with #chip <model>, <MHz>
2. Functions
C
GCBASIC
void main()
Use a label Main:
void interrupt()
Sub Interrupt
Rule: Use Sub and Interrupt
End with End Sub
3. Infinite Loop
C
GCBASIC
while(1) { }
Do → Loop
Rule: No condition needed
4. Variables
C Type
GCBASIC
unsigned char
Dim x As Byte
unsigned int
Dim x As Word
unsigned long
Dim x As Long
Rule: Match bit width: 8 / 16 / 32
5. Bit Access
C
GCBASIC
PORTA.F0
PORTA.0
var.F3 = 1
var.3 = 1
Rule: Use dot-number (.0 to .7)
6. Port I/O
C
GCBASIC
TRISA = 0b00000011;
TRISA = 0b00000011
(implied by TRIS)
Dir PORTA.0 In
Rule: Always add Dir statements in GCBASIC
7. Delay
C
GCBASIC
Delay_ms(200);
Wait 200 ms
Rule: Use ms, us, s — auto-scaled
8. Logic & Conditions
C
GCBASIC
if (x != y)
If x <> y Then
else
Else
||
Or
&&
And
Rule: <> = not equal
9. Increment / Decrement
C
GCBASIC
x++;
x++
x--;
x--
Rule: Same
10. Constants
C
GCBASIC
#define MOTOR 100
#Define MOTOR 100
#define PERIOD 6944444
#Define PERIOD 6944444
Rule: Use #Define (capital D)
Type is implied
11. Comments
C
GCBASIC
// comment
// comment
/* block */
' block or //
Rule: // is fully supported and preferred
12. PWM & Timer Registers
C
GCBASIC
PR2 = 99;
PR2 = 99
T2CON = 0b00000111;
Same
CCPR1L = 50;
CCPR1L = 50
Rule: Identical register access
13. Interrupts
C
GCBASIC
INTCON = 0b10100000;
INTCON = 0b10100000
INTCON.T0IF = 0;
INTCON.T0IF = 0
Rule: Same bit names and masks
14. Binary Notation
C
GCBASIC
PORTA & *b00000011
PORTA And 0b00000011
Rule: Do not use &b prefix for binary use prefix 0b
Quick Template
// C (MikroC)voidmain(){TRISA=0b00000011;while(1){if(PORTA.F0)PORTB.F1=1;}}
```basic
// GCBASIC
chip 16F628A, 20
option explicit
Dir PORTA.0 In
Dir PORTB.1 Out
Main:
DIR PORTA.0 In
DIR PORTB.1 Out
DoIfPORTA.0ThenPORTB.1=1Loop
Final Checklist
#chip 16F628A, 20
All Dir pins set
Main loop
Sub Interrupt defined
INTCON.GIE = 1
No return in Sub used End Sub
Use Wait, not Delay_ms
Use ++ or --
Do not use UL for long constants
Use // comments
/******************************************************************************DC_motor_xtal.c-runaDCmotoratxtal"clockwork"lockedspeedStarted8Apr2013-Copyrightwww.RomanBlack.com,allowedforpublicuse,youmustmentionmeastheauthorandpleaseprovidealinktomywebpagewherethissystemisdescribed;www.RomanBlack.com/onesec/DCmotor_xtal.htmPIC16F628A-20MHzHSxtal(seewebpageforschematic)Compiler-MikroCforPICv8PICpins;RA0=digitalSTinput,quadencoderARA1=digitalSTinput,quadencoderBRB3=CCP1output,PWMtomotor,HI=ONRB0=echoencoderAoutputRB1=echoencoderAoutputPICconfigs;MCRLEoff,BODENoff,BORESoff,WDToff,LVPoff,PWRTon******************************************************************************/#chip 16F628A, 20#option Explicit//Thisconstantsetsthemotorspeed.ThevalueisinnanoSecondsperpulse,//asweareusingaquadratureencoderthereare4pulsesperencoderslot.//Myencoderhad36slots,sothatmakes36*4or144pulsesperrevolution.//Example;1motorrevpersecond=144pulses/sec.//nSperpulse=1billion/144=6944444//#define MOTOR_PULSE_PERIOD 1736111 // 4 RPS//#define MOTOR_PULSE_PERIOD 3472222 // 2 RPS#define MOTOR_PULSE_PERIOD 6944444 // 1 RPS//#define MOTOR_PULSE_PERIOD 13888889 // 0.5 RPS//Thisconstantsetstheproportionalgain.Basicallyitsetshowmuch//morePWM%isaddedforeachpulsebehindthatthemotorgets.//ie;ifsetto10,thePWMisincreasedby10%foreachpulsebehind.//Valuesmustbewithin1-50.Valuesof10or16workedwellwith//lowmotorRPMs,forhigherRPMsasmallervaluelike2to8canbeused.#define MOTOR_PROP_GAIN 10//globalvarsDimrposAsByte' reference position of xtal based freqDimmposAsByte' actual motor positionDimmlagAsByte' amount the motor lags the referenceDimenc_newAsByte' holds motor'squadratureencoderdatafortestingDimenc_lastAsByte' previous encoder stateDimbresAsLong' bresenham accumulator used to make ref frequencyDimpinsAsByte' temporary var for echoing encoder signals'=====================================================================' TMR0 INTERRUPT – Closed-loop DC motor speed control' Ported from MikroC void interrupt() function'=====================================================================SubInterrupt//---ClearTMR0interruptflagimmediately(maxsafety)INTCON.T0IF=0//--1.UPDATEENCODERPOSITION---------------------------enc_new=PORTAAnd0b00000011' read RA0, RA1 onlyIfenc_new<>enc_lastThenIfenc_new.1<>enc_last.0Thenmpos++' reverse step (original logic)Elsempos--' forward stepEndIfenc_last=enc_newEndIf//--2.UPDATEREFERENCE(Bresenham)----------------------' 512 cycles @ 20 MHz = 512 * 200 ns = 102400 ns per interruptbres=bres+102400Ifbres>=MOTOR_PULSE_PERIODThenbres=bres-MOTOR_PULSE_PERIODrpos++EndIf//--3.PROPORTIONALCONTROL(PWM)------------------------Ifmpos<rposThen' motor laggingmlag=rpos-mposIfmlag>=(100/MOTOR_PROP_GAIN)ThenCCPR1L=100' full powerElseCCPR1L=mlag*MOTOR_PROP_GAIN' proportionalEndIfElseCCPR1L=0' motor ahead → stopEndIf//--4.PREVENTROLL-OVER(keeperror)-------------------Ifrpos>250Ormpos>250Thenrpos=rpos-50mpos=mpos-50EndIfEndSub//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//=============================================================================//MAIN//============================================================================='=====================================================================' MAIN PROGRAM – GCBASIC port of MikroC main()'=====================================================================//-------------------------------------------------------//setupPIC16F628ACMCON=0b00000111;//comparatorsOFF,allpinsdigitalPORTA=0b00000000;//TRISA=0b00000011;//RA0,RA1usedfordigitalSTencoderinputsPORTB=0b00000000;//TRISB=0b00000000;//RB3isCCP1PWMout,RB0,RB1areencoderechooutputs//setTMR2torollevery100ticks,PWMfreq=5mil/16/100=3125HzT2CON=0b00000111;//TMR2ON,16:1prescalePR2=(100-1);//PWMtotalperiodof100//setPWMoutonCCP1CCPR1L=0;//PWMrange0-100%=startwithPWMof0%CCP1CON=0b00001100;//CCP1on,settoPWMmode//TMR0usedforinterrupt,makesinterruptevery512instsOPTION_REG=0b10000000;//PORTBpullupsOFF,TMR0on,2:1prescale//-------------------------------------------------------//setupbeforemainloopWait200ms;//allowPSUvoltagestimetostabilise//setupvarsetc,willbeusedininterruptbres=0;rpos=0;mpos=0;//finallystartTMR0rollinterruptINTCON=0b10100000;//GIE=on,TMR0IE=on//-------------------------------------------------------//mainrunloopDo//-------------------------------------------------//Wedon't need to do anything in main loop as the motor speed//controlisdoneentirelyintheTMR0interrupt.//-------------------------------------------------//Forconvenienceinsettinguptheencodertrimpots,//echothetwoencoderpinsouttwosparePORTBdigitaloutputs!pins=0;if(PORTA.0)Thenpins.0=1;if(PORTA.1)Thenpins.1=1;PORTB=pins;//outputthosetwopinsonly(PWMoutputisnotaffected)Loop
Last edit: Anobium 8 hours ago
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
// This constant sets the motor speed. The value is in nanoSeconds per pulse,
// as we are using a quadrature encoder there are 4 pulses per encoder slot.
// My encoder had 36 slots, so that makes 36*4 or 144 pulses per revolution.
// Example; 1 motor rev per second = 144 pulses /sec.
// nS per pulse = 1 billion / 144 = 6944444
//#define MOTOR_PULSE_PERIOD 1736111 // 4 RPS
//#define MOTOR_PULSE_PERIOD 3472222 // 2 RPS
define MOTOR_PULSE_PERIOD 6944444 // 1 RPS
//#define MOTOR_PULSE_PERIOD 13888889 // 0.5 RPS
// This constant sets the proportional gain. Basically it sets how much
// more PWM % is added for each pulse behind that the motor gets.
// ie; if set to 10, the PWM is increased by 10% for each pulse behind.
// Values must be within 1-50. Values of 10 or 16 worked well with
// low motor RPMs, for higher RPMs a smaller value like 2 to 8 can be used.
define MOTOR_PROP_GAIN 10
// global vars
unsigned char rpos; // reference position of xtal based freq
unsigned char mpos; // actual motor position
unsigned char mlag; // amount the motor lags the reference
unsigned char enc_new; // holds motor's quadrature encoder data for testing
unsigned char enc_last;
unsigned long bres; // bresenham accumulator used to make ref frequency
unsigned char pins; // temporary var for echoing encoder signals
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void interrupt()
{
//-------------------------------------------------------
// This is TMR0 int, prescaled at 2:1 so we get here every 512 instructions.
// This int does the entire closed loop speed control;
// 1. updates encoder to see if motor has moved, records it position
// 2. updates reference freq generator, records its position
// 3. compares the two, sets PWM if motor lags behind reference
// 4. limit both counts, so they never roll, but still retain all error
//-------------------------------------------------------
// clear int flag straight away to give max safe time
INTCON.T0IF = 0;
// 1. updates encoder to see if motor has moved, records it position
enc_new = (PORTA & 0b00000011); // get the 2 encoder bits
if(enc_new != enc_last)
{
if(enc_new.F1 != enc_last.F0) mpos++; // record new motor position
else mpos--;
enc_last = enc_new;
}
// 2. updates reference freq generator, records its position
bres += 102400; // add nS per interrupt period (512 insts * 200nS)
if(bres >= MOTOR_PULSE_PERIOD) // if reached a new reference step
{
bres -= MOTOR_PULSE_PERIOD;
rpos++; // record new xtal-locked reference position
}
// 3. compares the two, set PWM% if motor lags behind reference
if(mpos < rpos) // if motor lagging behind
{
mlag = (rpos - mpos); // find how far it's lagging behind
if(mlag >= (100/MOTOR_PROP_GAIN)) CCPR1L = 100; // full power if is too far behind
else CCPR1L = (mlag * MOTOR_PROP_GAIN); // else adjust PWM if slightly behind
}
else // else if motor is fast, cut all power!
{
CCPR1L = 0;
}
// 4. limit both counts, so they never roll, but still retain all error
if(rpos>250 || mpos>250)
{
rpos -= 50;
mpos -= 50;
}
//=============================================================================
// MAIN
//=============================================================================
void main()
{
//-------------------------------------------------------
// setup PIC 16F628A
CMCON = 0b00000111; // comparators OFF, all pins digital
PORTA = 0b00000000; //
TRISA = 0b00000011; // RA0,RA1 used for digital ST encoder inputs
PORTB = 0b00000000; //
TRISB = 0b00000000; // RB3 is CCP1 PWM out, RB0,RB1 are encoder echo outputs
// set TMR2 to roll every 100 ticks, PWM freq = 5mil/16/100 = 3125 Hz
T2CON = 0b00000111; // TMR2 ON, 16:1 prescale
PR2 = (100-1); // PWM total period of 100
// set PWM out on CCP1
CCPR1L = 0; // PWM range 0-100% = start with PWM of 0%
CCP1CON = 0b00001100; // CCP1 on, set to PWM mode
// TMR0 used for interrupt, makes interrupt every 512 insts
OPTION_REG = 0b10000000; // PORTB pullups OFF, TMR0 on, 2:1 prescale
//-------------------------------------------------------
// setup before main loop
Delay_mS(200); // allow PSU voltages time to stabilise
// setup vars etc, will be used in interrupt
bres = 0;
rpos = 0;
mpos = 0;
//-------------------------------------------------------
// main run loop
while(1)
{
//-------------------------------------------------
// We don't need to do anything in main loop as the motor speed
// control is done entirely in the TMR0 interrupt.
//-------------------------------------------------// For convenience in setting up the encoder trimpots,// echo the two encoder pins out two spare PORTB digital outputs!pins=0;if(PORTA.F0)pins.F0=1;if(PORTA.F1)pins.F1=1;PORTB=pins;// output those two pins only (PWM output is not affected)
I asked Grok to convert. It gave Grok the rules I wrote. It made one error.
' GCBASIC version of the motor speed control code for PIC16F628A' Assumes 20MHz clock#chip 16F628A, 20#option explicit' Constants#DEFINE MOTOR_PULSE_PERIOD 6944444#DEFINE MOTOR_PROP_GAIN 10' Variablesdimrposasbyte' reference positiondimmposasbyte' actual motor positiondimmlagasbyte' amount the motor lags the referencedimenc_newasbyte' holds motor'squadratureencoderdatadimenc_lastasbyte' last encoder statedimbresaslong' bresenham accumulator for reference frequencydimpinsasbyte' temporary for echoing encoder signals' Setup PIC16F628ACMCON=7' Disable comparators, all pins digitalPORTA=0DIRPORTA.0IN' RA0, RA1 for encoder inputsDIRPORTA.1INPORTB=0DIRPORTBOUT' All PORTB outputs (RB3 PWM, RB0/RB1 echo)' Setup TMR2 for PWM: 3125 Hz, period 100T2CON=0b00000111' TMR2 ON, 16:1 prescalerPR2=99' PWM period of 100CCPR1L=0' Start with 0% PWMCCP1CON=0b00001100' CCP1 PWM mode' Setup TMR0 for interrupt every ~102.4 us (512 instructions at 20MHz)OPTION_REG=0b10000000' Pullups OFF, TMR0 internal clock, 1:2 prescalerInitTimer0Osc,PRE0_2' Internal clock (Fosc/4), prescaler 1:2' Initial delay for PSU stabilizationWait200ms' Initialize variablesbres=0rpos=0mpos=0enc_last=0' Setup and start TMR0 interruptOnInterruptTimer0OverflowCallMotorISR' Main loop - echo encoder pins to RB0/RB1Dopins=0ifPORTA.0=1thenpins.0=1ifPORTA.1=1thenpins.1=1PORTB=pins' Output echo (PWM on RB3 unaffected)Loop' Interrupt Service Routine for closed-loop speed controlSubMotorISRTMR0IF=0' Clear interrupt flag' 1. Update encoder positionenc_new=PORTAAnd0b00000011ifenc_new<>enc_lastthenifenc_new.1<>enc_last.0thenmpos=mpos+1' Forwardelsempos=mpos-1' Backwardendifenc_last=enc_newendif' 2. Update reference frequency generatorbres=bres+102400' Add ns per interrupt periodifbres>=MOTOR_PULSE_PERIODthenbres=bres-MOTOR_PULSE_PERIODrpos=rpos+1endif' 3. Compare positions and adjust PWM if laggingifmpos<rposthenmlag=rpos-mposifmlag>=(100/MOTOR_PROP_GAIN)thenCCPR1L=100' Full power if too far behindelseCCPR1L=mlag*MOTOR_PROP_GAIN' Proportional adjustmentendifelseCCPR1L=0' Cut power if aheadendif' 4. Limit counts to prevent rollover while retaining errorifrpos>250ORmpos>250thenrpos=rpos-50mpos=mpos-50endifEndSub
Last edit: Anobium 8 hours ago
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you very much ANOBIUM, it compiles well. In the next few days I will try to assemble and test the mechanics to see if it works.
And what does that error mean?
OSC: HS, 20Mhz (Clock source is not a primary internal oscillator. Ensure the clock source is correctly setup) Chip: 16F628A
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I would be very grateful if someone could help me. I'm trying to compile this code but I can't get it to work.
Gbasic version : 2025.10.04 (Windows 64 bit) : Build 1523
Hello,
I am not sure who added this to your code but they gave you good advice. But, not complete.
However,
Code Review
The original GCBASIC port contained critical syntax errors that prevented compilation, including:
- Invalid
endif/wendkeywords- Deprecated loop structures
- Incorrect interrupt syntax
- Bit-shift confusion in quadrature logic
1. Critical Syntax Errors (Compilation Failures)
endifendifEnd IfwendwendLoopwhileloopwhile true … wendDo … LoopelseafterendifEnd IfbeforeElse2. Constants
const X = Y#DEFINE X Yconst MOTOR_PROP_GAIN = 10#DEFINE MOTOR_PROP_GAIN 103. Interrupt Handler (Manual Compliance)
oninterrupt Timer0Sub Interruptend oninterruptEnd Sub4. Delay Function
delayms 200Wait 200 msDelayMSis deprecated5. Quadrature Encoder Logic
(enc_new >> 1)(enc_new > 1)6. Bit Access in Main Loop (Readability)
if (PORTA & 1) thenIf PORTA.0 Thenif (PORTA & 2) thenIf PORTA.1 Then7. Verified Hardware Configuration
#chip16F628A, 20HS_OSCPR2 = 99,T2CON = 0b00000111OPTION_REG = 0b10000000Conclusion
The original port was non-functional due to fundamental syntax violations.
Through rigorous, line-by-line correction , the code has been compiled into a more robust, correct, and authoritative implementation.
Also, the original source code. You should share this. As the logic in your code provided does not make sense to me. 'if (enc_new > 1) <> (enc_last & 1) then' this makes no sense. It will compile but the outcome is not what you need.
This surely should be a bitwise inspections. The code may not work as expected.
Post the C source.
C to GCBASIC Porting Rules
High-Level Cheat Sheet for PIC16F628A (MikroC → GCBASIC))
1. Chip & Clock
#pragma config FOSC = HS#chip 16F628A, 20#option explicit(recommended)2. Functions
void main()Use a label Main:void interrupt()Sub Interrupt3. Infinite Loop
while(1) { }Do→Loop4. Variables
unsigned charDim x As Byteunsigned intDim x As Wordunsigned longDim x As Long5. Bit Access
PORTA.F0PORTA.0var.F3 = 1var.3 = 16. Port I/O
TRISA = 0b00000011;TRISA = 0b00000011Dir PORTA.0 In7. Delay
Delay_ms(200);Wait 200 ms8. Logic & Conditions
if (x != y)If x <> y ThenelseElse||Or&&And9. Increment / Decrement
x++;x++x--;x--10. Constants
#define MOTOR 100#Define MOTOR 100#define PERIOD 6944444#Define PERIOD 694444411. Comments
// comment// comment/* block */' blockor//12. PWM & Timer Registers
PR2 = 99;PR2 = 99T2CON = 0b00000111;CCPR1L = 50;CCPR1L = 5013. Interrupts
INTCON = 0b10100000;INTCON = 0b10100000INTCON.T0IF = 0;INTCON.T0IF = 014. Binary Notation
PORTA & *b00000011PORTA And 0b00000011Quick Template
```basic
// GCBASIC
chip 16F628A, 20
option explicit
Dir PORTA.0 In
Dir PORTB.1 Out
Main:
DIR PORTA.0 In
DIR PORTB.1 Out
Final Checklist
#chip 16F628A, 20Dirpins setSub InterruptdefinedINTCON.GIE = 1returninSubusedEnd SubWait, notDelay_ms++or--ULfor long constants//commentsLast edit: Anobium 8 hours ago
Thanks Anobium, sorry I posted the wrong version of the code. I asked the AI for help, that's why the AI added all that.
original MikroC code
// This constant sets the motor speed. The value is in nanoSeconds per pulse,
// as we are using a quadrature encoder there are 4 pulses per encoder slot.
// My encoder had 36 slots, so that makes 36*4 or 144 pulses per revolution.
// Example; 1 motor rev per second = 144 pulses /sec.
// nS per pulse = 1 billion / 144 = 6944444
//#define MOTOR_PULSE_PERIOD 1736111 // 4 RPS
//#define MOTOR_PULSE_PERIOD 3472222 // 2 RPS
define MOTOR_PULSE_PERIOD 6944444 // 1 RPS
//#define MOTOR_PULSE_PERIOD 13888889 // 0.5 RPS
// This constant sets the proportional gain. Basically it sets how much
// more PWM % is added for each pulse behind that the motor gets.
// ie; if set to 10, the PWM is increased by 10% for each pulse behind.
// Values must be within 1-50. Values of 10 or 16 worked well with
// low motor RPMs, for higher RPMs a smaller value like 2 to 8 can be used.
define MOTOR_PROP_GAIN 10
// global vars
unsigned char rpos; // reference position of xtal based freq
unsigned char mpos; // actual motor position
unsigned char mlag; // amount the motor lags the reference
unsigned char enc_new; // holds motor's quadrature encoder data for testing
unsigned char enc_last;
unsigned long bres; // bresenham accumulator used to make ref frequency
unsigned char pins; // temporary var for echoing encoder signals
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void interrupt()
{
//-------------------------------------------------------
// This is TMR0 int, prescaled at 2:1 so we get here every 512 instructions.
// This int does the entire closed loop speed control;
// 1. updates encoder to see if motor has moved, records it position
// 2. updates reference freq generator, records its position
// 3. compares the two, sets PWM if motor lags behind reference
// 4. limit both counts, so they never roll, but still retain all error
//-------------------------------------------------------
// clear int flag straight away to give max safe time
INTCON.T0IF = 0;
// 1. updates encoder to see if motor has moved, records it position
enc_new = (PORTA & 0b00000011); // get the 2 encoder bits
if(enc_new != enc_last)
{
if(enc_new.F1 != enc_last.F0) mpos++; // record new motor position
else mpos--;
enc_last = enc_new;
}
// 2. updates reference freq generator, records its position
bres += 102400; // add nS per interrupt period (512 insts * 200nS)
if(bres >= MOTOR_PULSE_PERIOD) // if reached a new reference step
{
bres -= MOTOR_PULSE_PERIOD;
rpos++; // record new xtal-locked reference position
}
// 3. compares the two, set PWM% if motor lags behind reference
if(mpos < rpos) // if motor lagging behind
{
mlag = (rpos - mpos); // find how far it's lagging behind
if(mlag >= (100/MOTOR_PROP_GAIN)) CCPR1L = 100; // full power if is too far behind
else CCPR1L = (mlag * MOTOR_PROP_GAIN); // else adjust PWM if slightly behind
}
else // else if motor is fast, cut all power!
{
CCPR1L = 0;
}
// 4. limit both counts, so they never roll, but still retain all error
if(rpos>250 || mpos>250)
{
rpos -= 50;
mpos -= 50;
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//=============================================================================
// MAIN
//=============================================================================
void main()
{
//-------------------------------------------------------
// setup PIC 16F628A
CMCON = 0b00000111; // comparators OFF, all pins digital
PORTA = 0b00000000; //
TRISA = 0b00000011; // RA0,RA1 used for digital ST encoder inputs
PORTB = 0b00000000; //
TRISB = 0b00000000; // RB3 is CCP1 PWM out, RB0,RB1 are encoder echo outputs
// set TMR2 to roll every 100 ticks, PWM freq = 5mil/16/100 = 3125 Hz
T2CON = 0b00000111; // TMR2 ON, 16:1 prescale
PR2 = (100-1); // PWM total period of 100
// set PWM out on CCP1
CCPR1L = 0; // PWM range 0-100% = start with PWM of 0%
CCP1CON = 0b00001100; // CCP1 on, set to PWM mode
// TMR0 used for interrupt, makes interrupt every 512 insts
OPTION_REG = 0b10000000; // PORTB pullups OFF, TMR0 on, 2:1 prescale
//-------------------------------------------------------
// setup before main loop
Delay_mS(200); // allow PSU voltages time to stabilise
// setup vars etc, will be used in interrupt
bres = 0;
rpos = 0;
mpos = 0;
// finally start TMR0 roll interrupt
INTCON = 0b10100000; // GIE=on, TMR0IE=on
//-------------------------------------------------------
// main run loop
while(1)
{
//-------------------------------------------------
// We don't need to do anything in main loop as the motor speed
// control is done entirely in the TMR0 interrupt.
}
}
//-----------------------------------------------------------------------------
I asked Grok to convert. It gave Grok the rules I wrote. It made one error.
Last edit: Anobium 8 hours ago
Thank you very much ANOBIUM, it compiles well. In the next few days I will try to assemble and test the mechanics to see if it works.
And what does that error mean?
OSC: HS, 20Mhz (Clock source is not a primary internal oscillator. Ensure the clock source is correctly setup) Chip: 16F628A
GCBASIC Warning Explained
Message
This is a warning from GCBASIC, not an error.
What It Means
OSC: HS, 20MhzChip: 16F628A(Clock source is not a primary internal oscillator...)Ensure the clock source is correctly setupRequired Hardware Setup
OSC1→ Pin 15OSC2→ Pin 16Required GCBASIC Configuration
or
Common Mistakes
#config OSC = HSINTRCwith 20 MHzSummary
#config OSC = HSThank you for your help and explanation.