Menu

all about electronic and microcontrollers

Tuesday, December 14, 2010

Lesson nr.20-Sound generation

Hardware setup:


Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:


Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.20:
'          Sound generation.
'  Done by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will work with sounds.
'          I'll show how to generate and make sound helped by microcontroller 
'          and some buttons.
'          Communication with the buzzer will be performed  at PORT RB3 ( as PWM mode).
'          The Push buttons are connected to PORT RA4 (generates Tone1), RA6
'          (generates Tone2) and RA7(generates melody2). 
'          Of course we need pull-up resistors (4k7 is required).
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
void Tone1()
{
 Sound_Play(5000, 1000);         // Frequency = 659Hz, duration = 250ms
}

void Tone2() 
{
 Sound_Play(4000, 1000);         // Frequency = 698Hz, duration = 250ms
 }

void Tone3() 
{
 Sound_Play(3000, 1000);         // Frequency = 784Hz, duration = 250ms
 }

void Melody1()                  // Make funny melody 1;
{
 Tone1(); Tone2(); Tone3();
 Tone3(); Tone2(); Tone1();
 Tone1(); Tone3(); Tone2();
 Tone3(); Tone2(); Tone1(); Tone3();
 Tone1(); Tone2(); Tone3();
 Tone3(); Tone1(); Tone2(); Tone2(); Tone1();
 }

void ToneA()                    // Tone A;
{
 Sound_Play(1618, 50);          // (frequency, duration)
}

void ToneB()                    // Tone B;
{
 Sound_Play(1918, 50);          // (frequency, duration)
}

void ToneC()                    // Tone C;
{
 Sound_Play(2212, 50);          // (frequency, duration)
}

void Melody2()                  // Make funny melody 2;
{
 unsigned short i;
 for (i = 12; i > 0; i--)
 {
  ToneA(); ToneB(); ToneC();
  }
 }

void main() 
{
 CMCON |=7;                     // Disable comparator
 TRISB = 0xF0;                  // Pins RB7-RB4 are configured as inputs,
                                // RB3 is configured as an output
 Sound_Init(&PORTB, 3);
 Sound_Play(5000,100);          // Start with this song (frequency, duration)

 while (1)                      // infinite loop
 {
  if (Button(&PORTA,4,1,0))     // RB4 generates Tone1
  Tone1();
  
  if (Button(&PORTA,6,1,0))     // RB6 generates Tone2
  Tone2();

  if (Button(&PORTA,7,1,0))     // RA7 generates melody 2
  {
   Melody2();
   Delay_ms(1500);              // Delay 1,5s
   Melody2();
   Delay_ms(1500);              // Delay 1,5s
   Melody2();
   }
  }
}

Lesson nr.19-Using Internal EEPROM Memory

Hardware setup:



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:


Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.19:
'          Using Internal EEPROM Memory.
'  Done by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will work with internal EEPROM Memory
'          and I'll show how to write and read information on it helped by a little
'          menu displayed on the LCD.
'          Communication with LCD will be performed through 4-bits and connections
'          is made as follows: D4 with RB0, D5 with RB1, D6 with RB2, D7 with RB3;
'                              RS with RB4 and EN with RB5.
'          The Push buttons are connected to PORT RA4 (for read), RA6(for write) and RA7
'          (for delete). Of course we need pull-up resistors (4k7 is required).
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
// LCD module connections
sbit LCD_RS at RB4_bit;                 // LCD_RS assigned to PORT RB4;
sbit LCD_EN at RB5_bit;                 // LCD_EN assigned to PORT RB5;
sbit LCD_D4 at RB0_bit;                 // LCD_D4 assigned to PORT RB0;
sbit LCD_D5 at RB1_bit;                 // LCD_D5 assigned to PORT RB1;
sbit LCD_D6 at RB2_bit;                 // LCD_D6 assigned to PORT RB2;
sbit LCD_D7 at RB3_bit;                 // LCD_D7 assigned to PORT RB3;

sbit LCD_RS_Direction at TRISB4_bit;    // LCD_RS assigned to TRIS B4;
sbit LCD_EN_Direction at TRISB5_bit;    // LCD_EN assigned to TRIS B5;
sbit LCD_D4_Direction at TRISB0_bit;    // LCD_D4 assigned to TRIS B0;
sbit LCD_D5_Direction at TRISB1_bit;    // LCD_D5 assigned to TRIS B1;
sbit LCD_D6_Direction at TRISB2_bit;    // LCD_D6 assigned to TRIS B2;
sbit LCD_D7_Direction at TRISB3_bit;    // LCD_D7 assigned to TRIS B3;
// End LCD module connections

// Define Messages
char message1[] = "Switch1: Read";
char message2[] = "Switch2: Write";
char message3[] = "Switch3: Erase";
char message4[] = "EEPROM_Write";
char message5[] = "EEPROM_Read ";
char message6[] = "EEPROM ERASED";
char message7[] = "Internal";
char message8[] = "EEPROM";
char message9[] = "*";
char message10[] = "**";
char message11[] = "***";

char digit[] = "00000000000000";
unsigned short  ii, All ;

void read_eeprom()
{
 if (Button(&PORTA, 4, 1, 0))           // Detect logical one to zero;
 {    
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Out(1,3,message5);
  Lcd_Out(2,7,message9);
  delay_ms(1000);                       // Delay 1s
  Lcd_Out(2,7,message10);
  delay_ms(1000);                       // Delay 1s
  Lcd_Out(2,7,message11);
  delay_ms(1000);                       // Delay 1s
  for (ii=0; ii<=13; ii++)
  {
   All = EEPROM_Read(0x00+ii);          // Start EEPROM Location,
   digit[ii] = All+65;                  // Look at ascii table
   }
  Lcd_Out(2,2,digit);
  delay_ms(5000);                       // Delay 5s
  }
 }

void write_eeprom()
{
 if (Button(&PORTA, 6, 1, 0))           // Detect logical one to zero
 {
  for (ii=0; ii<14; ii++)
  EEPROM_Write(0x00+ii,ii);
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Out(1,3,message4);
  Lcd_Out(2,7,message9);
  delay_ms(1000);
  Lcd_Out(2,7,message10);
  delay_ms(1000);
  Lcd_Out(2,7,message11);
  delay_ms(1000);
  }
 }

void delete_eeprom()
{
 if (Button(&PORTA, 7, 1, 0))           // Detect logical one to zero
 {     
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Out(1,3,message6);
  Lcd_Out(2,7,message9);
  delay_ms(1000);
  Lcd_Out(2,7,message10);
  delay_ms(1000);
  Lcd_Out(2,7,message11);
  delay_ms(1000);
  for (ii=0; ii<=13; ii++)
  EEPROM_Write(0x00+ii,0x0e);
  }
 }

