PIC 24F processor programming experiences
2 posters
Page 1 of 1
PIC 24F processor programming experiences
I have started programming (in C) with the PIC 24F microcontroller line, 16 bit processor.
First problem I ran into was the inability to read the port B input lines. A was able to read other discrete input lines, but not Port B. A little internet search revealed that the analog inputs are turned on by default. There is a register line that is used to turn off all analog inputs. You can also allow some analogs to be turned on, and some turned off. Note that the analog input pins are shared with the discrete ports, and that switching between analog and digital channels is a register setting in the microcontroller. A true bit turns off analog channel.
AD1PCFGL = 0xFFFF;
If you want to use analog channel 1 only you would use this for register value: 0xFFFE
First problem I ran into was the inability to read the port B input lines. A was able to read other discrete input lines, but not Port B. A little internet search revealed that the analog inputs are turned on by default. There is a register line that is used to turn off all analog inputs. You can also allow some analogs to be turned on, and some turned off. Note that the analog input pins are shared with the discrete ports, and that switching between analog and digital channels is a register setting in the microcontroller. A true bit turns off analog channel.
AD1PCFGL = 0xFFFF;
If you want to use analog channel 1 only you would use this for register value: 0xFFFE
N1LAF- Charter Member
- Posts : 68
Join date : 2011-11-29
Millisecond timer for PIC24F - Part 1
Controlling processor events by time is an important feature, and here we will go over how to implement a millisecond counter for PIC24F family processors.
This will be the starting point of this discussion
- Code:
#include <p24FJ256GA1xx.h>
#include <stdlib.h>
// Configuration for PIC24F
_CONFIG1(JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF & WINDIS_OFF & ICS_PGx1)
_CONFIG2(IESO_OFF & FNOSC_PRI & FCKSM_CSDCMD & OSCIOFNC_OFF & IOL1WAY_ON & POSCMOD_EC)
_CONFIG3(WPCFG_WPCFGDIS & WPDIS_WPDIS)
// Start of main program
int main(void) {
// Loop forever
while (1) {
}
}
This will be the starting point of this discussion
N1LAF- Charter Member
- Posts : 68
Join date : 2011-11-29
Millisecond timer for PIC24F - Part 2
First we need a procedure to configure the timer, to setup timer interrupt, and a global millisecond variable.
Timer Configuration:
We need to calculate the 1 millisecond time constant. We can use a #define statement for this. For the PIC24F, it takes two seconds to execute an instruction. And we know that 1 Sec = 1000 milliseconds. There is a PRESCALE variable, but for this example, it is 1.
Timer Configuration:
- Code:
void config_timers(void) {
/* Timer setup */
T1CON = 0x00; // Stop timer1, reset control reg
TMR1 = 0x00; // Clear timer register
PR1 = 0xFFFF; // Load the period register
IPC0bits.T1IP = 0x01; // Set timer1 interrupt priority level
IFS0bits.T1IF = 0; // Clear timer1 interrupt status flag
IEC0bits.T1IE = 1; // Enable Timer1 Interrupt
T1CONbits.TON = 1; // Start Timer1
}
We need to calculate the 1 millisecond time constant. We can use a #define statement for this. For the PIC24F, it takes two seconds to execute an instruction. And we know that 1 Sec = 1000 milliseconds. There is a PRESCALE variable, but for this example, it is 1.
Last edited by N1LAF on Sun Jul 21, 2013 11:03 am; edited 1 time in total
N1LAF- Charter Member
- Posts : 68
Join date : 2011-11-29
Millisecond timer for PIC24F - Part 3
To calculate timer executions per millisecond, TMR1msec = CLOCKOSCFREQ * (1000 msec/sec) * (1 execution/2 cycles), simplify to:
TMR1msec = CLOCKOSCFREQ*500
The timer overflow interrupt occurs when the timer wraps around from 0xFFFF to 0, so the timer needs to be updated with a value that represents 1 millisecond until interrupt is called.
So we need a timer interrupt routine...
TMR1msec = CLOCKOSCFREQ*500
The timer overflow interrupt occurs when the timer wraps around from 0xFFFF to 0, so the timer needs to be updated with a value that represents 1 millisecond until interrupt is called.
So we need a timer interrupt routine...
- Code:
void timer_interrupt_function(void) {
MSECClock++; // Increment millisecond variable
TMR1 = 0xFFFF - TMR1msec; // Reset timer counter
}
N1LAF- Charter Member
- Posts : 68
Join date : 2011-11-29
Millisecond timer for PIC24F - Part 4
We will need to setup an interrupt vector for the timer:
The MSECClock global variable will increment every 1 millisecond.
- Code:
void __attribute__ ((__interrupt__, no_auto_psv, __shadow__)) _T1Interrupt(void) {
timer_interrupt_function(); // Call millisec update routing
IFS0bits.T1IF = 0; // Clear interrupt flag
}
The MSECClock global variable will increment every 1 millisecond.
N1LAF- Charter Member
- Posts : 68
Join date : 2011-11-29
Millisecond timer for PIC24F - Part 5
An example using the timer is a time delay function
- Code:
void time_delay_ms(unsigned int ms)
{
unsigned int timer = MSECClock; // Set local variable to present
// millisecond counter variable
while((MSECClock - timer) < ms) // Loop for ms milliseconds
{
;
}
}
N1LAF- Charter Member
- Posts : 68
Join date : 2011-11-29
Millisecond timer for PIC24F - Part 6 - Putting it together
Our code should look like this:
- Code:
#include <p24FJ256GA1xx.h>
#include <stdlib.h>
#define CLOCKOSCFREQ 16 // Assuming usage of external 16 Mhz Osc
#define TMR1msec CLOCKOSCFREQ*500
void config_timers(void);
void time_delay(unsigned int ms);
unsigned int MSECClock = 0;
// Configuration for PIC24F
_CONFIG1(JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF & WINDIS_OFF & ICS_PGx1)
_CONFIG2(IESO_OFF & FNOSC_PRI & FCKSM_CSDCMD & OSCIOFNC_OFF & IOL1WAY_ON & POSCMOD_EC)
_CONFIG3(WPCFG_WPCFGDIS & WPDIS_WPDIS)
void __attribute__ ((__interrupt__, no_auto_psv, __shadow__)) _T1Interrupt(void) {
timer_interrupt_function(); // Call millisec update routing
IFS0bits.T1IF = 0; // Clear interrupt flag
}
void timer_interrupt_function(void) {
MSECClock++; // Increment millisecond variable
TMR1 = 0xFFFF - TMR1msec; // Reset timer counter
}
void config_timers(void) {
/* Timer setup */
T1CON = 0x00; // Stop timer1, reset control reg
TMR1 = 0x00; // Clear timer register
PR1 = 0xFFFF; // Load the period register
IPC0bits.T1IP = 0x01; // Set timer1 interrupt priority level
IFS0bits.T1IF = 0; // Clear timer1 interrupt status flag
IEC0bits.T1IE = 1; // Enable Timer1 Interrupt
T1CONbits.TON = 1; // Start Timer1
}
void time_delay(unsigned int ms)
{
unsigned int timer = MSECClock; // Set local variable to present
// millisecond counter variable
while((MSECClock - timer) < ms) // Loop for ms milliseconds
{
;
}
}
config_timers();
// Start of main program
int main(void) {
// Loop forever
while (1) {
...
time_delay(50); // Wait 50 milliseconds
...
}
}
N1LAF- Charter Member
- Posts : 68
Join date : 2011-11-29
Re: PIC 24F processor programming experiences
Do you know Steven Bible? N7HPR. He is the guy with SuitSAT and Microchip design engineer. You need to get to know this guy if you don't already.N1LAF wrote:Our code should look like this:
- Code:
#include <p24FJ256GA1xx.h>
#include <stdlib.h>
#define CLOCKOSCFREQ 16 // Assuming usage of external 16 Mhz Osc
#define TMR1msec CLOCKOSCFREQ*500
void config_timers(void);
void time_delay(unsigned int ms);
unsigned int MSECClock = 0;
// Configuration for PIC24F
_CONFIG1(JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF & WINDIS_OFF & ICS_PGx1)
_CONFIG2(IESO_OFF & FNOSC_PRI & FCKSM_CSDCMD & OSCIOFNC_OFF & IOL1WAY_ON & POSCMOD_EC)
_CONFIG3(WPCFG_WPCFGDIS & WPDIS_WPDIS)
void __attribute__ ((__interrupt__, no_auto_psv, __shadow__)) _T1Interrupt(void) {
timer_interrupt_function(); // Call millisec update routing
IFS0bits.T1IF = 0; // Clear interrupt flag
}
void timer_interrupt_function(void) {
MSECClock++; // Increment millisecond variable
TMR1 = 0xFFFF - TMR1msec; // Reset timer counter
}
void config_timers(void) {
/* Timer setup */
T1CON = 0x00; // Stop timer1, reset control reg
TMR1 = 0x00; // Clear timer register
PR1 = 0xFFFF; // Load the period register
IPC0bits.T1IP = 0x01; // Set timer1 interrupt priority level
IFS0bits.T1IF = 0; // Clear timer1 interrupt status flag
IEC0bits.T1IE = 1; // Enable Timer1 Interrupt
T1CONbits.TON = 1; // Start Timer1
}
void time_delay(unsigned int ms)
{
unsigned int timer = MSECClock; // Set local variable to present
// millisecond counter variable
while((MSECClock - timer) < ms) // Loop for ms milliseconds
{
;
}
}
config_timers();
// Start of main program
int main(void) {
// Loop forever
while (1) {
...
time_delay(50); // Wait 50 milliseconds
...
}
}
N9XR- Charter Member
- Posts : 67
Join date : 2013-09-17
Age : 66
Location : Oregon, IL
Page 1 of 1
Permissions in this forum:
You cannot reply to topics in this forum
|
|