|
|
View previous topic :: View next topic |
Author |
Message |
[email protected]
Joined: 05 Nov 2003 Posts: 23
|
use_fast_io didn't work, PWM didn't work A2D didn't work 16F |
Posted: Thu Sep 09, 2004 8:45 am |
|
|
Wow, all that in one try.
The basics:
Windoze 2000 SP2, 128MB RAM
PCM 3.18
PIC 16F73 (rev C)
My problems:
1)
I tried to use the #use_fast_io settings on my 16F73 and no I/O worked
at all, all I/O lines where still set as inputs. I used the set_tris_a/b/c to
set up the correct directions, but it just wouldn't work until I took out the
#use_fast_io directives. This used to work, did it get broken?
2)
Here is the setup code for my PWM for CCP1 on the 16F73
[code]
set_tris_c(0b10000000);
setup_timer_2(T2_DIV_BY_16,0,1); //about 1.2KHz PWM
set_timer2(0);
setup_ccp1(CCP_PWM);
output_low(PWM);
set_pwm1_duty(500);
[/code]
No PWM is shown, the PWM line stays low. A related question, in the
setup_timer_2() there is a period field, which says in the manual can
be from 0-255 - which doesn't make sense because this is a 16 bit
timer, although the CCS manual thinks it is only 8 bit. Is this a
compiler issue or a manual issue? I had this set to 0, 1023, 127, 500,
it made no difference, no PWM was coming out. What am I not
doing correctly for PCM?
3)
The A2D does not seem to work, here is the setup code that I use:
[code]
set_tris_a(0b00011111);
setup_adc(ADC_CLOCK_INTERNAL); //May work, we'll see
setup_port_a(ALL_ANALOG); //all channels
setup_adc_ports(ALL_ANALOG);
set_adc_channel(0); //get forward side voltage
ma = read_adc();
[/code]
No readings are returned. ma is a unsigned long BTW. Also, example
programs always show setup_port_a(), the manual doesn't have that,
it has setup_adc_ports() - So which is it? Both seem to compile, which
one is the correct one to use?
Can anyone show me where my understanding of the "way things be"
is different from the CCS compiler's needs? I've not looked at the
assembly code generated, so I'm not read to comment on what it
did there yet.
thanks,
Dennis Clark
TTT Enterprises _________________ --
------------------------------------
Dennis Clark [email protected]
http://www.techtoystoday.com
------------------------------------ |
|
|
[email protected]
Joined: 05 Nov 2003 Posts: 23
|
|
Posted: Thu Sep 09, 2004 1:36 pm |
|
|
Hmm, upon MUCH closer reading of the docs for the 16F73, I think that I
see what I did wrong with the PWM bit. I still don't have answers for
questions 1 and 3.
DLC _________________ --
------------------------------------
Dennis Clark [email protected]
http://www.techtoystoday.com
------------------------------------ |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Sep 09, 2004 1:52 pm |
|
|
Quote: | The A2D does not seem to work. |
More detailed information is needed to help on this.
What voltage is being applied to the A/D pin ?
What values are you reading ?
The A/D converter is only 8-bits on this PIC. Are you
aware of this ? (ie., 16F877 A/D is 10-bits)
CCS uses 3 digits to the right of the decimal point for their
version numbers. There can be huge differences between
versions. What is your full version number ?
http://www.ccsinfo.com/versions.shtml |
|
|
[email protected]
Joined: 05 Nov 2003 Posts: 23
|
|
Posted: Thu Sep 09, 2004 2:31 pm |
|
|
[quote="PCM programmer"][quote]The A2D does not seem to work.[/quote]
More detailed information is needed to help on this.
What voltage is being applied to the A/D pin ?
What values are you reading ?
The A/D converter is only 8-bits on this PIC. Are you
aware of this ? (ie., 16F877 A/D is 10-bits)
Yes, I originally read the wrong PIC doc, yes it is 8 bits. The voltage
on the A2D pins is 0-4.87V, constrained by a resistor network and
other things - I've measured this on a scope.
[quote]PCM 3.18 [/quote]
CCS uses 3 digits to the right of the decimal point for their
version numbers. There can be huge differences between
versions. What is your full version number ?
http://www.ccsinfo.com/versions.shtml[/quote]
3.180 is my version.
DLC _________________ --
------------------------------------
Dennis Clark [email protected]
http://www.techtoystoday.com
------------------------------------ |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Sep 09, 2004 3:06 pm |
|
|
Quote: |
Yes, I originally read the wrong PIC doc, yes it is 8 bits. The voltage
on the A2D pins is 0-4.87V, constrained by a resistor network and
other things - I've measured this on a scope. |
I looked at the ASM code for vs. 3.180 with the 16F73.
I don't see any problems with it.
One thing you should know is that these two lines do exactly
the same thing. The function names are aliases for each other.
You only need to use one of them.
setup_port_a(ALL_ANALOG);
setup_adc_ports(ALL_ANALOG);
Questions:
1. How do you determine that the A/D doesn't work ?
2. What values do you read ?
You should post a small but complete test program
that shows the problem. Show all pre-processor
statements, #include statements, etc. Show the
printf() line that displays the values. Show all
variable declarations. ie., Don't leave anything
out of the test program that you post. |
|
|
Charlie U
Joined: 09 Sep 2003 Posts: 183 Location: Somewhere under water in the Great Lakes
|
|
Posted: Thu Sep 09, 2004 3:43 pm |
|
|
I'll try to add a little here and see if it helps.
Regarding the #use fast_io() pre-processor command, it must be before the set_tris function calls. I use this command an several different processors and it seems to work fine. I am using 3.190 though.
Regarding the pwm setup, try:
setup_timer_2(T2_DIV_BY_16,0xFF,1);
You do not need the set_timer2() call. I am not certain why you are setting the PWM pin low. I have never needed anything like this to get the pwm to work. The set_pwm1_duty(500); call should set the dc and the pwm should work.
If this pwm works like the others that I have used, the least 2 bits in the timer are cleared at the beginning of the period and the upper 8 bits are loaded from the PR2 register. This is the second parameter (0xFF) in the setup_timer_2 call above. The timer then runs and is compared to the value in CCPR1L and the 5 and 4 bits of CCP1CON. If the value in the set_pwm1_duty call is a long, then the compiler will load both the CCPR1L register and the CCP1CON bits. If the value is an int, then it will merely load the value into the CCPR1L register.
So, in summary, the actual period will be 4x the parameter entered in the setup_timer_2 call and the period will be either equal to the parameter in the set_pwm1_duty call if it is a long or it will be 4x the value if it is an int. Hows that for confusing!?!?
Regarding the adc, you just have snippets of code, so it is hard to make detailed comments on this, but are you waiting the acquisition time after you select the adc channel? From your code it appears that you are not. Look at the data sheet and see how much delay time is required between the channel set and the read. |
|
|
[email protected]
Joined: 05 Nov 2003 Posts: 23
|
|
Posted: Thu Sep 09, 2004 9:31 pm |
|
|
Here's the answers and what I'm doing. The weird thing is that I've
used this compiler and this chip with ADC on another project and it
worked fine. This doesn't work at all, about the only thing that is
working is the RS232 port.
DLC
[quote]
I looked at the ASM code for vs. 3.180 with the 16F73.
I don't see any problems with it.
Questions:
1. How do you determine that the A/D doesn't work ?
2. What values do you read ?
[/quote]
I get zeros out of it with printf's
[quote]
You should post a small but complete test program
that shows the problem. Show all pre-processor
statements, #include statements, etc. Show the
printf() line that displays the values. Show all
variable declarations. ie., Don't leave anything
out of the test program that you post.
[/quote]
[code]
//picpid.c
/*
This is my attempt at a simple but complete PID velocity controller. It will use all PID
and trapazoidal ramp up and down speed capabilities if I succeed.
PID
t = current time
error(t) = Vdesired(t) - Vmeasured(t)
Vcontrol(t) = Vprop(t) + Vinteg(t) + Vderiv(t)
Vprop(t) = Kp * error(t) (Kp = proportional gain)
Vinteg(t) = Ki * SUM(error(0 to t)) (Ki = integral gain; SUM = sum of all past errors)
Vderiv(t) = Kd * (error(t) - error(t-1)) (Kd = deriv gain; error difference between last and now)
*/
#include <16F73.h>
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT
#use delay(clock=14740000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) //hardware UART
//#use FAST_IO(C) //turned off, didn't work
//#use FAST_IO(B)
//#use FAST_IO(A)
#define PWM PIN_C2
#define DIR1A PIN_B0
#define DIR1B PIN_B1
//*******************************************************************************************
// GLOBALS
//*******************************************************************************************
signed long ehist; //error history accumulated
signed long Vdesired; //desired velocity (arbitrary units)
signed long Verror;
signed long lerror = 0; //last error value
signed long Vc, Vp, Vi, Vd;
float Kp = 1; //proportional gain
float Ki = .1; //integral gain
float Kd = .5; //derivitive gain
//*******************************************************************************************
// FUNCTIONS
//*******************************************************************************************
void init(void)
{
/*
A0 = AN0 analog input for direction A side of motor
A1 = AN1 analog input for direction B side of motor
A2 = digital output (unused)
A3 = AN3 analog input for speed pot input
A4 = digital output (unused)
A5 = digital output (unused)
*/
set_tris_a(0b00011111);
setup_adc(ADC_CLOCK_INTERNAL); //May work, we'll see
setup_adc_ports(ALL_ANALOG);
/*
B0 = DIR1A output
B1 = DIR2A output
B2-B5 unused outputs
B6 = PGD for ICSP
B7 = PGC for ICSP
*/
set_tris_b(0x00);
/*
C0 = unused output
C1 = PWM2 output (unused)
C2 = PWM1 output
C3 = unused output
C4 = unused output
C5 = unused output
C6 = TxD output
C7 = RxD input
*/
set_tris_c(0b10000000);
setup_timer_2(T2_DIV_BY_16,255,1); //about 1.2KHz PWM
setup_ccp1(CCP_PWM);
set_pwm1_duty(0);
ehist = 0; //no history yet
}
signed long getMeasured()
{
signed long meas;
unsigned int ma,mb;
delay_ms(1); //wait for steady state
set_adc_channel(0); //get forward side voltage
delay_us(30);
ma = read_adc();
printf("MA %u\n\r",ma);
set_adc_channel(1); //get reverse side voltage
delay_us(30);
mb = read_adc();
printf("MB %u\n\r",mb);
if (ma > mb)
meas = ma;
else
meas = 0 - mb; //negative value for reverse
return meas;
}
void main(void)
{
Vdesired = 100;
output_low(PWM);
set_pwm1_duty(500);
output_low(DIR1A);
output_high(DIR1B);
while(1)
{
Vc = getMeasured();
printf("MEAS= %ld\r\n",Vc);
delay_ms(100);
}
}
[/code][/code][/quote] _________________ --
------------------------------------
Dennis Clark [email protected]
http://www.techtoystoday.com
------------------------------------ |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Sep 09, 2004 9:40 pm |
|
|
1. You have an init() routine, but it's never called.
2. Your post has lots of [code] and [quote] statements but
they are not working. Have you accidently checked the
box for "Disable HTML in this post" ? |
|
|
[email protected]
Joined: 05 Nov 2003 Posts: 23
|
|
Posted: Thu Sep 09, 2004 9:53 pm |
|
|
[quote="PCM programmer"]1. You have an init() routine, but it's never called.
2. Your post has lots of [code] and Quote: | statements but
they are not working. Have you accidently checked the
box for "Disable HTML in this post" ? |
I can't believe I made such a noob mistake. I must now hide my head
in shame, never to be seen by my fellow programmers again.
DLC _________________ --
------------------------------------
Dennis Clark [email protected]
http://www.techtoystoday.com
------------------------------------ |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|