void main() {
CMCON  |= 7;                            // Disable Comparators
TRISA4_bit = 1;
TRISA6_bit = 1;
TRISA7_bit = 1;
TRISB = 0;
PORTB = 0;
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);                    // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF);               // Cursor off
Lcd_Out(1,5,message7);
Lcd_Out(2,6,message8);
delay_ms(3000);                         // Delay 3s
do {
    Lcd_cmd(_LCD_Clear);
    Lcd_Out(1,2,message1);              // Write message1 in 1st row
    delay_ms(1000);
    read_eeprom();
    write_eeprom();
    delete_eeprom();
    Lcd_cmd(_LCD_Clear);
    Lcd_Out(1,2,message2);
    delay_ms(1000);
    read_eeprom();
    write_eeprom();
    delete_eeprom();
    Lcd_cmd(_LCD_Clear);
    Lcd_Out(1,2,message3);
    delay_ms(1000);
    read_eeprom();
    write_eeprom();
    delete_eeprom();
    } while(1);
}

Tuesday, November 30, 2010

Lesson nr.18-DS18X20 using 1-Wire Protocol & LCD

Hardware setup:
In this experiment we will work with temperature sensor DS18B20, but this time results will be displayed on 2x16 LCD.
Communication with LCD will be performed through 4-bits and connections is made as follows: D4 with RB0, D5 with RB1, D6 with RB2, D7 with RB3, RS with RB4 and EN with RB5.
Data pin of DS18B20 is connected to PORT RA1 and we also use pull-up resistors (4k7 ohm), for the communication with temperature sensor to be performed.
The range value wich can be measured, is between -55 and +128 Celsius degree.



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:


Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.18:
'          DS18X20 using 1-Wire Protocol & LCD.
'  Done by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will work with temperature sensor DS18B20 and LCD.
'          Communication with LCD will be performed through 4-bits and connections
'          is made as follows: D4 with RB0, D5 with RB1, D6 with RB2, D7 with RB3;
'                              RS with RB4 and EN with RB5.
'          Data pin of DS18B20 is connected to PORT RA1 and we also use pull-up 
'          resistors (4k7 ohm).
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
// 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
// Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
// 18S20:  9  (default setting; can be 9,10,11,or 12)
// 18B20: 12
const unsigned short TEMP_RESOLUTION = 12;

char *text = "000.0";
unsigned temp;

void Display_Temperature(unsigned int temp2write) 
{
 const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
 char temp_whole;
 unsigned int temp_fraction;
 unsigned short isNegative = 0x00;

 // Check if temperature is negative
 if (temp2write & 0x8000) 
 {
  text[0] = '-';
  temp2write = ~temp2write + 1;
  isNegative = 1;
  }

  // Extract temp_whole
  temp_whole = temp2write >> RES_SHIFT ;

  // Convert temp_whole to characters
  if (!isNegative){
  if (temp_whole/100)
  text[0] = temp_whole/100  + 48;
  else
  text[0] = '+';
  }
  text[1] = (temp_whole/10)%10 + 48;             // Extract tens digit
  text[2] =  temp_whole%10     + 48;             // Extract ones digit

  // Extract temp_fraction and convert it to unsigned int
  temp_fraction  = temp2write << (4-RES_SHIFT);
  temp_fraction &= 0x000F;
  temp_fraction *= 625;

  // Convert temp_fraction to characters
  text[4] =  temp_fraction/1000    + 48;         // Extract thousands digit
  
  // Print temperature on LCD
  Lcd_Out(2, 5, text);
}
  // Custom character for simbol " * " (degrees).
const char character[] = {4,10,4,0,0,0,0,0};
void CustomChar(char pos_row, char pos_char) 
{
 char i;
 Lcd_Cmd(64);
 for (i = 0; i<=7; i++) Lcd_Chr_CP(character[i]);
 Lcd_Cmd(_LCD_RETURN_HOME);
 Lcd_Chr(pos_row, pos_char, 0);
 }

void main()                                      // Main;
{
 CMCON |=7;                                      // Disable Comparators;
 Lcd_Init();                                     // Initialize LCD;
 Lcd_Cmd(_LCD_CLEAR);                            // Clear LCD;
 Lcd_Cmd(_LCD_CURSOR_OFF);                       // Turn cursor off;
 Lcd_Out(1, 3, "Temperature:");                  // Show message to LCD on line 1 from
                                                 // column 3;
 // Print degree character, 'C' for Centigrades
 CustomChar(2,10);                               // Display custom character (degree)
                                                 // on line 2 and column 10.

 Lcd_Chr(2,11,'C');                              // Show message to LCD on line 2 from
                                                 // column 11;

 //--- Main loop
 do 
 {
  //--- Perform temperature reading
  Ow_Reset(&PORTA, 1);                           // Onewire reset signal;
  Ow_Write(&PORTA, 1, 0xCC);                     // Issue command SKIP_ROM;
  Ow_Write(&PORTA, 1, 0x44);                     // Issue command CONVERT_T;
  Delay_us(700);                                 // delay 0,7s (required for signal
                                                 // processing);

  Ow_Reset(&PORTA, 1);                           // Onewire reset signal;
  Ow_Write(&PORTA, 1, 0xCC);                     // Issue command SKIP_ROM;
  Ow_Write(&PORTA, 1, 0xBE);                     // Issue command READ_SCRATCHPAD;

  temp = Ow_Read(&PORTA, 1);                     // Next Read Temperature, read Byte
                                                 // 0 from Scratchpad;
  temp = (Ow_Read(&PORTA, 1) << 8) + temp;       // Then read Byte 1 from Scratchpad
                                                 // and shift 8 bit left and add the Byte 0;

  //--- Format and display result on Lcd
  Display_Temperature(temp);                     // Call Display_Temperature;

  Delay_ms(400);                                 // 0,4s delay required to finish the process;
  } while (1);                                   // infinite loop;
}                                                // End.

Lesson nr.17-Alphanumeric LCD and Push Button

Hardware setup:
In this experiment we will work with alphanumeric LCD and push button.
Communication with LCD will be performed through 4-bits and connections is made as follows: D4 with RB0, D5 with RB1, D6 with RB2, D7 with RB3, RS with RB4 and EN with RB5. The Push button is connected to PORT RA4 (for increment) and PORT RA6 (for decrement). Of course both button have pull-up resistors (4k7).
To make this project more interesting , you can reach from 0000 to 9999 by pressing the button.



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:


Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.17:
'          Alphanumeric LCD and Push Button.
'  Done by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will work with alphanumeric LCD and push button.
'          Communication with LCD will be performed through 4-bits and connections
'          is made as follows: D4 with RB0, D5 with RB1, D6 with RB2, D7 with RB3;
'                              RS with RB4 and EN with RB5.
'          The Push button is connected to PORT RA4 (for increment) and PORT RA6
'          (for decrement). Of course both button have pull-up resistors (4k7).
'          To make this project more interesting , you can reach from 0000 to 9999 
'          by pressing the button.
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
// LCD module connections
sbit LCD_RS at RB4_bit;                 // LCD_RS assigned to PORT RB4;
sbit LCD_EN at RB5_bit;                 // LCD_EN assigned to PORT RB5;
sbit LCD_D4 at RB0_bit;                 // LCD_D4 assigned to PORT RB0;
sbit LCD_D5 at RB1_bit;                 // LCD_D5 assigned to PORT RB1;
sbit LCD_D6 at RB2_bit;                 // LCD_D6 assigned to PORT RB2;
sbit LCD_D7 at RB3_bit;                 // LCD_D7 assigned to PORT RB3;

