Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

C18 Questions

Status
Not open for further replies.
It will indeed still take a while, I just meant it will help me get past the current snag. The final goal of making a device plug into two ports of a servo receiver and control two motors in two directions is a way off. But one by one I'm knocking parts of it off the list.
 
Sending an array of data(not string)

Hi i want to send a array of data through the serial port but when i try to use a pointer to address the array and then write

at start of program tempptr=tempdata;


then

putcUSART(*tempptr);
tempptr++;

it gives a syntax error.

On the other hand tempdata[counter] works fine.
 
Hi i want to send a array of data through the serial port but when i try to use a pointer to address the array and then write

at start of program tempptr=tempdata;


then

putcUSART(*tempptr);
tempptr++;

it gives a syntax error.

On the other hand tempdata[counter] works fine.

If you're using BoostC then it doesn't support ROM based pointers. You have to use the Var[offset] type of indexing.

Mike.
 
I am using C18 and wanted to use a pointer to index an array(a very very simple application).But i got errors so i used the conventional method.My question is

Can you index a numeric array using the built in functions of the USART.I tried and i got errors..am i doing it incorrectly?

PS: I have already done it the other way but wanted to clear my self about the abilities of C18.
 
I would guess that the function expects a ram based variable and wont work with a rom pointer, try,
Code:
static rom char HW[]="Hello World!";
rom char *P;
char i;

P=HW;           // or P=&HW[0];
while(*P){
    i=*P++;
    putcUSART(i);
}

Mike.
 
Last edited:
I am using a RAM Array already, but since it does not accept a ram array pointer so guess it was not working.I would rather use the conventional array indexing approach since my application allows it.The code you provide works.Thanks for you reply.
 
Alright, I coded a C18 version of what 3v0 posted above in post #139. The code is below, I have just included the part for the CCP setup, the interrupt and the timer setup:

configuration
Code:
	//configure timer1
	OpenTimer1(0b10010101);
	
	PIE1bits.TMR1IE = 1; //periferial interupt register, 1 = timer 1 interupt enabled
	PIR1bits.TMR1IF = 0; //clears the timer 1 interupt flag

	//configure CCP1 for capture, rising edge
	CCP1CON = 0b0000101;

code withen interrupt function
Code:
	//ccp interrupt
	if(PIR1bits.CCP1IF == 1)
	{	
		if(PWM1Edge == 1)//if detecting rising
		{	
			interrupttest3++;
			
			PWM1RiseTime = CCPR1;//save the low timer value for the rise time
			CCP1CON = 0b0000100;//switch to detect falling edge
			PWM1Edge = 0;//switch to indicate falling edge is next
		}
		else //detecting falling
		{
			interrupttest2++;

			PWM1Width = CCPR1 - PWM1RiseTime;
			CCP1CON = 0b0000101;//switch to detect rising edge
			PWM1Edge = 1;//switch to indicate rising edge is next
		}
		
		interrupttest1++;
		PIR1bits.CCP1IF = 0; //clear the flag
	}
}

So far it is working ok. The value I get ranges from 178 with the knob all the way in one direction to 143 all the way in the other, at a given position the value varies by as much as 9, but that variance increases towards the extremes, varying only by 3 in the neutral center position.

I'm looking for suggestions on how this could be improved. As I am not very good with timers, and CCP1 depends on timer1, I suspect that I could improve the settings there to get higher resolution. Would the resolution go up as the prescaler goes down or vice versa? Part of my concern is that I haven't really followed this step "Configure Timer1 prescaler so that Timer1 will run WMAX without overflowing." since I don't really understand prescalers. So, I'll need to read up on them and get that part fine tuned.

Any other suggestions on how this could be improved would be appreciated.

details: Im using a traxas 2215 receiver at 27mhz, it is connected to the 3 pin port of my junebug (RB3,UV5,GND)
 
Last edited:
You don't mention the speed of your chip but as it's a Junebug I assume you set it to 8MHz. If this is the case then I would set the prescaler to 2 so each timer 1 count = 1uS. This will mean that typical servo pulses should give you readings from 1000(1mS) to 2000(2mS). The prescaler is how much to divide the clock by before feeding it to timer 1 - it is already divided by 4 and so is effectively 2MHz.

Mike.
 
