Author Topic: MPLAB X on PIC10F222, getting started.  (Read 19669 times)

0 Members and 1 Guest are viewing this topic.

Offline Bruce Abbott

  • Frequent Contributor
  • **
  • Posts: 627
  • Country: nz
    • Bruce Abbott's R/C Models and Electronics
Re: MPLAB X on PIC10F222, getting started.
« Reply #25 on: December 12, 2015, 07:44:46 pm »
using the _delay(x) command that i got working, and which is a reflection of the clock frequency somehow.
_delay(x) simply executes a fixed number of CPU instructions which the compiler has pre-calculated will produce the required delay. It works because the PIC always takes the same amount of time to execute each instruction. Of course this timing is dependent on clock speed, so the compiler must be told what clock frequency the chip will be running at.

Note that this delay is not accurate when put into a program, because other code in the loop adds an unknown number of extra instructions. A few lines of C code could add 10s to 100s of microseconds.
     
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: MPLAB X on PIC10F222, getting started.
« Reply #26 on: December 12, 2015, 11:21:29 pm »
 
Quote
this delay is not accurate when put into a program, because other code in the loop adds an unknown number of extra instructions. A few lines of C code could add 10s to 100s of microseconds.
Quote
I want to to make the LED blink with a speed set by the voltage on the input
I doubt that 100 microsecond accuracy is needed for LED blinking :-)

Code: [Select]
    :
   value = ADRES;  // Get A-D value, 0-255
   // Blink LED
   GPIO = 0b000100;   // Turn on LED
   while (value--) {
      delay_ms(4);   // Delay 0-1 sec total. 4 ms for each A-D count.
   }
   GPIO = 0b000000;   // Turn off LED
 

Offline step_sTopic starter

  • Regular Contributor
  • *
  • Posts: 138
  • Country: dk
Re: MPLAB X on PIC10F222, getting started.
« Reply #27 on: December 13, 2015, 12:40:25 am »
@Mark: That wont work.

@O.P.
That is when you *NEED* to use a delay function or routine that will take a variable as a parameter rather than the compiler's built-in _delay() or  __delay_us(), __delay_ms() macros.  Mark's delay macros wrap _delay() so have the same 'no variables' limitation.

You could use one of the variable delay functions for XC8/HiTech C you will find scattered all over the net (and if you want a particularly accurate one for PICs with more memory, ask me), however on a PIC10, I'd do it a bit differently, because of the limited stack depth, RAM and FLASH.


Thank you for the post Ian :)
So what you are saying is that the _delay(x) function is not able to load variables directly. . . I'm a bit confused in trying to find another macro on the net, since all I seem to find is pretty much what Mark has written. If you had a suggestion for putting in a variable directly, it would be much appreciated :)

Quote
Code: [Select]
   // Blink LED
   GPIO = 0b000100;   // Turn on LED
   for(i=0; i<ADRES; i++) __delay_ms(4);   // Delay 0-1 sec
   GPIO = 0b000000;   // Turn off LED

i should be declared as unsigned char at the start of the main() function.  As xc8 isn't officially C99 compliant yet, avoid the temptation to declare it in the for() statement.  Don't forget the #define _XTAL_FREQ 4000000UL

There's another pitfall here.  If you use i<=ADRES, the loop will never end if ADRES is 255, as i will wrap to zero before it can become greater than ADRES.

So basicly this code  compares ADRES to the unsigned char, and if it's lower than ADRES, the char gets +1 and a 4ms delay is added. This will run until I = ADRES, and the LED wil light. Am i right? Is this a good way of doing it, or a necessary evil? :P

Thanks in advance!
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12860
Re: MPLAB X on PIC10F222, getting started.
« Reply #28 on: December 13, 2015, 01:08:28 am »
Its a good way of doing it on a PIC10 due to its limited resources, though you might also call it evil.  On a 14 bit cire PIC18 or an 16 bit core PIC18, a carefully tuned delay function is better: See http://www.microchip.com/forums/m877727.aspx
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: MPLAB X on PIC10F222, getting started.
« Reply #29 on: December 13, 2015, 02:45:38 am »
I would normally do:
Code: [Select]
void delay_ms(int n)  // delay for a variable number of ms
{
   while (n--)
      __delay_ms(1);  // delay that requires a constant.
}