sbit LCD_RS_Direction at TRISB4_bit;    // LCD_RS assigned to TRIS B4;
sbit LCD_EN_Direction at TRISB5_bit;    // LCD_EN assigned to TRIS B5;
sbit LCD_D4_Direction at TRISB0_bit;    // LCD_D4 assigned to TRIS B0;
sbit LCD_D5_Direction at TRISB1_bit;    // LCD_D5 assigned to TRIS B1;
sbit LCD_D6_Direction at TRISB2_bit;    // LCD_D6 assigned to TRIS B2;
sbit LCD_D7_Direction at TRISB3_bit;    // LCD_D7 assigned to TRIS B3;
// End LCD module connections

char Message1[]="LCD and Button";       // Message for line1;
unsigned int number = 0;

char *digit = "0000";

void Display_init()   // define display_init;
{                    
 digit[0] = number/1000 + 48;           // thousands digit;
 digit[1] = (number/100)%10 +48;        // hundreds digit;
 digit[2] = (number/10)%10 + 48;        // tens digit;
 digit[3] = number%10 +48;              // unit digit;
 Lcd_Out(2,7,digit);                    // display on LCD from column 2, character 7;
}

void main()                             // main;
{
 CMCON |= 7;                            // turn off analogue comparator and make PORTA to digital I/O;
 TRISA6_bit = 1;                        // make PORT RA6 as input for button;
 TRISA7_bit = 1;                        // make PORT RA7 as input for button;
 PORTA = 0;                             // Turn ON PORTA;
 TRISB = 0;                             // Set PORTB direction to be output;
 PORTB = 0;                             // Turn ON PORTB;

 Lcd_init();                            // LCD Initialization;
 Lcd_cmd(_LCD_CLEAR);                   // Clear LCD;
 Lcd_cmd(_LCD_CURSOR_OFF);              // Cursor mode, off;
 Lcd_out(1,2,Message1);                 // display message1 from column 1, character 3;

 do{
    if(Button(&PORTA,4,1,0)){
                             Delay_ms(200);    // If button is pressed, delay 0,2s and increment "number" with 1;
                             number = number +1;
                             }
    if(Button(&PORTA,6,1,0)){
                             Delay_ms(200);    // If button is pressed, delay 0,2s and decrement "number" with 1;
                             number = number -1;
                             }
    if (number > 9999u)                 // if it's more than 9999 go to 0;
    number = 0;
    display_init();                     // call display_init();
    } while(1);                         // infinite loop;
 }                                      // end.

Lesson nr.16-Alphanumeric LCD as counter mode

Hardware setup:
The communication technique with the LCD is the same like the last lesson, and for the current experiment we have added a counter which counts between 0000 and 9999. Our counter increments with 1 second delay.
The connections with LCD is made as follows: D4 with RB0, D5 with RB1, D6 with RB2, D7 with RB3, RS with RB4 and EN with RB5.



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:


Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.16:
'          Alphanumeric LCD as counter mode.
'  Done by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will work with alphanumeric LCD. Communication
'          with LCD will be performed through 4-bits and connections is made as
'          follows: D4 with RB0, D5 with RB1, D6 with RB2, D7 with RB3;
'                   RS with RB4 and EN with RB5.
'          To make this project more interesting , a counter is added
'          (counts from 0000 to 9999) with a delay of 1 secunde.
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
// LCD module connections
sbit LCD_RS at RB4_bit;                 // LCD_RS assigned to PORT RB4;
sbit LCD_EN at RB5_bit;                 // LCD_EN assigned to PORT RB5;
sbit LCD_D4 at RB0_bit;                 // LCD_D4 assigned to PORT RB0;
sbit LCD_D5 at RB1_bit;                 // LCD_D5 assigned to PORT RB1;
sbit LCD_D6 at RB2_bit;                 // LCD_D6 assigned to PORT RB2;
sbit LCD_D7 at RB3_bit;                 // LCD_D7 assigned to PORT RB3;

sbit LCD_RS_Direction at TRISB4_bit;    // LCD_RS assigned to TRIS B4;
sbit LCD_EN_Direction at TRISB5_bit;    // LCD_EN assigned to TRIS B5;
sbit LCD_D4_Direction at TRISB0_bit;    // LCD_D4 assigned to TRIS B0;
sbit LCD_D5_Direction at TRISB1_bit;    // LCD_D5 assigned to TRIS B1;
sbit LCD_D6_Direction at TRISB2_bit;    // LCD_D6 assigned to TRIS B2;
sbit LCD_D7_Direction at TRISB3_bit;    // LCD_D7 assigned to TRIS B3;
// End LCD module connections

char Message1[]="Counter Mode";         // Message for line1;
unsigned int number = 0;

char *digit = "0000";

void Display_init()   // define display_init;
{                    
 digit[0] = number/1000 + 48;           // thousands digit;
 digit[1] = (number/100)%10 +48;        // hundreds digit;
 digit[2] = (number/10)%10 + 48;        // tens digit;
 digit[3] = number%10 +48;              // unit digit;
 Lcd_Out(2,7,digit);                    // display on LCD from column 2, character 7;
}

void main()                             // main;
{
 CMCON |= 7;                            // turn off analogue comparator and make PORTA to digital I/O;
 Lcd_init();                            // LCD Initialization;
 Lcd_cmd(_LCD_CLEAR);                   // Clear LCD;
 Lcd_cmd(_LCD_CURSOR_OFF);              // Cursor mode, off;
 Lcd_out(1,3,Message1);                 // display message1 from column 1, character 3;

 do{
    display_init();                     // call display_init();
    delay_ms(1000);                     // delay 1s;
    number ++;                          // Increment number;
    if (number > 9999u)                 // if it's more than 9999 go to 0;
    number = 0;
    } while(1);                         // infinite loop;
 }                                      // end.

Thursday, November 4, 2010

Cadsoft Eagle Cad

The EAGLE Layout Editor is an easy to use, yet powerful tool for designing printed circuit boards (PCBs). The name EAGLE is an acronym, which stands for " Easily Applicable Graphical Layout Editor".
The program consists of three main modules: 
  • Layout editor;
  • Schematic editor;
  • Autorouter.
which are embedded in a single user interface. Therefore there is no need for converting netlists between schematics and layouts.

And now I will present a tutorial consisting of 11 lessons:
























Sunday, October 17, 2010

Lesson nr.15-Alphanumeric LCD in 4-bit mode

Hardware setup:
The purpose of this experiment is to interface an LCD 2x16 characters (compatible with standard HD44780) to PIC16F628A in 4-bit mode. This means the data transfer will use just 4 pins of the microcontroller. No additional hardware configuration is required. In the current experiment we are displaying a text, on the 2 x16 LCD. The circuit diagram is presented below.













Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:


Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.15:
'          Alphanumeric LCD in 4-bit mode.
'  Done by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will work with alphanumeric LCD. Communication 
'          with LCD will be performed through 4-bits and connections is made as
'          follows: D4 with RB0, D5 with RB1, D6 with RB2, D7 with RB3;
'                   RS with RB4 and EN with RB5.
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
// 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