Yes, I'm using the 18F1320 on the junebug. I don't remember setting the speed of the chip, but I'll check on that.

I also have a question about debug mode. So far it seems as if it runs at full speed, if I have a LED set to blink every 1000mS, it seems to keep blinking every second weather I'm in debug mode or not, and the capture timing seems correct too. Does debug run at full speed?
 
Debug runs the chip at it's real speed when in RUN mode. But when you want to single step it's very slow at 31kHz (the default 18F1320 speed).
OSCCON = $72 will speed things up to 8MHz.

Note: The more variables you're watching the slower single step / animate will run.
 
I usually have been using run mode, even though I wasnt sure that would capture pwm properly I was sure that step animate wouldent get it.

Thanks for the speed control pointer.
 
I had the PWM measuring code working pretty well inside 3V0's program, but now that I moved it on its own I cant get the interrupt to go. I must be missing something. The standalone program I have so far is fairly short.

I wouldent be surprised if the problem is in the way I configured the interrupt as thats something I dont understand very well yet. Does each type of interrupt use its own function, or do they all call the interrupt function, then you sort out what to do by checking the flags? I've seen various interrupt code, and I cant really tell what each part means, so its hard to know what I copied over wrong. I've tried this line "#pragma code low_vector = 0x18" with 0x08 and 0x18 since I've seen both in examples, I cant see to get that interrupt to trigger.

Code:
 #pragma	config OSC = INTIO2, WDT = OFF, LVP = OFF
 #include <p18f1320.h>


//set up interrupt
void low_ISR(void);//prototype
#pragma code low_vector = 0x18
void low_interrupt (void){
_asm goto low_ISR _endasm
}
#pragma code
#pragma interrupt low_ISR


//setup pins for PWM input
#define ReceiverPin PORTBbits.RB3
#define ReceiverTris TRISBbits.TRISB3


//PWM capture variables
unsigned int PWM1RiseTime = 0;
unsigned int PWM1Width = 0;
char PWM1Edge = 1;

char test1 = 0;

// Interrupts
void low_ISR(void)
{		

	test1 = 1;
	//ccp interrupt
	if(PIR1bits.CCP1IF == 1)
	{	
		PIR1bits.CCP1IF = 0; //clear the flag
		if(PWM1Edge == 1)//if detecting rising
		{	
			
			PWM1RiseTime = CCPR1;//save the low timer value for the rise time
			CCP1CON = 0b0000100;//switch to detect falling edge
			PWM1Edge = 0;//switch to indicate falling edge is next
		}
		else //detecting falling
		{

			PWM1Width = CCPR1 - PWM1RiseTime;
			CCP1CON = 0b0000101;//switch to detect rising edge
			PWM1Edge = 1;//switch to indicate rising edge is next
		}
		
	}
}

void main(void)
{	
	//set clock to 8 Mhz
	OSCCONbits.IRCF0=1;  
	OSCCONbits.IRCF1=1;  
	OSCCONbits.IRCF2=1;  

	//configure timer1
	OpenTimer1(0b10010101);
	PIE1bits.TMR1IE = 1; //periferial interupt register, 1 = timer 1 interupt enabled
	PIR1bits.TMR1IF = 0; //clears the timer 1 interupt flag

	//configure CCP1
	CCP1CON = 0b0000101; //configure CCP1 for capture, rising edge
	ReceiverTris = 1; //set RB3 for input so the capture can work.
	
	//configure ports
	ADCON1 = 0xff; //all digital
	INTCON2bits.RBPU = 0; //port b weak pullups on
	
	while(1)
	{
	}
}
 
Last edited:
You aren't enabling the interrupts, you need to add these lines,
Code:
    INTCONbits.PEIE=1;		//enable peripheral ints
    PIE1bits.CCP1IE=1;		//namely the CCP1 int
    INTCONbits.GIE=1;		//finally turn them on

And remove these lines,
Code:
	PIE1bits.TMR1IE = 1; //periferial interupt register, 1 = timer 1 interupt enabled
	PIR1bits.TMR1IF = 0; //clears the timer 1 interupt flag

This is because you are using the ccp interrupt - not the timer1 interrupt.

Mike.
 
Thanks, what was missing from all my variations so far in trying to get it to work was turning on GIE.