main() {
    :
   value = ADRES;
    :
   delay_ms(value);

And only didn't because of the known limitations of the PIC10 (call stack, variable space, questionable amount of C compiler optimization.)
(It would probably be "educational" to run several of these suggestions through your compiler and compare the assembly code produced.)
(A "reasonably good" compiler would inline the function call and notice that "value" would be overlapped with n, and you'd get the same code.)
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12860
Re: MPLAB X on PIC10F222, getting started.
« Reply #30 on: December 13, 2015, 02:53:57 am »
Code: [Select]
do{ __delay_ms(1); }while(--n);Has less loop overhead provided n is unsigned char, as the loop compiles to a DECFSZ and a GOTO or BRA (under HiTech C or XC8), but it has the disadvantage that n=0 takes 256 loops, and the small overhead doesn't matter if you are running off a +/-1% to 2% internal oscillator.
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 2549
  • Country: us
Re: MPLAB X on PIC10F222, getting started.
« Reply #31 on: December 13, 2015, 04:43:58 am »
@Mark: That wont work.

@O.P.
That is when you *NEED* to use a delay function or routine that will take a variable as a parameter rather than the compiler's built-in _delay() or  __delay_us(), __delay_ms() macros.  Mark's delay macros wrap _delay() so have the same 'no variables' limitation.

You could use one of the variable delay functions for XC8/HiTech C you will find scattered all over the net (and if you want a particularly accurate one for PICs with more memory, ask me), however on a PIC10, I'd do it a bit differently, because of the limited stack depth, RAM and FLASH.


Thank you for the post Ian :)
So what you are saying is that the _delay(x) function is not able to load variables directly. . . I'm a bit confused in trying to find another macro on the net, since all I seem to find is pretty much what Mark has written. If you had a suggestion for putting in a variable directly, it would be much appreciated :)

Quote
Code: [Select]
   // Blink LED
   GPIO = 0b000100;   // Turn on LED
   for(i=0; i<ADRES; i++) __delay_ms(4);   // Delay 0-1 sec
   GPIO = 0b000000;   // Turn off LED

i should be declared as unsigned char at the start of the main() function.  As xc8 isn't officially C99 compliant yet, avoid the temptation to declare it in the for() statement.  Don't forget the #define _XTAL_FREQ 4000000UL

There's another pitfall here.  If you use i<=ADRES, the loop will never end if ADRES is 255, as i will wrap to zero before it can become greater than ADRES.

So basicly this code  compares ADRES to the unsigned char, and if it's lower than ADRES, the char gets +1 and a 4ms delay is added. This will run until I = ADRES, and the LED wil light. Am i right? Is this a good way of doing it, or a necessary evil? :P

Thanks in advance!

Using --delay_ms(1) inside a loop will be the best and easiest way to implement a delay in most cases.  Another option would be to use one of the timers (if one is available).  However this is quit involved.  I would only use a timer (with or without interrupts) if you need a long delay or have special timing requirements.
 

Offline step_sTopic starter

  • Regular Contributor
  • *
  • Posts: 138
  • Country: dk
Re: MPLAB X on PIC10F222, getting started.
« Reply #32 on: December 13, 2015, 12:10:21 pm »
Okay guys, thanks for all the great answers!
So after looking at your suggestions I have made the following code:

Code: [Select]
#define _XTAL_FREQ 80000000UL
#define delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/40000.0)))

unsigned char i;
unsigned char j;

void main(void) {

   ADCON0bits.ANS = 0b01; //Setting GP0 to analog
   ADCON0bits.CHS = 0b00; //Select channel ANS0
   ADCON0bits.ADON = 1; //Enable ADC
   OPTION = 0b00000000; //Disable all OPTION to enable GP2
   TRISGPIO = 0b00001001; //Set GP0 and GP3 to input
     
   while (1)
   {
       GP1 = 0; //Resets LEDS
       GP2 = 0; //Resets LEDS
       
       while (GP3 = 0); //Button press
       {
          ADCON0bits.GO=1; // Read analog data
          while (ADCON0bits.nDONE); // Wait for A/D to convert 
       
         i = ADRES; // Transfers ADRES to i
         j = ADRES; // Transfers ADRES to j
         GP1 = 1;   // Turn on RED LED
         GP2 = 0;   // Turn off BLUE LED
         for(i=0; i<ADRES; i++) delay_ms(18);   // Delay = 1sec/v
         GP1 = 0;   // Turn off RED LED
         GP2 = 1;   // Turn on BLUE LED
         for(j=255; j>ADRES; j--) delay_ms(18);   // Delay = 1sec/v
       }
     }
   } 
I have a two colored blue/red LED connected, and this will make it blink depending on the voltage.
By raising the divider in (_XTAL_FREQ/40000.0) to give a lower delay, I can make the LED blink with a speed that makes for an intermittent color red->purple->blue.
This is pretty much what i wanted, but now i have two problems:
How can I make the LED switching on/off into a separate delay, so that they will stay flickering in the intermittent color for a short while,
after the button press? A loop inside a loop I would guess? I can't seem to find any PWM functions on this PIC, since this would cut off some code,
and make me explore some new features + make for a better LED driver.
Also, I need some sort of "interval" on the voltage, since this is for a lithium cell, and it will need the color to be red at 3V and go towards blue at 4.2V.

I might be overlooking some simple things right now, but I just got up. . forgive me xD
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12860
Re: MPLAB X on PIC10F222, getting started.
« Reply #33 on: December 13, 2015, 12:36:08 pm »
Its a baseline PIC so there are no interrupts, no PWM and if you want to do anything concurrent at different time scales(e.g. read a button and PWM a LED), your only choice is a state machine in a fast superloop.

If you upgraded to a midrange device you get timer interrupts, so could do software PWM in the background, and in the case of the pin-compatible PIC10F320/322 chips, you also get two hardware PWM modules so can 'set and forget' the LED colour, and the hardware will maintain it while you code does other stuff.

Edit: dead link switched to wayback machine archive
« Last Edit: June 27, 2016, 10:15:39 am by Ian.M »
 

Offline Howardlong

  • Super Contributor
  • ***
  • Posts: 5319
  • Country: gb
Re: MPLAB X on PIC10F222, getting started.
« Reply #34 on: December 13, 2015, 02:03:34 pm »
You could use the watchdog timer to delay turn off, this is the closest you'll get to an "interrupt" on that device, but it resets, so at the beginning on main() you have to check to TO, PD and GPWUF bits of the status register to determine what caused the reset.

All of this is fiddly and makes for difficult to read code. While it can and is done, I'd agree with Ian and jump up to the 10f320/322 if you need the same form factor device for the reasons he cites.

Alternatively, stick with what you have, and if you get it to work reasonably well it will be a great learning experience. Sometimes, though, if there's no need to beat yourself with a stick, then don't!
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12860
Re: MPLAB X on PIC10F222, getting started.
« Reply #35 on: December 13, 2015, 02:32:37 pm »
There's no need to beat yourself with several sticks.

There are perfectly good baseline parts with a lot more pins if you want to learn assembler programming on the 12 bit core as an intellectual 'hair shirt' exercise: e.g. PIC16F527 which has 20 pins including a full 8 bit port C so you can output whole bytes to LEDs to debug it.  e.g. if you are feeling flush, hang two N.O.S. TIL311 Hex decoded 7 segment LEDs off it for direct readout.  Me? I make do with binary readout on a 10 LED bar graph and a 330R resistor array.

The highly pin constrained PIC10 parts should only be used when size and weight are ultimate requirements.  Due to the low pin count it is often difficult to arrange the application circuit to permit in-circuit programming without adding a lot of extra components, so its usual to order them pre-programmed.  Use of the PIC10 DIP packages other than for pure development is a sign of insanity, you might as well use a PIC12 and get two more I/Os, or free ICSP/ICD pins.

The cost savings of using an under-specified chip are usually so small that the added development costs involved with torturing your programming team till the code fits wont be recovered till somewhere between 10K and 100K units have been sold.  Don't do it, especially not for small volume and one-offs.
« Last Edit: December 13, 2015, 03:08:18 pm by Ian.M »
 

Offline Howardlong

  • Super Contributor
  • ***
  • Posts: 5319
  • Country: gb
Re: MPLAB X on PIC10F222, getting started.
« Reply #36 on: December 13, 2015, 02:59:58 pm »
All of what Ian.M stated.

Even with the debug header versions of the very low end devices, debugging is painful, typically with only one breakpoint for example, so you can't single step and have a separate code breakpoint.

As a general rule for these devices, I develop on a near identical device with a few more pins for debugging (blinky pins, and in circuit debugging/programming) and if necessary port back to the real thing.

The only thing I use these the PIC10F2xx for has been to program up chip registers on power up like clock generators. For that they're great, but not for anything much more complex.
 

Offline step_sTopic starter

  • Regular Contributor
  • *
  • Posts: 138
  • Country: dk
Re: MPLAB X on PIC10F222, getting started.
« Reply #37 on: December 13, 2015, 05:19:27 pm »
Thank you all for the great advice. I just leaped in to this with no knowledge at all, so it means a lot!
I see now that the chip is quite inadequate for the task I wanted it to do.
Say I wanted to upgrade to a better suited PIC, and i wanted to make it in to a complete project for the lithium cell. Looking at the PIC16 family with 14 pins, would any of these be able to do the task of:

Have the battery indicator formulated in this thread (Only 2 color LED version is needed).
Be able to run a step up converter for lithium cell to 5V, at a reasonable frequency (500kHz-1MHz).
Be able to run a step down converter for 5V to lithium cell.
Have room for a few other button press features for some extra fun.

My first thought was to just have a step down converter to the cell, to charge it from a 5V source, up to around 4V (since most converters have a 1-1.2V gap from input), and then have a linear chip take over for the last 0.35V. This was in order to prevent overheating when the battery voltage was low in the first part of charging (the batteries are 3200mah 4.35V cell).
Then after that, have a step up converter with a good solid output, from the cell to a 5V output (already played around with some good SOT-23 1.5A ones).
At the end have this small PIC10 run a voltage indicator. For a total of 3 x SOT-23 package chips, and a few other components.

Maybe i should make a new thread on this, but any help is much appreciated! :)
 

