problems programming in mikroeC - Page 1
Forum section: electronics / general

author: Simon
author_rank: Unknown
timestamp: October 14, 2012, 12:13:38 pm
content: so I wrote the following program:it is a cut down version of what I was starting with as nothing was happening, I have since added code to set the clock speed registers as even though I had set 8MHz in the project settings panel it was running on just over 30KHz !!!, even after getting the clock to 8MHz no pwm out ensuesCode:int speed_pot, speed_fan;void main() {TRISA = 0b11111111 ; /* all of port A to be inputs */ANSEL = 0b00011111 ; /* AN0-AN5 of porta A to be analog inputs */TRISB = 0b00000000 ; /*all of port B is outputs *//* analog prescler set to 16 (for 8MHz) */ADCS2_bit = 1 ; ADCS1_bit = 0 ; ADCS0_bit = 1 ;/* ADC ref setting to Vcc & GND */VCFG1_bit = 0; VCFG0_bit = 0 ;/* right justify ADC result */ADFM_bit = 1 ;/* enable PWM module */CCP1M3_bit = 1 ; CCP1M2_bit = 1 ;PWM1_Init(1000); /* initialize the PWM output at 1KHz) *//*speed_pot = ADC_read(0); read the value of the fan speed pot *//*speed_fan = speed_pot ; transfer speed setting to speed control */PWM1_set_duty(100); /* use speed_fan variable for PWM duty */PWM1_start() ;while(1);}

author: Baliszoft
author_rank: Frequent Contributor
timestamp: October 14, 2012, 12:28:54 pm
content: I am not into the mikroeC, but i suppose the PWM1_ ... functions are from a library or they are predefined ones. What i know is that generating a PWM signal needs a timer to be set up, too. I don't know if it is done by the PWM1_ ... functions, or not.EDIT: I see that you are specifying the frequency, though no selection for the timer itself.

author: djsb
author_rank: Super Contributor
timestamp: October 14, 2012, 01:25:24 pm
content: Can you post the full code listing please? What chip is this for?David.PS Did you read my reply to your post elsewhere where I recommend the CCS PCM Compiler?

author: Simon
author_rank: Unknown
timestamp: October 14, 2012, 02:04:37 pm
content: That is all the code. anything else is in the setup panel although I had to set the clock speed myself. There was no mentioning of setting up a timer in the library explanation, and not wanting to be funny I'll be doing assembly soon if I have to spell any more out to the compiler. I doubt the code will be portable because I have to refer to so many registers that one register name change on another processor will ruin code portability.I didn't realize there was a free (demo) version of CCS, I might give it a go.

author: Simon
author_rank: Unknown
timestamp: October 14, 2012, 02:08:45 pm
content: I could probably have this running on mikroe basic........

author: baljemmett
author_rank: Unknown
timestamp: October 14, 2012, 02:14:08 pm
content: You don't appear to be setting TRISC appropriately; I think you mentioned you were using the PIC16F77 somewhere, and the PWM section of the datasheet has:Quote

author: Simon
author_rank: Unknown
timestamp: October 14, 2012, 02:15:05 pm
content: it's a 16F88

author: Baliszoft
author_rank: Frequent Contributor
timestamp: October 14, 2012, 02:35:50 pm
content: Quote from: Simon on October 14, 2012, 02:04:37 pmIf there is only one timer in that micro, then probably that's the answer (and you dont have to deal with selecting one). A timer is needed for PWM though.

author: Simon
author_rank: Unknown
timestamp: October 14, 2012, 02:38:53 pm
content: well I enabled the PWM module with registers and invoked it from the PWM library, what else should i do, any more and I'll be writing all of the registers myself and just do "high level assembler"

author: baljemmett
author_rank: Unknown
timestamp: October 14, 2012, 02:40:58 pm
content: Quote from: Simon on October 14, 2012, 02:15:05 pmOh balls, sorry, my mistake! Ignore that then, obviously...What I'd do, personally, is just implement section 9.3.3 of the datasheet by hand first to give yourself a baseline for troubleshooting. That's mainly because I'm not familiar with whatever library routines you have available; I'd guess they aren't starting Timer2 but that's just a guess, so at least if you follow the steps by hand you should have something that works and you can then try replacing bits with library calls to get a hint as to what's missing.... on the other hand you could just throw in a TMR2ON = 1; to see if Timer2 is indeed the missing bit!I just had a quick Google to see what other library calls mikroC supports, and they havea page describing the routineswhich comes complete with a comment from some chap asking why he can't get them working, hmm. Their sample code looks like your code, so perhaps it's their problem rather than yours.

