Saturday, August 27, 2011

My experiment with PIC18F4550 and Graphic LCD interface using MikroC Compiler

In this post i have tested MikroC built-in Graphic LCD Library functions with the example they provide in the help section. I had to make slight changes to the code to run on my PIC18F4550 microcontroller. The original source code is for PIC18F887 which does not gets compiled for PIC18F4550 device.

I ran this code on internal 8.000Mhz oscillator. To run the cpu on internal oscillator one needs to set Oscillator to : INTOSC:USB-HS or to INTOSC:USB-XT. My Breadboard prototype circuit runs on USB power, As i use a home built USB connector to get +5v dc from USB interface.

Configuraion:


Schematics:

Video:




Source Code:

// Glcd module connections
char GLCD_DataPort at PORTD;

sbit GLCD_CS1 at RB0_bit;
sbit GLCD_CS2 at RB1_bit;
sbit GLCD_RS at RB2_bit;
sbit GLCD_RW at RB3_bit;
sbit GLCD_EN at RB4_bit;
sbit GLCD_RST at RB5_bit;

sbit GLCD_CS1_Direction at TRISB0_bit;
sbit GLCD_CS2_Direction at TRISB1_bit;
sbit GLCD_RS_Direction at TRISB2_bit;
sbit GLCD_RW_Direction at TRISB3_bit;
sbit GLCD_EN_Direction at TRISB4_bit;
sbit GLCD_RST_Direction at TRISB5_bit;
// End Glcd module connections

void delay2S(){ // 2 seconds delay function
Delay_ms(2000);
}

void main() {
unsigned short ii;
char *someText;

#define COMPLETE_EXAMPLE // comment this line to make simpler/smaller example
CMCON = 0x07; // Disable comparators
ADCON1 = 0x0F; // Disable Analog functions
OSCCON = 0x70; // configures oscillator divider for 8MHz int. oscillator

Glcd_Init(); // Initialize GLCD
Glcd_Fill(0x00); // Clear GLCD

while(1) {
Glcd_Fill(0x00); // Clear GLCD
Glcd_Box(62,40,124,56,1); // Draw box
Glcd_Rectangle(5,5,84,35,1); // Draw rectangle
Glcd_Line(0, 0, 127, 63, 1); // Draw line
delay2S();

for(ii = 5; ii < 60; ii+=5 ){ // Draw horizontal and vertical lines
Delay_ms(250);
Glcd_V_Line(2, 54, ii, 1);
Glcd_H_Line(2, 120, ii, 1);
}

delay2S();

Glcd_Fill(0x00); // Clear GLCD
#ifdef COMPLETE_EXAMPLE
Glcd_Set_Font(Font_Glcd_Character8x7, 8, 7, 32); // Choose font, see __Lib_GLCDFonts.c in Uses folder
#endif
Glcd_Write_Text("mikroE", 1, 7, 2); // Write string

for (ii = 1; ii <= 10; ii++) // Draw circles
Glcd_Circle(63,32, 3*ii, 1);
delay2S();

Glcd_Box(12,20, 70,57, 2); // Draw box
delay2S();

#ifdef COMPLETE_EXAMPLE
Glcd_Fill(0xFF); // Fill GLCD

Glcd_Set_Font(Font_Glcd_Character8x7, 8, 7, 32); // Change font
someText = "8x7 Font";
Glcd_Write_Text(someText, 5, 0, 2); // Write string
delay2S();

Glcd_Set_Font(Font_Glcd_System3x5, 3, 5, 32); // Change font
someText = "3X5 CAPITALS ONLY";
Glcd_Write_Text(someText, 60, 2, 2); // Write string
delay2S();

Glcd_Set_Font(Font_Glcd_System5x7, 5, 7, 32); // Change font
someText = "5x7 Font";
Glcd_Write_Text(someText, 5, 4, 2); // Write string
delay2S();

Glcd_Set_Font(Font_Glcd_5x7, 5, 7, 32); // Change font
someText = "5x7 Font (v2)";
Glcd_Write_Text(someText, 50, 6, 2); // Write string
delay2S();
#endif
}
}

Thursday, August 25, 2011

PIC18F2550 and PWM Experiment, using MikroC Pro for PIC