Offline Bruce Abbott

  • Frequent Contributor
  • **
  • Posts: 627
  • Country: nz
    • Bruce Abbott's R/C Models and Electronics
Re: MPLAB X on PIC10F222, getting started.
« Reply #38 on: December 13, 2015, 05:44:12 pm »
By raising the divider in (_XTAL_FREQ/40000.0) to give a lower delay,
Don't do this. The delay_ms() function will then not be milliseconds, but something else.  If you want a shorter delay then change the value of x in delay_ms(x). If 1ms is too long then change the name of your macro to something more appropriate, eg. delay_us() or my_delay().

Use a define so you only have to change the delay value in one place, like this:-

#define  TICK 18
...
         for(i=0; i<ADRES; i++) delay_ms(TICK);   // Delay = 1sec/v


Quote
How can I make the LED switching on/off into a separate delay, so that they will stay flickering in the intermittent color for a short while, after the button press? A loop inside a loop I would guess?
Yes, just create an outside loop that repeats the blinking pattern a certain number of times after the button press.

Quote
I can't seem to find any PWM functions on this PIC, since this would cut off some code, and make me explore some new features + make for a better LED driver.
First get it to work properly, and don't get carried away trying to make it 'better' or adding features unless there is a real need for it.   

The first thing I would look at is ADC accuracy. To get a stable result you will probably have to take several readings and average them.

