PIC18F4550 USB…….? It Really Worth!

Welcome back guys;

I have developed a USB device with LPC2148 ARM7  Watch Here microcontroller for data acquisition, thats pretty good than PIC18F.  There are many problems in PIC18F4550.

A friend of mine developed a temperature heater control with pic18f4550. He designed it successfully but when he tested with 5 PC ‘s, only 3Pc’c  worked correctly out of 5.

If you are planning to use USB Connectivity PIC18F4550  for industrial and precise control i personally not recommended, rather go for PIC24F or 32 series there are really good.



Timer0 Programming

Hello Guys;

Happy to see you back again, to check how to program timer.

We need to do some mathematical calculation to configure the timer. Lets see how.

Clock Source : 20MHZ.

so FCPU = Clock/4                           (20Mhz/4)

FCUP = 5MHZ.

Time Period= 1/FCPU                   (1/5MHZ)

Time Period = 0.2uS.

Prescaler = 256.

Prescaler Period = 0.2us * 256

Prescaler Period= 51.2us

Overflow Period = 51.2us * 256 = 13107.2us

Overflow Period = 0.013107 S

For 1 Sec time delay we need 1/0.013107

1 Sec = 76.29 Overflow.

The best way to understand the working of timer is Led Blinking. We are going to program to blink a led every 1Sec (76 Overflow).

Registers Configuration:

T0CON is Timer0 register. we need to configure it according to our calculation.

Prescaler: Bit 0 to 2 are prescaler selection. we need to configure according to table.

T0PS0=1; //Prescaler is divide by 256
T0PS1=1;
T0PS2=1;

PSA: we need to low  this bit, so that it will take prescaler select bit.

PSA=0;  //Timer Clock Source is from Prescaler

T0CS: Timer source select bit.

T0CS=0;     //Prescaler gets clock from FCPU (5MHz)

T08BIT: To make timer work in 8 Bit mode or 16 Bit mode.

T08BIT=1;   //8 BIT MODE

TMR0ON: Timer0 ON/OFF Bit

TMR0ON=1;      //Now start the timer!

Now we need to configure the Timer interrupt,

Timer0 Interrupt:

TMR0IE=1;   //Enable TIMER0 Interrupt

Peripheral Interrupt:

PEIE=1;     //Enable Peripheral Interrupt

Global Interrupt:

GIE=1;      //Enable INTs globally

We have successfully configured the timer. lets built and test drive it.

SOURCE CODE:

#include <htc.h>

// PIC 18F4550 fuse configuration:
// Config word 1 (Oscillator configuration)
// 20Mhz crystal input scaled to 48Mhz and configured for USB operation
__CONFIG(1, USBPLL & IESODIS & FCMDIS & HSPLL & CPUDIV1 & PLLDIV5);
// Config word 2
__CONFIG(2, VREGEN & PWRTDIS & BOREN & BORV20 & WDTDIS & WDTPS32K);
// Config word 3
__CONFIG(3, PBDIGITAL & LPT1DIS & MCLREN);
// Config word 4
__CONFIG(4, XINSTDIS & STVREN & LVPDIS & ICPORTDIS & DEBUGDIS);
// Config word 5, 6 and 7 (protection configuration)
__CONFIG(5, UNPROTECT);
__CONFIG(6, UNPROTECT);
__CONFIG(7, UNPROTECT);

unsigned char counter=0;//Overflow counter

void main()
{
//Setup Timer0
T0PS0=1; //Prescaler is divide by 256
T0PS1=1;
T0PS2=1;

PSA=0;      //Timer Clock Source is from Prescaler

T0CS=0;     //Prescaler gets clock from FCPU (5MHz)

T08BIT=1;   //8 BIT MODE

TMR0IE=1;   //Enable TIMER0 Interrupt

PEIE=1;     //Enable Peripheral Interrupt

GIE=1;      //Enable INTs globally

TMR0ON=1;      //Now start the timer!

//Set RC1 as output because we have LED on it

TRISC=TRISC&0C11111101;

while(1);
}

void interrupt ISR()
{
//Check if it is TMR0 Overflow ISR

if(TMR0IE && TMR0IF)
{
//TMR0 Overflow ISR
counter++;  //Increment Over Flow Counter

if(counter==76)
{
//Toggle RB1 (LED)

if(RC1==0)
RC1=1;
else
RC1=0;

counter=0;  //Reset Counter

}

//Clear Flag
TMR0IF=0;
}
}

You can download Project Here