For anyone interested, heres the working code I have so far for Capturing the width of a PWM signal. In this case from a servo receiver plugged into RB3 of the junebug:

Code:
//Basic configureation of chip periferials
 #pragma config OSC = INTIO2, WDT = OFF, LVP = OFF
 #include <p18f1320.h>

//setup pins for PWM input
#define ReceiverPin PORTBbits.RB3
#define ReceiverTris TRISBbits.TRISB3


//PWM capture variables
unsigned int PWM1RiseTime = 0;
unsigned int PWM1Width = 0;
char PWM1Edge = 1;

//set up interrupt
void low_ISR(void);//prototype
#pragma code low_vector = 0x08
void low_interrupt (void){
_asm goto low_ISR _endasm
}
#pragma code
#pragma interrupt low_ISR

//debug stuff
char test1 = 0;
char test2 = 0;

void main(void)
{	
	OSCCON = 0x72; //8MHz clock
	while(!OSCCONbits.IOFS); //Wait for OSC to become stable 

	//configure timer1
	OpenTimer1(0b10010101);
	PIE1bits.TMR1IE = 1; //periferial interupt register, 1 = timer 1 interupt enabled
	PIR1bits.TMR1IF = 0; //clears the timer 1 interupt flag

	//configure CCP1
	CCP1CON = 0b0000101; //configure CCP1 for capture, rising edge
	INTCONbits.PEIE=1;		//enable peripheral interrupts
    PIE1bits.CCP1IE=1;		//enabled CCP1 interrupt
    INTCONbits.GIE=1;		//enable branching to interrupt
	
	ReceiverTris = 1; //set RB3 for input so the capture can work.
	
	//configure ports
	ADCON1 = 0xff; //all digital
	INTCON2bits.RBPU = 0; //port b weak pullups on
	
	while(1)
	{
	}
}


void low_ISR(void)
{		

	test1 = 1;
	//ccp interrupt
	if(PIR1bits.CCP1IF == 1)
	{	
		PIR1bits.CCP1IF = 0; //clear the flag
		if(PWM1Edge == 1)//if detecting rising
		{	
			
			PWM1RiseTime = CCPR1;//save the low timer value for the rise time
			CCP1CON = 0b0000100;//switch to detect falling edge
			PWM1Edge = 0;//switch to indicate falling edge is next
		}
		else //detecting falling
		{

			PWM1Width = CCPR1 - PWM1RiseTime;
			CCP1CON = 0b0000101;//switch to detect rising edge
			PWM1Edge = 1;//switch to indicate rising edge is next
		}
		
	}
}
 
Hi! me again...i was doing a program on the 18LF4620 that requires me to calculate the percent difference between two integers.I was surprised to find out that although C18 allows multiplication and division of 'int' but when i was subtracting one from the other, it was only subtracting the Lower 8 bits.Weird huh?Is there any way with out using the 32 bit libraries(huge code size)?Except the manual way(8 bit operations)
 
Post the code. You have done something wrong. Sixteen bit maths works fine in C18.

Mike.
 
Just worked it out.The problem was with the result that i was expecting.I cant calculate percentages with out using floating point math since the answer is going to be in decimals(after divisions) which cant be used with out teh math library so even after multiplying it with 100 i got zero.So what i have done is just calculated the difference and then did the other stuff in my labview vi(constituting the other part of the 'project').Thanks for you reply Mike.
 
Hi 3V0,here is the code.This is just a math test.

Code:
#include<p18f4620.h>
void main(void)
{	unsigned int result;
	unsigned int a=0x1018;
	unsigned int b=0x0018;
	unsigned int ceilingrd=0x1018;
	unsigned int ceilingr=0x0018;
	unsigned int diff,perc,castingl,castingh;
	castingl=(ceilingrd);
	castingh=(ceilingrd/256);
	diff=ceilingrd-ceilingr;
	result=b-a;
	perc=(diff/ceilingrd)*100;
	
	while(1);

If you see in MPLab Sim the variable perc is zero.


PS:3V0 can i PM you about a board that i made.Its basically a question(not technical) and may be useful to you.I would be really thankful.If you say yes the i will get back to you i 2 or 3 days..just wanted to ask since i have your attention.
 

Attachments

  • Mplabsim.JPG
    Mplabsim.JPG
    20.8 KB · Views: 174
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top