Quote
Also, I need some sort of "interval" on the voltage, since this is for a lithium cell, and it will need the color to be red at 3V and go towards blue at 4.2V.
Subtract 3V from the ADC reading (or make it zero if already less then 3V). If the analog input is scaled to get a reading 255 at 4.2V then you have 16.5mV per step. 3V/16.5mV = 182. Subtract 182 from the ADC reading and you get a range of 0-73 representing 3.0 to 4.2 Volts.

Make your flicker routine loop 73 times, with a step delay of 1/73 = 13ms giving a 1 second flicker period (or use a shorter delay if you want it to flicker faster). When the loop count is less than or equal to the ranged ADC value turn the Blue LED on and the Red LED off, when it is above do the opposite.

Quote
I see now that the chip is quite inadequate for the task I wanted it to do.
It is quite adequate for what you wanted it to do.
 
Quote
Looking at the PIC16 family with 14 pins, would any of these be able to do the task of:

Have the battery indicator formulated in this thread (Only 2 color LED version is needed).
Be able to run a step up converter for lithium cell to 5V, at a reasonable frequency (500kHz-1MHz).
Be able to run a step down converter for 5V to lithium cell.
Have room for a few other button press features for some extra fun.
Some of the latest chips may be able to do all that, but do you have the programming skills to get it all working properly?