Timer In PIC18f4550

Welcome Back;

Sorry guys i was busy with my office work, currently developing device driver for USB. I will try to update my blog regularly.

This tutorial is all about timer in PIC18f4550. Timers are common features of all microcontroller. In simplified terms a timer is a register whose value keeps increasing or decreasing  by a constant rate without the help of the CPU.

The Timer register can have the following bit length

* 8 bit timers – These can count between between 0-255
* 16 bit timers – These can count between 0-65536
* 32 bit timers – These can count between 0-4294967296

Timers are also called Counters this is because they can be used to count external events.

This clock source for the timer is obtained from the CPU clock, which ranges from 1Mhz to 24Mhz. At this high frequency operation how can a clock run in real time ? you can’t see the blades of  fan while its running at 50 HZ.

Ans: You might have heard about prescaler, the main purpose of prescaler is to divide the CPU clock to obtain smaller frequency. The prescaler divides the clock in a defined factor  (i.e) 1, 2, 4, 8, 16, 32, 64, 128, 256.

Overflow:
An overflow occurs when a timer register has already counted the maximum value it can count. At overflow the counter value become 0 again. For example when an 8 bit timer has the value 255 and receive another clock that will set it to 0 and generate an overflow. An overflow can trigger an interrupt and the ISR can handle it.

Interrput’s Programming

Welcome Back.,

Hope you read my previous post. Now we are entering to programming part.

Syntax :

void interrupt Function Name(void)

{

// Your Code

}

Example :

void interrupt ISR()

{

// Your Code

}

Now look at first line void interrupt ISR().

1. my function name is ISR. you can use any name  as you like.

2. The interrupt function must always be void.

I am going to explain about two most popular interrupt, Timer Interrupt and External Interrupt. The other interrupt are very easy to use compared to these interrupts.

External Interrupt:

Register to be configured for external interrupt:

We are going to configure Interrupt Zero (INT0) for external interrupt. Two registers are responsible for external interrupt.

1.INTCON

2.INTCON2


INTCON: INTERRUPT CONTROL REGISTER

This register are responsible for enabling the interrupt.


INTCON=0b10011000; Hope you can understand this code.

We need to configure  GIE, PEIE, INT0IE, RBIE, INTOIF. Read the above image for description.

INTCON2:

INTEDG0 and RBPU registers have to be configures. so INTCON2 have to be configured aINTCON2=0b10000000;

So this  will enable the interrupt in falling edge.

PROGRAMMING:

#include <htc.h>

#include “delay.h”

static void Port_Config(void);

// PIC 18F4550 fuse configuration:

// Config word 1 (Oscillator configuration)

// 20Mhz crystal input scaled to 48Mhz and configured for USB operation

__CONFIG(1, USBPLL & IESODIS & FCMDIS & HSPLL & CPUDIV1 & PLLDIV5);

// Config word 2

__CONFIG(2, VREGEN & PWRTDIS & BOREN & BORV20 & WDTDIS & WDTPS32K);

// Config word 3

__CONFIG(3, PBDIGITAL & LPT1DIS & MCLREN);

// Config word 4

__CONFIG(4, XINSTDIS & STVREN & LVPDIS & ICPORTDIS & DEBUGDIS);

// Config word 5, 6 and 7 (protection configuration)

__CONFIG(5, UNPROTECT);

__CONFIG(6, UNPROTECT);

__CONFIG(7, UNPROTECT);

void interrupt my_isr(void)

{

INT0IF=0; //clear flag

PORTD=~PORTD;//toggle led to indicate interrupt.

DelayMs(255);

}

void int_init()

{

INTCON=0b10011000;

INTCON2=0b10000000;

/*INT0IF=0; //clear external interrupt flag.

INT0IE=1; //enable external interrupt 1 on B1.

IPEN=0; //peripheral enable bit set false

RBPU=0; //turn off pull-ups

INTEDG0=0; //active on falling edge

GIE=1; //global interrupt enable on*/

}

void main()

{

Port_Config();

int_init();

while(1)

{

PORTC=1; //this code toggles an LED on Port C

DelayMs(255);

PORTC=0;

DelayMs(255);

}

}

// Initialise system

static void Port_Config(void)

{

ADCON1 = 0x0F; // Default all pins to digital

// Configure ports as inputs (1) or outputs(0)

TRISA = 0b00000000;

TRISB = 0b00000001; // Interrupt0 has been set as input.

TRISC = 0b00000000;

TRISD = 0b00000000;

TRISE = 0b00000000;

// Clear all ports

PORTA = 0b00000000;

PORTB = 0b00000000;

PORTC = 0b00000000;

PORTD = 0b00000000;

PORTE = 0b00000000;

}