author: Simon
author_rank: Unknown
timestamp: October 14, 2012, 02:44:09 pm
content: Quote from: baljemmett on October 14, 2012, 02:40:58 pmTo be honest I've been plagued with "their" problems since using their basic compiler, I thought the C one was supposed to be better.(in the basic compiler you can only set 8 bits of resolution in the PWM not 10 because they are too stupid to write a library that uses the 2 bits from the other register !)

author: Baliszoft
author_rank: Frequent Contributor
timestamp: October 14, 2012, 02:50:16 pm
content: Mmmm. Maybe you could try to initialize the PWM "manually" then. Usually it involves, selecting port directions, setting up a timer (which will determine the frequency), enabling that timer (!), setting up the CCP module in PWM mode with the duty cycle and finally enabling the CCP module, too.

author: Simon
author_rank: Unknown
timestamp: October 14, 2012, 02:51:11 pm
content: yea that was the idea of a library, and it works in their basic except that it only does 8 bit resolution

author: baljemmett
author_rank: Unknown
timestamp: October 14, 2012, 02:51:46 pm
content: Quote from: Simon on October 14, 2012, 02:44:09 pmYeah, I've observed your various tales of woe with their compilers in the past -- personally I wouldn't bother with 'em if they give that much trouble, even if MPLAB can take a little more fiddling to set up!I think I'd still suggest trying to follow the various steps in section 9.3.3 by hand -- you might find their libraries are doing almost everything apart from one crucial step, and then you can go back to using the library calls with that omission in mind. Good luck :-/

author: Simon
author_rank: Unknown
timestamp: October 14, 2012, 02:52:40 pm
content: yea I'll need it, and they expect to sell this shit !

author: Simon
author_rank: Unknown
timestamp: October 14, 2012, 03:37:41 pm
content: Yes my aim is to control the PWM output with the ADC input.I'm actually trying to knock this up in basic, see if that works. I use libraries because I want it as fast and simple as possible.

author: Simon
author_rank: Unknown
timestamp: October 14, 2012, 03:53:36 pm
content: I got it to workI initally had issues with the clock speed, then while sorting that out started probing the wrong CCP1 pin and didn't know what the MCLR setting was

author: djsb
author_rank: Super Contributor
timestamp: October 14, 2012, 03:55:39 pm
content: Here is a PWM example using CCS CCode://LED + 150 Ohm Resistor on CCP pin B3#include <16F819.h>#fuses INTRC_IO,NOWDT,NOPROTECT,NOLVP,CCPB3,MCLR#use delay(clock=1000000)//Use a 1 MHz clockvoid main() {unsigned char value;long DutyMax;float Duty;//Float variable needed for Duty calculationsetup_ccp1(CCP_PWM);//Configure CCP1 for PWMsetup_timer_2(T2_DIV_BY_4, 255, 1);//Setup Timer2DutyMax=((255+1)*4)-1;//Calculate max duty and store in a long variablewhile(TRUE) {for(value=0;value<255;value++){//Increase in brightnessDuty = ((DutyMax/255)*value);//Calculate duty and store in a float variableset_pwm1_duty((long)Duty); //Set PWM duty by Type Casting to a long variable typedelay_ms(1);}for(value=255;value>0;value--){//Decrease in brightnessDuty = ((DutyMax/255)*value);//Calculate duty and store in a float variableset_pwm1_duty((long)Duty); //Set PWM duty by Type Casting to a long variable typedelay_ms(1);}}}You just have to use the ADC to control the brightness instead of the For() loop.David.

author: Simon
author_rank: Unknown
timestamp: October 14, 2012, 03:57:38 pm
content: I did have a little look at CCS but in the setup bit noticed it won't let me go over 500 Hz on the frequency, I'm happy to loose bits in favour of speed as 20 steps will be fine

author: Simon
author_rank: Unknown
timestamp: October 14, 2012, 04:08:16 pm
content: well I'm getting some weird behavior. The PWM is now occurring in bursts of 10ms with pauses of 10ms this is for either 100 duty or 1000 duty and a frequency of 1KHzI'm also getting the odd verification fail on programming, maybe my chips are knackered