Quote
the batteries are 3200mah 4.35V cell
This is a large cell and potentially very dangerous. I would not consider using a PIC to charge it unless I was very sure that my code was safe.
 

« Last Edit: December 13, 2015, 05:46:30 pm by Bruce Abbott »
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12860
Re: MPLAB X on PIC10F222, getting started.
« Reply #39 on: December 13, 2015, 06:08:48 pm »
A MCP19111 has enough processing power (a 8MHz PIC midrange core) and a realtime analog synchronous buck control loop sufficient to implement LiPO battery charging and management with minimal external components apart from a pair of MOSFETs.  However it cant directly handle boosting the LiPO to 5V unless you want to write a software driven boost converter and certainly cant do that at  >500KHz so would need an external boost converter for the application output  5V regulator, although it could monitor and control one.

It certainly isn't a 14 pin part, and as Bruce has pointed out, DIY LiPO management in software requires excellent programming skills and a high level of justified self-confidence.  Many consultants would be cautious taking that project on.  Its certainly *NOT* novice friendly.

You are going about this the wrong way.   The question shouldn't be "What midrange 14 pin PIC can do all this?", it should be "What PIC or other brand MCU can tie together chips or hardware modules to monitor and control the following tasks, while operating over the full voltage range of a LiPO battery and drawing negligible current when off/quiescent?" and "How is my choice constrained by the T.C.O. of the tools to develop for and debug in-circuit my shortlist of MCUs?".     Finally, beware of feeping creaturitis creeping featuritis!
 

Offline step_sTopic starter

  • Regular Contributor
  • *
  • Posts: 138
  • Country: dk
Re: MPLAB X on PIC10F222, getting started.
« Reply #40 on: December 13, 2015, 06:34:48 pm »
@Bruce
True, it does what I wanted it to do, basicly, and it has still been quite insightful. I understand. . . keep the code understandable. Keep ms in ms and us in us!
How would this outside loop look like? The 3-4.2v range is done! Thanks :)
It does seem like too much work to program a PIC when the fact is that the step-up and step-down IC's can be had in SOT-23 packages (same size as the switching MOSFETs I would need anyway), and it is tried and tested. Reliability over all.
@Ian
I get your point. What works best together, and how simple and effective can it be done. I will try to not catch featuritis xD
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12860
Re: MPLAB X on PIC10F222, getting started.
« Reply #41 on: December 13, 2015, 06:53:27 pm »
Got a PICkit 3?  If so I'd be looking at debug capable (without extra headers) enhanced midrange PIC16F1xxx parts in 14 pin DIP for development and 16 lead QFN for the final version.  The 16 lead QFN package is only 4mm x 4mm which is no larger than a PIC12 SOIC-8 footprint.  There are no other PIC families in such a small package that have *ANY* members with built-in debug support.  Dedicating the ICSP/ICD pins to development that leaves you with 9 I/Os for your application and hopefully not *TOO* much feeping creaturitis.   The internal band-gap references aren't that great so you'll probably have to calibrate the ADC.   Beware: not all PICs with a band-gap FVR module can actually feed that to the ADC module as the +Vref internally.  Check datasheet and errata *BEFORE* designing one in! 
 

Offline Howardlong

  • Super Contributor
  • ***
  • Posts: 5319
  • Country: gb
Re: MPLAB X on PIC10F222, getting started.
« Reply #42 on: December 13, 2015, 07:15:49 pm »
I concur regarding the MCP19111, it seemed like a great part, but when I got into the nitty gritty with it wasn't quite so nice. For example, it talks about being able to deal with supplies/chargers with Vout > 3.6v by using a simple potential divider: it can't, if you want current limiting, unless you use an external current sense device, which you'll then have to somehow interface to the MCP19111 ISEN differential inputs, and a simple pair of potential dividers won't work. I lost a week or two of my life on that part.

Doing buck/boost in not trivial. Start with buck, then move up.

For measuring current beyond the voltage range of your device, typically you either measure it with reference to ground with a current sense resistor (and all the issues you then have with a semi-floating ground) or use an external current sense part.
 