Hope you can understand this program.

You can download project source code here.

If you  have any query mail me.

Happy Learning……



Interrupts ! “Oh My God”

Interrupts are common features in almost all processor family, right from very old 8051 to x64 processors. So what it is?

WHAT IS INTERRUPT :

Interrupts, as the name suggests interrupts the normal execution of CPU and request immediate attention of CPU.

The PIC18F4550  have multiple interrupt sources and an interrupt priority feature that allows each interrupt source to be assigned a high priority level or a low priority level.

High priority interrupt events will interrupt any low priority interrupts that may be in progress.

TYPE’S OF INTERRUPT’S :

• External Interrupts
• TIMER Interrupts
• ADC Interrupt
• Peripheral Interrupt (USART, USB,SPI,IIC)

REGISTER’S TO CONTROL INTERRUPT :

There are ten registers which are used to control interrupt operation. These registers are

• RCON
• INTCON
• INTCON2
• INTCON3
• PIR1, PIR2
• PIE1, PIE2
• IPR1, IPR2

Each interrupt source has three bits to control its operation. The functions of these bits are:

• Flag bit : To indicate that an interrupt event occurred
• Enable bit : That allows program execution to branch to the interrupt vector address when the flag bit is set.
• Priority bit : To select high priority or low priority

In global level their are following bits to control the interrupts globally.

• GIE : Global Interrupt Enable, enables/disables interrupts globally.
• PEIE :  Enable/disable all peripheral interrupts.

Analog To Digital Converter Programming

 

Welcome back,

Hope you have read my previous post. There are three register which control ADC operation.

ADCON0 :

check out the image

To select the adc channel assign values to CHSo to CHS3 as per table. ADON register should be enabled. Go/Done Register is a status register for ADC conversion.

This ADCON0 register is used to enable ADC and to select ADC channel

ADCON1 :


This register is used to set voltage reference and port configuration. Bit 4 &  5 register are used to set reference voltage. Bit 0 to 3 register is used for port configuration. ie if you want to use single pin of PortA as analog and other as digital you must configure this register as per table.

ADCON2:

This is the most important register of ADC. Bit7 ADFM , is used to justify result, ie  if our result is 1001, if ADFM is right justified the output will be 00001001. is left justified then 10010000.

Acquisition Time: ACQT0 to ACQT2

When an specific channel is selected the voltage from that input channel is stored in an internal holding capacitor. It takes some time for the capacitor to get fully charged and become equal to the applied voltage. This time is called acquisition time. Will be explained in detail .

ADC Clock Select:

ADCS0 to ADCS2 are the registers used to select clock source.

You may see that ADC clock period is 0.7us, for better ADC operation you must select value of ADCS greater than 0.7us.

Consider you are using 20Mhz crystal. T=1/F;

Time period= 1/20Mhz =50ns.

32 X Tsoc = 32x 50ns= 1.6us. [ 16 x Tsoc = 0.8us, dont choose very close because external crystal will not provide very accurate clock , so its better to choose  32 x Tsoc]

Now to select acquisition time it must be greater than minimum acquisition time ie 2.4us.

we need to select Acquisition time ,

2 x TAD = 2 x 1.6us =3.2us. this is greater then minimum acquisition time.

we need to configure ADCON2=0b10001010; for 20mhz clock .

Lets do some programming.

 

void Adc_Init()

{

ADCON0=0b00000000; // select channel AN0

ADCON1=0b00001110; // Select An0 s analog and rest pins as digital

ADCON2=0b10001010;

ADON=1;  //switch on the adc module

GODONE=1;  //Start conversion

}

 

void Adc_Read();

{

while(GODONE){

ADON=0;

return ADRES;

}

}

void main(){
//Let the LCD Module start up
Wait(100);

//Initialize the LCD Module
LCDInit(LS_BLINK);

//Initialize the ADC Module

Adc_Init();

//Clear the Module
LCDClear();

//Write a string at current cursor pos
LCDWriteString(“ADC Test”);

while(1)
{
unsigned int val; //ADC Value

val=Adc_Read(1);   //Read Channel 1
LCDWriteIntXY(0,1,val,4);

Wait(1000);
}

}

I had developed a simple ADC library, you can download the entire project in Mplab Here
Hope you have enjoyed this tutorial. Bye