As the title suggest this experiment tests Microchips PIC18F2550 Microcontroller and its PWM Peripheral. The Code presented here turns on led connected at pin 13 (RC2/CCP1) of the PIC18F4550 with 0% brightness and then gradually increases the brightness upto 100% with change in the duty cycle by calling PWM1_Set_Duty (duty) function by increasing duty variable after every 10 mili sec.

Schematics:


PWM Library Functions Description:
There are following 4 functions provided by MikroC Compiler which lets you control PIC microcontroller's PWM Channel.

1. PWM1_Init (const long freq)
This routine needs to be called before using other functions from PWM Library.
Takes "freq" parameter as frequency in hertz, and initializes the PIC microcontroller's PWM channel.
All PWM modules use Timer2 for its operation, so you can not set different frequencies for different PWM modules.

2. void PWM1_Set_Duty(unsigned short duty_ratio)
Sets PWM duty ratio. Parameter duty takes values from 0 to 255, where 0 is 0%, 127 is 50%, and 255 is 100% duty ratio. Other specific values for duty ratio can be calculated as (Percent*255)/100.

3. void PWM1_Start(void)
The function returns nothing and takes no input parameter. This function starts PWM.
4. void PWM1_Stop(void)
The function returns nothing and takes no input parameter. This function stops PWM.

The source code presented here runs on internal 8.000Mhz built-in oscillator.

Configuration:

Source Code:

void main()
{
unsigned char duty = 0;
OSCCON = 0x70; // configures oscillator divider for 8MHz int. oscillator
PORTC = 0; // sets port c to all 0
TRISC = 0; //configures port c as output port
PWM1_Init (5000); // sets pwm frequency to 5000Hz
PWM1_Start(); // starts pwm1 peripheral

while (1)
{
PWM1_Set_Duty(duty); // sets duty cycle
duty++; // increments duty cycle by 1
Delay_ms(10); // adds 10 msec delay
}
}

Video 1: Showing signal observed at pin 13 (RC2/CCP1) changing duty cycle from 0% to 100% in a loop.




Video 2: Showing LED changing its brightness from 0% to 100% in a loop




Conclusion: PIC microcontroller's PWM peripheral is very easy to program using MikroC Library.


Sunday, August 21, 2011

My experiement with PIC18F2550 and Character Type LCD, using MikroC Pro for PIC

This weekend i wanted to test a character type LCD library supplied with MikroC Pro for PIC. I ran the LCD code on PIC18F2550 device. I ran my PIC18F2550 Device using internal oscillator. To correctly run PIC on internal oscillator, i selected oscillator to INTOSC:USB+HS or INTOSC:USB+XT from the Project Settings Dialog box (which can be accessed by pressing CTRL+SHIF+E in MikroC). To run the microcontroller on internal 8.000mhz clock i also added following statement to my C code:

OSCCON = 0x70; // configures oscillator divider for 8MHz int. oscillator


Schematics:


Picture of my assembled circuit:


MikroC Project Settings




Source Code:

// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;

// End LCD module connections

char txt1[] = "mikroElektronika";
char txt2[] = "EasyPIC6";
char txt3[] = "Lcd4bit";
char txt4[] = "example";

char i; // Loop variable

void Move_Delay() { // Function used for text moving
Delay_ms(250); // You can change the moving speed here
}

void main(){
CMCON = 0x07; // Disable comparators
ADCON1 = 0x0F; // Disable Analog functions
OSCCON = 0x70; // configures oscillator divider for 8MHz int. oscillator

Lcd_Init(); // Initialize LCD

Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
Lcd_Out(1,6,txt3); // Write text in first row

Lcd_Out(2,6,txt4); // Write text in second row
Delay_ms(2000);
Lcd_Cmd(_LCD_CLEAR); // Clear display

Lcd_Out(1,1,txt1); // Write text in first row
Lcd_Out(2,5,txt2); // Write text in second row

Delay_ms(2000);

// Moving text
for(i=0; i<4; i++) { // Move text to the right 4 times
Lcd_Cmd(_LCD_SHIFT_RIGHT);
Move_Delay();
}

while(1) { // Endless loop
for(i=0; i<8; i++) { // Move text to the left 7 times
Lcd_Cmd(_LCD_SHIFT_LEFT);
Move_Delay();
}

for(i=0; i<8; i++) { // Move text to the right 7 times
Lcd_Cmd(_LCD_SHIFT_RIGHT);
Move_Delay();
}
}
}


Conclusion: Using MikroC built-in LCD library it is very quick and easy to run character type LCDs.