author: Simon
author_rank: Unknown
timestamp: October 14, 2012, 07:50:28 pm
content: i got it to work and suspect that my uC's are knackered. The PWM library works! and it even takes 10 bit values correctly! the problem was that despite me setting 8MHz in the project settings panel I still had to set it up in the registers, presumably only the compiler uses the value in the settings panel to calculate delays etc. so I actually had a default clock of 31.25KHzWhat I'm trying to do now is work out how to loop my program and how to run through the register setup procedure once only. for following did not workCode:int speed_pot, speed_fan, setupconfig=0;void main() {for (; setupconfig = 0 ;){/* Clock speed set to 8MHz */IRCF2_bit = 1; IRCF1_bit = 1; IRCF0_bit = 1;TRISA = 0b11111111 ; /* all of port A to be inputs */ANSEL = 0b00011111 ; /* AN0-AN5 of porta A to be analog inputs */TRISB = 0b00000000 ; /*all of port B is outputs *//* analog prescler set to 16 (for 8MHz) */ADCS2_bit = 1 ; ADCS1_bit = 0 ; ADCS0_bit = 1 ;/* ADC ref setting to Vcc & GND */VCFG1_bit = 0; VCFG0_bit = 0 ;/* right justify ADC result */ADFM_bit = 1 ;PWM1_Init(1000); /* initialize the PWM output at 1KHz) */setupconfig = 1;}/*speed_pot = ADC_read(0); read the value of the fan speed pot *//*speed_fan = speed_pot ; transfer speed setting to speed control */PWM1_set_duty(1000); /* use speed_fan variable for PWM duty */PWM1_start() ;while(1);}

author: TheDirty
author_rank: Frequent Contributor
timestamp: October 14, 2012, 08:19:27 pm
content: Yes, anything you setup in the project settings panel is simply for reference by their libraries. You are not changing code at all. You need to do everything yourself and setting up the main oscillator is needed.The code posted by djsb is a very common method and a pretty standard template for a basic C program for the PIC. The original register setup is done and all the non-interrupt driven processing is done within a "while(1)" infinite loop.Like others I would highly suggest not using any PIC specific libraries that are supplied by the compiler until you know the peripherals.

author: baljemmett
author_rank: Unknown
timestamp: October 14, 2012, 08:38:47 pm
content: Quote from: Simon on October 14, 2012, 07:50:28 pmNope, because your for loop doesn't make any sense the way you have it. The structure of a for loop in C is:for (begin;test;step) {body}Which translates to:begin;while (test) {body;step; }... so your 'for(; setupconfig=0;)' will never execute because 'setupconfig=0' equals zero which means false.However, I'm not sure why you want a for loop at all, especially over the setup code; the general layout of your code should look something like:Code:void main() {/* Setup code here, will execute once at startup */while (1) {/* Code to execute repeatedly forever here */}}So I'd put everything that's inside your for loop at the moment where I have the first comment, and then put the ADC reading and PWM duty cycle setting calls inside the while loop where I have the second comment.Alternatively, if you wanted to try a loop to test out the PWM stuff, you could do something like this inside your while loop:Code:for (speed_fan = 64; speed_fan < 192; speed_fan++){PWM1_set_duty(speed_fan);/* Some sort of delay here so you can see the ramp;* not sure what delay routines you might have,* so adjust to suit!*/delay_ms(100);}... which will make it repeatedly ramp the PWM output from 25% up to 75% over the course of ~12 seconds, just so you can see it working.Hmm, actually, your comment about the PWM library accepting 10-bit values is at odds with the documentation I found earlier, which says it only accepts 8-bit values! So you may need to change the start and end conditions in my example loop to suit -- but of course, as you're learning the language it's always a good idea to play around with examples anyway so you can get a feel for how it hangs together.

author: ptricks
author_rank: Frequent Contributor
timestamp: October 15, 2012, 11:19:35 pm
content: Quote from: TheDirty on October 14, 2012, 08:19:27 pmThe interesting thing is if you read the help files they don't go into mentioning about configuring the clocks, or ports yourself which causes new users to get confused . I don't use their stuff except when I have something that requires it like a TFT LCD design, their libraries make this stuff easy. I prefer to use the microchip version of C.