Offline step_sTopic starter

  • Regular Contributor
  • *
  • Posts: 138
  • Country: dk
Re: MPLAB X on PIC10F222, getting started.
« Reply #43 on: December 13, 2015, 07:44:46 pm »
@Ian
Got a Sure PicKit 3 clone. The PIC16F1xxx series seem like a really nice, and small PIC in the SMD version. Sure has lot's of PWM capabilities.
Talking about debugging and calibrating the ADC seems quite confusing right now, that i just learned these other new things!  :P
You have some kind of suggestion for the delay function of the button that Bruce was talking about? The external loop?

@Howardlong
I will try this out in the future :)
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12860
Re: MPLAB X on PIC10F222, getting started.
« Reply #44 on: December 13, 2015, 08:15:44 pm »
Did you read the 'superloop' link I gave in post#33?

To do the Batt status LED active delay from the button push, I'd implement a superloop with a sandwich delay of no greater than 100ms, (preferably in the 10ms to 20ms range), using a hardware timer.   

In the superloop it would have various tasks implemented as state machines so they can all execute and either do nothing or the appropriate action for that moment.  Any delays used would be minimal and only for unavoidable bit-banging of serial bus protocols to control peripheral chips.  If any task needed a delay, it would count passes of the superloop until the time for its next action.  All tasks would return as near immediately as possible.

So with that out of the way, you'd need the following:
* ADC task, responsible for updating a Batt_voltage variable
* Button task, responsible for monitoring and debouncing the button
* LED task, responsible for lighting the LEDs in the correct pattern until its time to turn them off again.

Its then a matter of choice whether you make each task monitor global variables and flags to determine when to run, or whether you minimise such interfaces by having a:

* SYSCON task responsible for timing and deciding when to start/stop other tasks.

On anything except a baseline PIC, I'd use one function per task.  On a baseline PIC, if I couldn't trust the compiler to inline stuff properly, I'd use a compound statement (block enclosed by { }) for each task, carefully commented just inside the {, directly in main().
« Last Edit: December 13, 2015, 08:56:04 pm by Ian.M »
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 2549
  • Country: us
Re: MPLAB X on PIC10F222, getting started.
« Reply #45 on: December 13, 2015, 08:38:07 pm »
Okay guys, thanks for all the great answers!
So after looking at your suggestions I have made the following code:

Code: [Select]
#define _XTAL_FREQ 80000000UL
#define delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/40000.0)))

unsigned char i;
unsigned char j;

void main(void) {

   ADCON0bits.ANS = 0b01; //Setting GP0 to analog
   ADCON0bits.CHS = 0b00; //Select channel ANS0
   ADCON0bits.ADON = 1; //Enable ADC
   OPTION = 0b00000000; //Disable all OPTION to enable GP2
   TRISGPIO = 0b00001001; //Set GP0 and GP3 to input
     
   while (1)
   {
       GP1 = 0; //Resets LEDS
       GP2 = 0; //Resets LEDS
       
       while (GP3 = 0); //Button press
       {
          ADCON0bits.GO=1; // Read analog data
          while (ADCON0bits.nDONE); // Wait for A/D to convert 
       
         i = ADRES; // Transfers ADRES to i
         j = ADRES; // Transfers ADRES to j
         GP1 = 1;   // Turn on RED LED
         GP2 = 0;   // Turn off BLUE LED
         for(i=0; i<ADRES; i++) delay_ms(18);   // Delay = 1sec/v
         GP1 = 0;   // Turn off RED LED
         GP2 = 1;   // Turn on BLUE LED
         for(j=255; j>ADRES; j--) delay_ms(18);   // Delay = 1sec/v
       }
     }
   } 

A programming note here:
Code: [Select]
         i = ADRES; // Transfers ADRES to i
         j = ADRES; // Transfers ADRES to j
Setting i and j do nothing in your code.  The first thing the "for" loops do is to set i and j to zero.
Also, you don't need two separate variables for the two loops.  You could use either i or j in both loops. 
Your "for" loops will initialize i and j to zero when entering the loop and incrementing them at the end of each pass through the loop.
 

Offline owiecc

  • Frequent Contributor
  • **
  • Posts: 315
  • Country: dk
    • Google scholar profile