// Define Messages
 char text1[] = "Testing LCD";
 char text2[] = "using PIC16F628A";
 char text3[] = "Test successful";
 char text4[] = "in 4-bit mode";
 
void main() {
  Lcd_Init();                        // Initialize LCD
  do {
      Lcd_Cmd(_LCD_CLEAR);           // Clear display
      Lcd_Cmd(_LCD_CURSOR_OFF);      // Cursor off
      Lcd_Out(1,3,text1);            // Write message1 in 1st row
      Lcd_Out(2,1,text2);            // Write message1 in 2nd row
      Delay_ms(3000);                // delay 3s
      Lcd_Cmd(_LCD_CLEAR);           // Clear display
      Delay_ms(1000);                // delay 1s
      Lcd_Out(1,2,text3);            // Write message3 in 1st row
      Lcd_Out(2,3,text4);
      Delay_ms(3000);                // delay 3s
      } while(1);
}

Lesson nr.14-DS18B20 using 1-Wire Protocol & 7seg

Hardware setup:
In this Lesson, we will make a digital temperature meter using DS18B20. The connection between temperature sensor and microcontroller will be done through a single wire. This is advantage of the temperature sensor model. The temperature value will be displayed on 4 digits-with 7 segment, in multiplexed mod of course.
PORTB will be used for character (RB0=a, RB1=b...RB6=g, RB7=dp) and for digits RA0 = digit1...RA3 = digit4. Data wire from DS18B20 is conected to RA4.
Pull-up resistor (with a value of 4.7 k), is required to perform communication between the sensor and microcontroller.











Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:



Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.14:
'          Digital thermometer with DS18B20 and 7- Segments.
'  Done by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will work with one-wire communication.
'          The thermal sensor used is "DS18B20" and measured value is displayed 
'          on the 7-segment digits. PORTB will be used for character
'          (RB0=a,RB1=b...RB6=g,RB7=dp)and for digits RA0=digit1...RA3=digit4.
'          Data wire from DS18B20 is conected to RA4.
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
unsigned short i, DD0=0x40, DD1=0x40,DD2=0x40, DD3 =0x61, N_Flag;
unsigned temp_value=0;                         // Variable to store temperature register value
unsigned short mask(unsigned short num)        // Mask for 7 segment common cathode;
{
 switch (num)
 {
  case 0 : return 0x3F;           // 0;
  case 1 : return 0x06;           // 1;
  case 2 : return 0x5B;           // 2;
  case 3 : return 0x4F;           // 3;
  case 4 : return 0x66;           // 4;
  case 5 : return 0x6D;           // 5;
  case 6 : return 0x7D;           // 6;
  case 7 : return 0x07;           // 7;
  case 8 : return 0x7F;           // 8;
  case 9 : return 0x6F;           // 9;
  case 10 : return 0x40;          // Symbol '-'
  case 11 : return 0x61;          // Symbol C
  case 12 : return 0x00;          // Blank
  } //case end
}

void display_temp(short DD0, short DD1, short DD2, short DD3)
{
 for (i = 0; i<=4; i++)
 {
  PORTB = DD3;
  RA0_bit = 1;                    // Select C Digit;
  RA1_bit = 0;
  RA2_bit = 0;
  RA3_bit = 0;
  delay_ms(2);
  PORTB = DD0;
  RA0_bit = 0;
  RA1_bit = 1;                    // Select Ones Digit;
  RA2_bit = 0;
  RA3_bit = 0;
  delay_ms(2);
  PORTB = DD1;
  RA0_bit = 0;
  RA1_bit = 0;
  RA2_bit = 1;                    // Select Tens Digit;
  RA3_bit = 0;
  delay_ms(2);
  PORTB = DD2;
  RA0_bit = 0;
  RA1_bit = 0;
  RA2_bit = 0 ;
  RA3_bit = 1;                    // Select +/- Digit;
  delay_ms(2);
  }return;
}

void DS18B20()                              //Perform temperature reading
{
 Display_temp(DD0, DD1, DD2, DD3);
 Ow_Reset(&PORTA, 4);                       // Onewire reset signal
 Ow_Write(&PORTA, 4, 0xCC);                 // Issue command SKIP_ROM
 Ow_Write(&PORTA, 4, 0x44);                 // Issue command CONVERT_T
 Display_temp(DD0, DD1, DD2, DD3);
 Ow_Reset(&PORTA, 4);
 Ow_Write(&PORTA, 4, 0xCC);                 // Issue command SKIP_ROM
 Ow_Write(&PORTA, 4, 0xBE);                 // Issue command READ_SCRATCHPAD
 Display_temp(DD0, DD1, DD2, DD3);
 // Next Read Temperature
 temp_value =  Ow_Read(&PORTA, 4);          // Read Byte 0 from Scratchpad
 temp_value = (Ow_Read(&PORTA, 4) << 8) + temp_value;       // Then read Byte 1 from
                                                            // Scratchpad and shift
                                                            // 8 bit left and add the Byte 0
 if (temp_value & 0x8000) {
                           temp_value = ~temp_value + 1;
                           N_Flag = 1;      // Temp is -ive
                           }
 if (temp_value & 0x0001) temp_value += 1;  // 0.5 round to 1
 temp_value = temp_value >> 4 ;      //<<<  // 1 for DS1820 and
                                            // 4 for DS18B20;
 }

void main()
{
 CMCON  |= 7;                               // Disable Comparators
 TRISB = 0;                                 // Set PORTB direction to be output
 PORTB = 0;                                 // Turn OFF LEDs on PORTB
 PORTA = 0;
 TRISA0_bit = 0;                            // RA.0 to RA3 Output
 TRISA1_bit = 0;
 TRISA2_bit = 0;
 TRISA3_bit = 0;
 
 do {                                        //--- main loop
     N_Flag = 0;                             // Reset Temp Flag
     DS18B20();
     DD0 = temp_value%10;                    // Extract Ones Digit
     DD0 = mask(DD0);
     DD1 = (temp_value/10)%10;               // Extract Tens Digit
     DD1 = mask(DD1);
     DD2 =  temp_value/100;                  // Extract Hundred digit
     if (N_Flag == 1) DD2=0x0A;              // DD2 10 ??
     else if (DD2 == 0) DD2 = 0x0D;          // DD2 13 ??
     DD2 = mask(DD2);
     display_temp(DD0, DD1, DD2, DD3);       // Infinite loop;
     } while (1);
 }

Lesson nr.13-7Segment and Push Button

Hardware setup:
Today Lesson is different from the last one, by the presence of two buttons and manually increment .
All 7-segment displays are connected to PORTB (RB0..RB7, segment A to RB0, segment B to RB1, etc.) with refresh via pins RA0..RA3 on PORTA.
If button on RA6 is presed the current number will be incremented by "1" and if button on RA7 is pressed the current number will be decremented by "1". Minimum number is 0000 and maximum number is 9999.



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:



Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.13:
'          Push Button & 7 Segment Display
'  Done by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          This code demonstrates  displaying number on four 7-segment display (common
'          cathode), in multiplex mode. All 7-segment displays are connected to PORTB
'          (RB0..RB7, segment A to RB0, segment B to RB1, etc.) with refresh via pins
'          RA0..RA3 on PORTA. If button on RA6 is presed the current number will be
'          incremented by "1" and if button on RA7 is pressed the current number will
'          be decremented by "1".
'
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         mikroC PRO for PIC
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
//***********Header*************/
unsigned short mask(unsigned short num)
{
 switch (num) 
 {
  case 0 : return 0x3F;
  case 1 : return 0x06;
  case 2 : return 0x5B;
  case 3 : return 0x4F;
  case 4 : return 0x66;
  case 5 : return 0x6D;
  case 6 : return 0x7D;
  case 7 : return 0x07;
  case 8 : return 0x7F;
  case 9 : return 0x6F;
  }
}
/*******Endless mask***********/
unsigned short shifter, portb_index;
unsigned int digit, number;
unsigned short portb_array[4];

void interrupt()
{
 PORTA = 0;                           // Turn off all 7seg. displays;
 PORTB = portb_array[portb_index];    // Bring appropriate value to PORTB;
 PORTA = shifter;                     // Turn on appropriate 7seg. display;

 //move shifter to next digit;
 shifter <<= 1;
 if(shifter > 15u)
 shifter = 1;

 //increment portb_index;
 portb_index ++ ;
 if (portb_index > 3u)
 portb_index = 0;                     //turn on 1st, turn off 2nd 7 seg.;
 TMR0 = 0;                            //reset TIMER0 value;
 INTCON = 0x20;                       //clear T0IF, Bit T0IF=0, T0IE=1;
 }

void main()
{
 CMCON |= 7;                          // Set AN pins to Digital I/O;
 OPTION_REG = 0x80;                   // Set timer TMR0;
 digit = 0;
 portb_index = 0;
 shifter = 1;
 TMR0 = 0;
 INTCON = 0xA0;                       // Disable interrupt PEIE,INTE,RBIE,T0IE
 TRISA = 0;
 TRISA6_bit = 1;
 TRISA7_bit = 1;                      // All port A pins are configured as outputs
 PORTA = 0;                           // Turn off displays
 TRISB = 0;                           // All port D pins are configured as outputs
 PORTB = 0;                           // Turn off all display segments
 
 number = 0;                          //initial value;
 
 do {
     if(Button(&PORTA,6,1,0)){
                              Delay_ms(200);
                              digit++ ;
                              number = number +1;
                              PORTB = number;
                              }
     if(Button(&PORTA,7,1,0)){
                              Delay_ms(200);
                              digit = digit -1;
                              number = number -1;
                              PORTB = number;
                              }
     if (number > 9999u)
     number = 0;

     digit = number % 10u;            //extract ones digit;
     portb_array[0] = mask(digit);    //and store it to PORTB array;
     digit = (number / 10u) % 10u;    //extract tens digit;
     portb_array[1] = mask(digit);    //and store it to PORTB array;
     digit = (number / 100u) % 10u;   //extract hundreds digit;
     portb_array[2] = mask(digit);    //and store it to PORTB array;
     digit = number / 1000u;          //extract thousands digit;
     portb_array[3] = mask(digit);    //and store it to PORTB array;
     } while(1);                      //Endless loop;
}                                     //End.

Lesson nr.12-Multiplexed 7Segment as counter mode

Hardware setup:
The basic technique is the same like the last lesson except fact that we have added a counter which counts between 0000 and 9999. Our counter increments with 1 second delay.
All 7-segment displays are connected to PORTB (RB0..RB7, segment A to RB0, segment B to RB1, etc.) with refresh via pins RA0..RA3 on PORTA.



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:



Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.12:
'          Multiplexed 7Segment as counter mode
'  Done by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          This code demonstrates  displaying number on four 7-segment display (common
'          cathode), in multiplex mode. All 7-segment displays are connected to PORTB
'          (RB0..RB7, segment A to RB0, segment B to RB1, etc.) with refresh via pins
'          RA0..RA3 on PORTA. Number is incremented for 1 second. 
'          To define this project, a counter is added (counts from 0000 to 9999).
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
//***********Header*************/
unsigned short mask(unsigned short num)
{
 switch (num)
 {
  case 0 : return 0x3F;
  case 1 : return 0x06;
  case 2 : return 0x5B;
  case 3 : return 0x4F;
  case 4 : return 0x66;
  case 5 : return 0x6D;
  case 6 : return 0x7D;
  case 7 : return 0x07;
  case 8 : return 0x7F;
  case 9 : return 0x6F;
  }
}
/*******Endless mask***********/
unsigned short shifter, portb_index;
unsigned int digit, number;
unsigned short portb_array[4];

void interrupt()
{
 PORTA = 0;                           // Turn off all 7seg. displays;
 PORTB = portb_array[portb_index];    // Bring appropriate value to PORTB;
 PORTA = shifter;                     // Turn on appropriate 7seg. display;

 //move shifter to next digit;
 shifter <<= 1;
 if(shifter > 8u)
 shifter = 1;

 //increment portb_index;
 portb_index ++ ;
 if (portb_index > 3u)
 portb_index = 0;                     //turn on 1st, turn off 2nd 7 seg.;
 TMR0 = 0;                            //reset TIMER0 value;
 INTCON = 0x20;                       //clear T0IF, Bit T0IF=0, T0IE=1;
 }

void main()
{
 CMCON |= 7;                          // Set AN pins to Digital I/O;
 OPTION_REG = 0x80;                   // Set timer TMR0;
 digit = 0;
 portb_index = 0;
 shifter = 1;
 TMR0 = 0;
 INTCON = 0xA0;                       // Disable interrupt PEIE,INTE,RBIE,T0IE
 PORTA = 0;                           // Turn off both displays
 TRISA = 0;                           // All port A pins are configured as outputs
 PORTB = 0;                           // Turn off all display segments
 TRISB = 0;                           // All port D pins are configured as outputs
 number = 0;                          //initial value;
 
 do {
     digit = number % 10u;            //extract ones digit;
     portb_array[0] = mask(digit);    //and store it to PORTB array;
     digit = (number / 10u) % 10u;    //extract tens digit;
     portb_array[1] = mask(digit);    //and store it to PORTB array;
     digit = (number / 100u) % 10u;   //extract hundreds digit;
     portb_array[2] = mask(digit);    //and store it to PORTB array;
     digit = number / 1000u;          //extract thousands digit;
     portb_array[3] = mask(digit);    //and store it to PORTB array;

     Delay_ms(1000);                  // 1s delay;

     number ++ ;                      //increment number;
     if (number > 9999u)
     number = 0;
     } while(1);                      //Endless loop;
 }                                    //End.

Lesson nr.11-7Segment in multiplexed mode

Hardware setup:
In this experiment we will learn how to use more than one 7-segment Led display, connected simultaneously at the microcontroller port,  using multiplexing technique. In the current experiment will interface four digit common cathode to PORT B, the command part, and to PORT A, the control of digits. The multiplexing circuit is configured on the breadboard, being composed of four NPN transistor and some resistance. Electric scheme emphasize  multiplexing interconnection mode. Multiplexing principle is that all digits are connected in parallel port on the microcontroller and the microcontroller alternately displays between units tens hundreds and thousands digits, selecting one at a time. The switching among the digits is so fast that it gives the impression of simultaneous emission of light.
Number displayed on the digits is 1234.



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:


Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.11:
'          7Segment in multiplexed mode
'  Written by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will show how to implement the multiplexed mode 
'          to control 7 segmnet digits. PORTB will be used for character 
'          (RB0=a,RB1=b...RB6=g,RB7=dp)and for digits RA0=digit1...RA3=digit4.
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
unsigned short mask(unsigned short num) // Mask for 7 segment common cathode;
{
 switch (num) {
               case 0 : return 0x3F;    // 0;
               case 1 : return 0x06;    // 1;
               case 2 : return 0x5B;    // 2;
               case 3 : return 0x4F;    // 3;
               case 4 : return 0x66;    // 4;
               case 5 : return 0x6D;    // 5;
               case 6 : return 0x7D;    // 6;
               case 7 : return 0x07;    // 7;
               case 8 : return 0x7F;    // 8;
               case 9 : return 0x6F;    // 9/
               }                        //case end
}
unsigned short digit1, digit2, digit3, digit4;
unsigned int number;

void main()                      // Main
{                     
 CMCON  |= 7;                    // Disable Comparators
 TRISB = 0;                      // Set PORTB direction to be output
 PORTB = 0xFF;                   // Turn OFF LEDs on PORTB
 TRISA = 0;
 PORTA = 0xFF;
 
 number = 1234;                  // value of number

 do {
     //Multiplexed mode;
     PORTB = digit4;
     RA0_bit = 0;
     RA1_bit = 0;
     RA2_bit = 0;
     RA3_bit = 1;                // Select Thousands Digit
     delay_ms(5);                // 5ms delay
     PORTB = digit3;
     RA0_bit = 0;
     RA1_bit = 0;
     RA2_bit = 1;                // Select Hundreds Digit
     RA3_bit = 0;
     delay_ms(5);                // 5ms delay
     PORTB = digit2;
     RA0_bit = 0;
     RA1_bit = 1;                // Select Tens Digit
     RA2_bit = 0;
     RA3_bit = 0;
     delay_ms(5);                // 5ms delay
     PORTB = digit1;
     RA0_bit = 1;                // Select Ones Digit
     RA1_bit = 0;
     RA2_bit = 0;
     RA3_bit = 0;
     delay_ms(5);                // 5ms delay
     
     digit1 = number%10;         // Extract Ones Digit
     digit1 = mask(digit1);
     digit2 = (number/10)%10;    // Extract Tens Digit
     digit2 = mask(digit2);
     digit3 = (number/100)%10;   // Extract Hundreds Digit
     digit3 = mask(digit3);
     digit4 = (number/1000);     // Extract Thousands Digit
     digit4 = mask(digit4);
     } while(1);                 // Infinite loop
}

Lesson nr.10-Software PWM & RGB LED

Hardware setup:
This time we will implement software PWM mode, to control the light intensity of an RGB Led (Red Green Blue, which represents a pixel) .PORT RA0~RA2 and PORT RB0~RB2 will be used for this experiment.
Port B is used, to see more easier transitions between RBG colors.



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:



Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.10:
'          Software PWM & RGB LED
'  Written by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will show how to implement software PWM to
'          control an RBG LED. PORT RA0~RA2 and PORT RB0~RB2 will be used for this experiment.
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
// LED RGB module connections
sbit RED1 at RA0_bit;
sbit GREEN1 at RA1_bit;
sbit BLUE1 at RA2_bit;
sbit RED2 at RB0_bit;
sbit GREEN2 at RB1_bit;
sbit BLUE2 at RB2_bit;

sbit RED1_Direction at TRISA0_bit;
sbit GREEN1_Direction at TRISA1_bit;
sbit BLUE1_Direction at TRISA2_bit;
sbit RED2_Direction at TRISB0_bit;
sbit GREEN2_Direction at TRISB1_bit;
sbit BLUE2_Direction at TRISB2_bit;
// End LED RGB module connections

int i = 0 ,PWN_COUNTER = 256;

void PWM_FADE_0_TO_1(void);
void PWM_FADE_1_TO_0(void);
void Delay(int num);

void main(void)
{
 CMCON  |= 7;                     //  Comparator is Off
 TRISA = 0;
 PORTA = 0;
 TRISB = 0;
 PORTB = 0;

 while(1){
          PWM_FADE_0_TO_1();
          PWM_FADE_1_TO_0();
          }
}

void PWM_FADE_0_TO_1(void)        // Duty cycle -  0%  to  100%
{
 for (i = 0; i < PWN_COUNTER; i++)
 {
  RED1 = 0;
  RED2 = 0;
  Delay(PWN_COUNTER - i);
  RED1 = 1;
  RED2 = 1;
  Delay(i);
  }
 for (i = 0; i < PWN_COUNTER; i++)
 {
  GREEN1 = 0;
  GREEN2 = 0;
  Delay(PWN_COUNTER - i);
  GREEN1 = 1;
  GREEN2 = 1;
  Delay(i);
  }
 for (i = 0; i < PWN_COUNTER; i++)
 {
  BLUE1 = 0;
  BLUE2 = 0;
  Delay(PWN_COUNTER - i);
  BLUE1 = 1;
  BLUE2 = 1;
  Delay(i);
  }
}

void PWM_FADE_1_TO_0(void)         // Duty cycle -  100% to 0%
{
 for (i = 0; i < PWN_COUNTER; i++)
 {
  RED1 = 1;
  RED2 = 1;
  Delay(PWN_COUNTER - i);
  RED1 = 0;
  RED2 = 0;
  Delay(i);
  }
 for (i = 0; i < PWN_COUNTER; i++)
 {
  GREEN1 = 1;
  GREEN2 = 1;
  Delay(PWN_COUNTER - i);
  GREEN1 = 0;
  GREEN2 = 0;
  Delay(i);
  }
 for (i = 0; i < PWN_COUNTER; i++)
 {
  BLUE1 = 1;
  BLUE2 = 1;
  Delay(PWN_COUNTER - i);
  BLUE1 = 0;
  BLUE2 = 0;
  Delay(i);
  }
}

void Delay(int num)
{
 while(num>0)
 num--;
}

Lesson nr.09-Using PWM to control DC Motor Speed

Hardware setup:
In this experiment we will work again with PWM, but this time, as a consumer, I will use a DC (Direct Current) motor. To avoid burning RB3 port, due to high consumption of the motor, consumption which can not be given by the port of the microcontroller, we will use an extension consisting of a transistor (our case, BC547/NPN) connected in switching mode (ON / OFF ). The current to drive the motor is provided by the collector current in the transistor. The diode is for EMF (ElectroMagnetic Field) protection. Protection provided to our transistor. I will use a small 5V DC motor from an old CD-Rom.



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:


Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.09:
'          Using PWM to control DC Motor Speed
'  Written by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will show how to work with module CCP1 as PWM mode.
'          The PORT RB3 is used for this experiment (as output, for DC Motor)
'          and RA4-RA6 (as imput, for buttons) which controls the pulse width.
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
// LCD module connections
sbit LCD_RS at RB5_bit;                 // LCD_RS assigned to PORT RB5;
sbit LCD_EN at RB6_bit;                 // LCD_EN assigned to PORT RB6;
sbit LCD_D4 at RB0_bit;                 // LCD_D4 assigned to PORT RB0;
sbit LCD_D5 at RB1_bit;                 // LCD_D5 assigned to PORT RB1;
sbit LCD_D6 at RB2_bit;                 // LCD_D6 assigned to PORT RB2;
sbit LCD_D7 at RB4_bit;                 // LCD_D7 assigned to PORT RB4;

sbit LCD_RS_Direction at TRISB5_bit;    // LCD_RS assigned to TRIS B5;
sbit LCD_EN_Direction at TRISB6_bit;    // LCD_EN assigned to TRIS B6;
sbit LCD_D4_Direction at TRISB0_bit;    // LCD_D4 assigned to TRIS B0;
sbit LCD_D5_Direction at TRISB1_bit;    // LCD_D5 assigned to TRIS B1;
sbit LCD_D6_Direction at TRISB2_bit;    // LCD_D6 assigned to TRIS B2;
sbit LCD_D7_Direction at TRISB4_bit;    // LCD_D7 assigned to TRIS B4;
// End LCD module connections

char message1[]="ON ";
char message2[]="OFF";

unsigned short Last_Duty, Current_Duty;
void main()                             // main;
{
 CMCON |= 7;                            // turn off analogue comparator and make PORTA to digital I/O;
 TRISA4_bit=1;
 TRISA6_bit=1;
 PORTA = 0;
 TRISB = 0;                             // make rb3 as output;
 PORTB = 0;                             // turn off LEDs on PORTB;
 Current_Duty = 0;                      // Initial value of variable current_duty;
 Last_Duty = 0;                         // Reset variable last_duty;
 
 Lcd_init();
 Lcd_cmd(_LCD_Clear);
 Lcd_cmd(_LCD_Cursor_Off);
 Lcd_out(1,6,"PWM and");
 Lcd_out(2,2,"DC Motor Speed");
 Delay_ms(3000);
 Lcd_cmd(_LCD_clear);
 Lcd_out(1,1,"switch1:");
 Lcd_out(2,1,"switch2:");

 Pwm1_Init(5000);                       // PWM module initialization (5KHz);
 Pwm1_Start();                          // Start PWM1 module;
 Pwm1_Set_Duty(Last_Duty);
 do {
     while(Last_Duty >= 0 <= 255)
     {
      if (Button(&PORTA, 4,1,0))
      {
       Last_Duty = Last_Duty + 5;       // If the button connected to RA4 is pressed
       Pwm1_Set_Duty(Last_Duty);
       Lcd_out(1,9,message1);
       }
      else
      Lcd_out(1,9,message2);
      Delay_ms(100);

      if (Button(&PORTA, 6,1,0))
      {
       Last_Duty = Last_Duty - 5;       // If the button connected to RA6 is pressed
       Pwm1_Set_Duty(Last_Duty);
       Lcd_out(2,9,message1);
       }
      else
      Lcd_out(2,9,message2);
      Delay_ms(100);
      }
     Delay_ms(200);                     // 200mS delay
     } while(1);                        // Do forever;
}                                       // End.

Lesson nr.08-Using PWM to control LED brightness

Hardware setup:
Like in the last Lesson, nr.07, we will work with CCP1 in PWM mode, to control the luminous intensity of a L.E.D, but here we will not use buttons to vary the width form of our signal. The pulse width will automatically vary between 0% and 100% and vice versa.
Button S1 and (pull-up) resistance with value of 4.7 K will provide the manual reset mode to the microcontroller.



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:



Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.08:
'          Using PWM to control LED brightness
'  Written by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will work with module CCP1 as PWM mode, to 
'          control LED brightness. PORT RB.3 will be used for this experiment.
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
unsigned short i;

void main()             // Main;
{
 TRISB3_bit = 0;        // RB.3 is output;
 PORTB = 0;             // Set PORTB to 0;

 Pwm1_Init(5000);       // Initialize PWM module at 5KHz;
 Pwm1_Start();          // Start PWM;

 do {
     while(i<255){                        // As long as i<255;
                  i = i+1;                // Increment i with 1;
                  Pwm1_Set_Duty(i);       // Set pwm duty;
                  Delay_ms(8);            // 5ms delay;
                  }
     Pwm1_Stop;                           // Stop pwm;
     Delay_ms(5);                         // 5ms delay;
     Pwm1_Start;                          // Start pwm;
     Delay_ms(5);                         // 5ms delay;
     
     while(i>0){                          // As long as i>0;
                i = i-1;                  // decrement i with 1;
                Pwm1_Set_Duty(i);         // Set pwm duty;
                Delay_ms(5);              // 5ms delay;
                }
     Pwm1_Stop;                           // Stop pwm;
     Delay_ms(100);                       // 100ms delay;
     } while(1);                          // Do forever;
}                                         // End.

Lesson nr.07-PWM & Push Button

Hardware setup:
In this experiment we will use the CCP1 as a PWM to control the power to a L.E.D. PWM stands for the Pulse Width Modulation where the width of a digital waveform is varied to control the power delivered to a load (in this case an L.E.D). The underlying principle in the whole process is that the average power delivered is directly proportional to the modulation duty cycle. The term duty cycle describes the proportion of on time to the regular interval or period of time; a low duty cycle corresponds to low power, because the power is off for most of the time. Duty cycle is expressed in percent, 100% being fully on and 0% means off.


Trough  hardware configuration of the microcontroller we will deduct to use the PORT RB3 as PWM output.
Button S1 and (pull-up) resistance with value of 4.7 K will provide the manual reset mode to the microcontroller.
Buttons S2 and S3 will vary the width form of our signal.
ICSP connector provides the connection between the programmer (PicKit 2) and microcontroller (PIC16F628A).



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:


Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.07:
'          PWM & Push Button
'  Written by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will show how to work with module CCP1 as PWM mode.
'          The PORT RB3 is used for this experiment (as output, for a led)
'          and RA6-RA7 (as imput, for buttons).
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
unsigned short last_duty, current_duty;
void main()                 // main;
{
 CMCON |= 7;                // turn off analogue comparator and make PORTA to digital I/O;
 trisb3_bit = 0;            // make rb3 as output;
 portb = 0;                 // turn off LEDs on PORTB;
 current_duty = 0;          // Initial value of variable current_duty;
 last_duty = 0;             // Reset variable last_duty;
 pwm1_init(5000);           // PWM module initialization (5KHz);
 pwm1_start();              // Start PWM1 module;
 pwm1_set_duty(last_duty);
 do {
     while(last_duty>0<255){
                            if (Button(&PORTA, 6,1,0))
                            last_duty = last_duty +2;       // If the button connected to 
                                                            // RA0 is pressed
                            Pwm1_Set_Duty(last_duty);
                            delay_ms(100);

                            if (Button(&PORTA, 7,1,0))
                            last_duty = last_duty -2;       // If the pressed button is 
                                                            // connected to RA1
                            Pwm1_Set_Duty(last_duty);
                            delay_ms(100);
                            }
     delay_ms(200);                       // 200mS delay
     } while(1);                          // Do forever;
}                                         // End.

Lesson nr.06-Push Button

Hardware setup:
In this experiment we will make a demonstration with button library. The PORTB is used for this experiment (as output, for a leds) and RA6 (as imput, for button S2).
As usualy, button S1 and (pull-up) resistance with value of 4.7 K will provide the manual reset mode to the microcontroller. This arangement provides a standard schematic when we whant to include a button as input, current mode is with pull-up resistance, but also exist and with pull-down resistance which will not be used in our experiments, at least for the moment.
ICSP connector provides the connection between the programmer (PicKit 2) and microcontroller (PIC16F628A).



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:


Software:
Here's a page from Button Library that specify buttons routines:


And as usualy, here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.06:
'          Push Button
'  Written by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will make a demonstration with button library
'          The PORTB is used for this experiment (as output, for a leds)
'          and RA6 (as imput, for button).
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
unsigned short oldstate;
void main()
{                                     // Main;
 TRISB = 0;                           // Set PORTB direction to be output;
 PORTB = 0xFF;                        // Turn OFF LEDs on PORTA;

 TRISA6_bit = 1;                      // Set PORT RB1 input for button;
 oldstate = 0;                        // Define value of oldstate;

do {
    if (Button(&PORTA,6,1,1)) oldstate = 1;
    Delay_ms(100);                                              //delay for prevent crash
    if (oldstate &&Button(&PORTA,6,1,0)) {
                                          PORTB = ~PORTB;       //invert state of PORTB
                                          oldstate = 0;
                                          }
    } while(1);                                                 //Infinite loop.
}

Lesson nr.05-Timers and Interrupts

Hardware setup:
In this experiment we will work with interrupt which are enabled after the timer register TMR1 (TMR1H, TMR1L) overflow occurs.
As result combination of bits will be changing on PORT RB.0~RB.7.
As we know, button S1 and (pull-up) resistance with value of 4.7 K will provide the manual reset mode to the microcontroller.
ICSP connector provides the connection between the programmer (PicKit 2) and microcontroller (PIC16F628A).



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:


Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.05:
'          Timers and Interrupts
'  Written by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will work with interrupt which are enabled after
'          the timer register TMR1 (TMR1H, TMR1L) overflow occurs.
'          Combination of bits changing on PORT RB.0~RB.7.
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
unsigned short cnt;                          // Define variable cnt;
void interrupt()
{
 if (PIR1.TMR2IF) {                          // If bit TMR2IF = 1,
                   cnt++ ;                   // Increment variable cnt by 1;
                   PIR1.TMR2IF = 0;          // Reset bit and
                   TMR2 = 0;                 // reset register TMR2;
                   }
}

void main() 
{                                            // Main;
 cnt = 0;                                    // Reset variable cnt;
 CMCON |=7;                                  // All I/O pins are configured as digital;
 TRISB = 0;                                  // All port B pins are configured as outputs;
 PORTB = 0xAA;                               // Logic state on port B pins ;
 T2CON = 0xFF;                               // Set timer T2;
 TMR2 = 0;                                   // Initial value of timer register TMR2;
 PIE1.TMR2IE = 1;                            // Enable interrupt;
 INTCON = 0xC0;                              // Set bits GIE and PEIE;

 while (1) {                                 // Endless loop;
            if (cnt > 10) {                  // Change PORTB after more than 10 interrupts;
                           PORTB = ~PORTB;   // Function Replace inverts the port B state;
                           cnt = 0;          // Reset variable cnt;
                           }                 // End if;
            }                                // End while;
}                                            // End.

Lesson nr.04-Watch-dog timer

Hardware setup:
This example illustrates how the watch-dog timer should not be used. A command used for resetting this timer is intentionally left out in the main program loop, thus enabling the microcontroller to be reset. As a result, the microcontroller will be reset all the time, which is reflected as PORT RB.0~RB.7 LED blinking.
Button S1 and (pull-up) resistance with value of 4.7 K will provide the manual reset mode to the microcontroller.
ICSP connector provides the connection between the programmer (PicKit 2) and microcontroller (PIC16F628A).



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:


Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.04:
'          Watch-dog timer
'  Written by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          This example illustrates how the watch-dog timer should not be used.
'          A command used for resetting this timer is intentionally left out in
'          the main program loop, thus enabling the microcontroller to be reset.
'          As a result, the microcontroller will be reset all the time, which is
'          reflected as PORT RB.0~RB.7 LED blinking.
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             ON
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
void main()                     // Main;
{
 OPTION_REG = 0x0E;             // Prescaler is assigned to timer wdt
                                // (1:4[0x0A];1:8[0x0B];1:16[0x0C];1:32[0x0D];
                                // 1:64[0x0E];1:128[0x0F]);
 asm CLRWDT;                    // Assembly command to reset WDT timer;
 TRISB = 0x00;                  // All port B pins are configured as output;
 PORTB = 0x0F;                  // Initial value of the PORTB register;
 Delay_ms(600);                 // 600ms delay;
 PORTB = 0xF0;                  // Porta B value different from initial;
 while(1);                      // Endless loop. Program remains here until WDT
                                // timer reset the  microcontroller;
 }                              // End.

Lesson nr.03-8-bit Binary counter

Hardware setup:
In this experiment we will show how to set MCU to count 8-bit in binary mode. The Counter will counts from 0(00h) to 255(FFh) with 1sec delay between each count. The output will be displayed on 8 L.E.Ds connected to PORT RB.0~RB.7
Button S1 and (pull-up) resistance with value of 4.7 K will provide the manual reset mode to the microcontroller.
ICSP connector provides the connection between the programmer (PicKit 2) and microcontroller (PIC16F628A).
I have to mention the fact that in video below I reduced the time between each count, to be more viewable all 8 bits.



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:


Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.03:
'          8-bit Binary counter
'  Written by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will show how to set MCU to count 8-bit in binary mode.
'          The output will be displayed on 8 LEDs connected to PORT RB.0~RB.7
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
void main()
{
 TRISB = 0x00;                //SET PORTB TO BE OUTPUT;
 PORTB = 0x00;                //TURN OFF LEDs ON PORTB;
 do {
     PORTB++;                //INCREMENTS;
     Delay_ms(1000);         //WAIT 1S;
     }while(1);              //INFINITE LOOP;
}