Re: MPLAB X on PIC10F222, getting started.
« Reply #46 on: December 13, 2015, 08:53:36 pm »
I ordered a PicKit3 and got a dev board with PIC16F1459 on it. It has a USB port. You get programming templates for OS X, Windows and Linux (MLA) so you can easily make an app to connect to your PIC.
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12860
Re: MPLAB X on PIC10F222, getting started.
« Reply #47 on: December 13, 2015, 09:02:31 pm »
While that is a nice little chip for lightweight I/O via USB,  *NOONE* in their right minds uses an 8 bit or 16 bit USB capable PIC for applications that don't need a USB interface.  There's no need to pay extra for the USB SIE, loose I/O pins to it, and get a crappier set of peripherals due to the die area it takes up.  The *ONLY* excuse is for a hobbyist who is having to settle for what's stocked locally because they cant order internationally.

(The equation's a bit different with PIC32 as the feature set you need may not be availabele *without* USB)
 

Offline step_sTopic starter

  • Regular Contributor
  • *
  • Posts: 138
  • Country: dk
Re: MPLAB X on PIC10F222, getting started.
« Reply #48 on: December 13, 2015, 09:22:48 pm »
Did you read the 'superloop' link I gave in post#33?

To do the Batt status LED active delay from the button push, I'd implement a superloop with a sandwich delay of no greater than 100ms, (preferably in the 10ms to 20ms range), using a hardware timer.   

In the superloop it would have various tasks implemented as state machines so they can all execute and either do nothing or the appropriate action for that moment.  Any delays used would be minimal and only for unavoidable bit-banging of serial bus protocols to control peripheral chips.  If any task needed a delay, it would count passes of the superloop until the time for its next action.  All tasks would return as near immediately as possible.

So with that out of the way, you'd need the following:
* ADC task, responsible for updating a Batt_voltage variable
* Button task, responsible for monitoring and debouncing the button
* LED task, responsible for lighting the LEDs in the correct pattern until its time to turn them off again.

Its then a matter of choice whether you make each task monitor global variables and flags to determine when to run, or whether you minimise such interfaces by having a:

* SYSCON task responsible for timing and deciding when to start/stop other tasks.

On anything except a baseline PIC, I'd use one function per task.  On a baseline PIC, if I couldn't trust the compiler to inline stuff properly, I'd use a compound statement (block enclosed by { }) for each task, carefully commented just inside the {, directly in main().


I read it now and understand the concept, but fail in seeing how to implement it. I see the PIC has a TMR0 internal timer, but how do use this function?
You want to divide all of the tasks in to separate tasks, but defining them or?
Sorry, but I'm a bit confused :P

@Mark
Ye, thanks for keeping an eye out. . I saw the stupidity myself :)
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12860
Re: MPLAB X on PIC10F222, getting started.
« Reply #49 on: December 13, 2015, 10:05:37 pm »
Sticking with your PIC10F222 for the moment, configure Timer 0 for internal (Fosc/4) clock with a prescaler of /128 for 4MHz Fosc or /256 for 8MHz Fosc.  That means that starting from zero, the top bit of timer 0 will toggle every 16.4ms (aprox).  Unfortunately there is no overflow flag for the timer so we cant do it the way we would on a non-baseline PIC.

The superloop and sandwich delay code becomes:
Code: [Select]
while(1){
   TMR0=0; // Start sandwich delay: 16.384ms (nominal) 'ticks'

   // tasks go here

   while(!(TMR0&0x80)); // Wait for TMR0 top bit to end sandwich delay
}

The LED task goes something like:
Code: [Select]
{ // LED blinking task
    static unsigned char LEDtime=0;  // LED timer in complete flickers
    static unsigned char LEDcnt=MAXVOLTS;    // LED counter for flicker

    if(button) LEDtime=5; // five complete flicker cycles per button push

    if(LEDtime) {
        LEDtime--;       
        if(LEDcnt>BattVolts) GPIO=RED; else GPIO=BLUE;
        if(!LEDcnt--) LEDcnt=MAXVOLTS; //reset flicker counter
    }
}
and of course you'll also need #defines for the bits to output for RED and BLUE and the scaled and offset  ADC count MAXVOLTS corresponding to 3.4V on the LiPO. 

Bugfixed: missing ; in if() ... else ... and corrected the TMR0 prescaler ratios. 
« Last Edit: December 14, 2015, 01:05:19 am by Ian.M »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf