Saturday 8 September 2012

Stepper Motor Interfacing with PIC16F877A

char RotSense, PulseNum;
char pos=0;

char FullStepForward [4]={0x03, 0x09, 0x0C, 0x06};
char FullStepBackward[4]={0x06, 0x0C, 0x09, 0x03};
char HalfStepForward [8]={0x03, 0x01, 0x09, 0x08, 0x0C, 0x04, 0x06, 0x02};
char HalfStepBackward[8]={0x06, 0x04, 0x0C, 0x08, 0x09, 0x01, 0x03, 0x02};

void FullStepMotorCW()
{
 TRISD=FullStepForward[pos];
 delay_ms(50);
 pos=(pos+1)%4;
}

void FullStepMotorCCW()
{
 TRISD=FullStepBackward[pos];
 delay_ms(1000);
 pos=(pos+1)%4;
}

void HalfStepMotorCW()
{
 TRISD=HalfStepForward[pos];
 delay_ms(1000);
 pos=(pos+1)%8;
}

void HalfStepMotorCCW()
{
 TRISD=HalfStepBackward[pos];
 delay_ms(1000);
 pos=(pos+1)%8;
}

void Initial()
{
  TRISD=0x00;
}

void main() {
  char i;
  Initial();

  do {
        PulseNum=200;
     for(i=0;i<PulseNum;i++) FullStepMotorCW();
     //for(i=0;i<PulseNum;i++) HalfStepMotorCW();
  } while (1);
}
void interrupt()
{
}

Touch Screen Interfacing with PIC16F877A

#include <18f4520.h>
#use delay(clock=40000000)
#use rs232(baud=9600, UART1)      // hardware UART; uses  RC6/TX and RC7/RX
#include "flex_lcd.c"             //must include in order to output to LCD

int j;
int16 x_pos, y_pos;

void get_screen_pos(int16& x_pos, int16& y_pos);

void main()
{

   lcd_init();  // Always call this first.

   //command Format Tablet: "<SOH>FT<CR>" sent to touchscreen via RC6/TX pin
   putc(0x01);
   putc(0x46);
   putc(0x54);
   putc(0x0D);

   while (TRUE)
   {
      //get the finger position relative to the touchscreen in 16-bit int format
      get_screen_pos(x_pos, y_pos);

      printf(lcd_putc,"\fX: %Lu\n",x_pos); //output "X: <x_pos>" to first line of LCD
      printf(lcd_putc,"Y: %Lu",y_pos);     //output "Y: <y_pos>" to second line of LCD
   }
}

//Function adapted from Nick Marchuk's IR touchscreen code
void get_screen_pos(int16& x_pos, int16& y_pos)
{
   int i, gotD8, j;
   int touchscreen_rcx[20];
   int pos[5];
   int16 high16, low16, xtotal16, ytotal16;
   int temp4, total8;
   high16 = 0;
   low16 = 0;
   xtotal16 = 0;
   ytotal16 = 0;
   temp4 = 0;
   total8 = 0;

   //get 10 bytes from the touchscreen (each touch signal is 10 bytes)
   for (i=1;i<=10;++i)
   {
      touchscreen_rcx[i] = getc();
   }

   //find the first instance of 0xD8 (start of each signal)
   gotD8 = 0;
   j = 1;
   while(gotD8==0)
   {
      if((touchscreen_rcx[j] == 0xD8))
      {
         gotD8 = 1; //j is the location of 0xD8
      }
      else
      {
         j = j+1;
      }

      if(j==9)
      {
         gotD8 = 1; //didnt find it, dont loop forever
      }
   }

   pos[1] = touchscreen_rcx[j+1]; //xlow, bits: 0 X6 X5 X4 X3 X2 X1 X0 (see touchscreen datasheet for FT response))
   pos[2] = touchscreen_rcx[j+2]; //xhigh, bits: 0 X13 X12 X11 X10 X9 X8 X7
   pos[3] = touchscreen_rcx[j+3]; //ylow, bits: 0 Y6 Y5 Y4 Y3 Y2 Y1 Y0
   pos[4] = touchscreen_rcx[j+4]; //yhigh, bits: 0 Y13 Y12 Y11 Y10 Y9 Y8 Y7

   //make the x
   temp4 = pos[2];
   high16 = temp4; //make high16= 0000 0000 0X13X12X11 X10X9X8X7
   low16 = pos[1]; //make low16= 0000 0000 0X6X5X4 X3X2X1X0

   xtotal16 = low16|(high16<<7); //OR 00X13X12 X11X10X9X8 X7000 0000 with 0000 0000 0X6X5X4 X3X2X1X0
   x_pos = xtotal16; //x_pos=00X13X12 X11X10X9X8 X7X6X5X4 X3X2X1X0

   //make the y
   temp4 = pos[4];
   high16 = temp4; //make high16= 0000 0000 0Y13Y12Y11 Y10Y9Y8Y7
   low16 = pos[3]; //make low16= 0000 0000 0Y6Y5Y4 Y3Y2Y1Y0

   ytotal16 = low16|(high16<<7); //OR 00Y13Y12 Y11Y10Y9Y8 Y7000 0000 with 0000 0000 0Y6Y5Y4 Y3Y2Y1Y0
   y_pos = ytotal16;             //x_pos=00Y13Y12 Y11Y10Y9Y8 Y7Y6Y5Y4 Y3Y2Y1Y0
}

RS232 Communication with PIC16F877A

#include <18F2620.h>
#device adc=16

#FUSES NOWDT                     //No Watch Dog Timer
#FUSES WDT128                    //Watch Dog Timer uses 1:128 Postscale
#FUSES H4                        //High speed osc with HW enabled 4X PLL
#FUSES NOBROWNOUT                //No brownout reset
#FUSES LVP                       //Low voltage prgming
#FUSES NOXINST                   //Extended mode disabled (Legacy mode)

#use delay(clock=40000000)
#use rs232(baud=57600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)


void main()
{
    int value = 85;
    char ch;
    char string[64];
   
    puts("**********************************");
    puts("  RS232 demo with CCS C compiler  ");
    puts("**********************************");
   
    /* start a new line (CR + LF) */
    putc('\n');
    putc('\r');
   
    /* output variable in decimal format */
    printf("Decimal variable output: %d\n\r", value);

    /* output variable in hex format */
    printf("Hex variable output: %x\n\r", value);


    /* echo demo: PIC receives data and sends it back. */
    /*            If ENTER key is received, this demo exits. */
    puts("Type on the keyboard, PIC will echo back the characters:");

    while (1)
    {
        /* read a single character */
        ch = getc();
        /* echo back the received character */
        putc(ch);
    }
}

DC Motor Interfacing Program with PIC16F877A

#include <pic.h>
__CONFIG (0x3F32);
#define sw1 RB0
#define ssL C1OUT
#define led1 RB6
#define led2 RB7
#define buzzer RC3
#define motor_ra RC4
#define motor_la RC7
#define pwml CCPR1L
#define pwmr CCPR2L



// Function Prototype
//************************************************** *************************

void init(void);
void delay(unsigned long data);
void forward(void);
void reverse(void);
void motor_run(void);
void stop(void);

// Main
//************************************************** *************************

void main(void)
{
unsigned i;

init(); // call initialization function
buzzer = 0; // buzzer OFF
led1 = 1;
led2 = 1;
stop(); // robot stop
pwml = 200; // set pwm left motor = 200
pwmr = 200; // set pwm right motor = 200

while(1) // infinite loop
{
if(sw1==0) // sw1 pushed?
{
while(!sw1);
while(1)
{ // if pushed
for(i=0;i<2;i++) // buzzer ON 2 times
{
buzzer = 1;
delay(10000);
buzzer = 0;
delay(10000);
}
motor_run(); // call motor run function
}
}
else stop(); // if sw1 not pushed, robot stop
}
}

// PIC Initialization Function Routine
//************************************************** *************************

void init()
{

PR2 = 255; // set period register
T2CON = 0b00000100; // set prescale 1
CCP1CON = 0b00001100; // config for RC1 to generate PWM

TRISE = 0b000; // set PORTE I/O direction
}

void delay(unsigned long data) // delay function
{
for(;data>0;data--); // delay depend on the data given
}

void motor_run(void) // motor_run function
{
unsigned n = 0;
forward(); // motor forward

while(n==0)
{

}
}
// Description : Motor functions
//================================================== ================================================== ========

void forward(void) // forward function
{
motor_ra = 1;
motor_la = 1;

}

void stop(void) // stop function
{
motor_ra = 1;
motor_la = 1;

}
void reverse(void)
{
motor_ra = 0;
motor_la = 0;

}

4x4 Keypad Interfacing Program with PIC16F877A

#include <pic.h>
/*   PIC Configuration Bit:
**   INTIO     - Using Internal RC No Clock
**   WDTDIS    - Wacthdog Timer Disable
**   PWRTEN    - Power Up Timer Enable
**   MCLREN    - Master Clear Enable
**   UNPROTECT - Code Un-Protect
**   UNPROTECT - Data EEPROM Read Un-Protect
**   BORDIS    - Borwn Out Detect Disable
**   IESODIS   - Internal External Switch Over Mode Disable
**   FCMDIS    - Monitor Clock Fail Safe Disable
*/
__CONFIG( WDTDIS & PWRTEN & UNPROTECT \
  & UNPROTECT & BORDIS);
 
#define FOSC 4000000
#define _delay_us(x) { unsigned char us; \
         us = (x)/(12000000/FOSC)|1; \
         while(--us != 0) continue; }
 
void _delay_ms(unsigned int ms)
{
  unsigned char i;
  do {
    i = 4;
    do {
      _delay_us(164);
    } while(--i);
  } while(--ms);
}
 
//****** LCD Functions declaration ******** //
void LCD_init(void);
void LCD_WriteCommand (unsigned char Command);
void LCD_WriteData (unsigned char Data);
 
void LCD_DisplayString (char row, char column, char *string);
void LCD_Cursor(char row, char column);
 
#define ENABLE_LCD              PORTD |= 0x80
#define DISABLE_LCD            PORTD &= ~0x80
#define SET_LCD_DATA           PORTD |= 0x20
#define SET_LCD_CMD            PORTD &= ~0x20
#define KB_PORT_OUT    PORTC
#define KB_PORT_IN    PORTC
 
//************************
 
void port_init(void)
{
 TRISB  = 0x00;  
 PORTB = 0x00;  
 TRISC  = 0xf0;//Key-board port, higer nibble - input, lower nibble - output
 PORTC = 0xff; 
 TRISD  = 0x0f;
 PORTD = 0x00;
}
 
 
//call this routine to initialize all peripherals
void init_devices(void)
{
 port_init();
 LCD_init(); 
} 
 
//****************** MAIN FUNCTION *******************
 
 int main(void)
{
   unsigned char upperNibble, keyCode, keyPressed, i;
   init_devices();
 
   LCD_DisplayString (1,1,"   WELCOME    ");
   LCD_WriteCommand(0xc0); //moving LCD cursor to second row
 
   while(1)
   {
        upperNibble = 0xff;
 
  for(i=0; i<4; i++)
     {
   _delay_ms(1);
   KB_PORT_OUT = ~(0x01 << i);
   _delay_ms(1); //delay for port o/p settling
   upperNibble = KB_PORT_IN | 0x0f;
 
   if (upperNibble != 0xff)
   {
     _delay_ms(20); //key debouncing delay
        upperNibble = KB_PORT_IN | 0x0f;
     if(upperNibble == 0xff) goto OUT;
 
     keyCode = (upperNibble & 0xf0) | (0x0f & ~(0x01 << i));
 
     while (upperNibble != 0xff)
       upperNibble = KB_PORT_IN | 0x0f;
 
     _delay_ms(20); //key debouncing delay
 
     switch (keyCode) //generating key characetr to display on LCD
     {
      case (0xee): keyPressed = '0'; 
        break;
   case (0xed): keyPressed = '1';
        break;
   case (0xeb): keyPressed = '2'; 
          break;
   case (0xe7): keyPressed = '3'; 
        break;
   case (0xde): keyPressed = '4'; 
        break;
   case (0xdd): keyPressed = '5'; 
        break;
   case (0xdb): keyPressed = '6'; 
        break;
   case (0xd7): keyPressed = '7'; 
        break;
   case (0xbe): keyPressed = '8'; 
        break;
   case (0xbd): keyPressed = '9'; 
        break;
   case (0xbb): keyPressed = 'A'; 
        break;
   case (0xb7): keyPressed = 'B'; 
        break;
   case (0x7e): keyPressed = 'C'; 
        break;
   case (0x7d): keyPressed = 'D'; 
        break;
   case (0x7b): keyPressed = 'E'; 
        break;
   case (0x77): keyPressed = 'F'; 
        break;
   default : keyPressed = 'X';
   }//end of switch
 
   LCD_WriteData(keyPressed); 
 
     OUT:;
    }//end of if
  }//end of for
 }//end of while(1)  
 
 return 0;    
}//end of main()
 
 
//***********************************************************************
//***********************   LCD Functions   ***************************** 
//***********************************************************************
 
// ********************************* 
// *** Initialize the LCD driver *** 
// ********************************* 
void LCD_init(void)
{
 _delay_ms(100); // wait for 100ms
 
 //SET_LCD_WRITE ;      // Set LCD in write mode
 
 LCD_WriteCommand (0x38); // 8 data lines
 LCD_WriteCommand (0x08); // display off
 LCD_WriteCommand (0x01); // clear LCD memory
 _delay_ms (10); // 10ms delay after clearing LCD
 LCD_WriteCommand (0x06); // cursor setting
 LCD_WriteCommand (0x0f); // display ON
}
 
 
// ********************************************** 
// *** Write a command instruction to the LCD *** 
// ********************************************** 
void LCD_WriteCommand (unsigned char Command)
{
 
 SET_LCD_CMD; // Set LCD in command mode
 
 PORTB = Command; // Load data to port
 
 ENABLE_LCD; // Write data to LCD
 
 asm("nop");     
 asm("nop");
 
 DISABLE_LCD; // Disable LCD 
 
 _delay_ms(1); // wait for 1ms
}
 
 
// ***************************************** 
// *** Write one byte of data to the LCD *** 
// ***************************************** 
void LCD_WriteData (unsigned char Data)
{
 SET_LCD_DATA; // Set LCD in data mode
 
 PORTB = Data; // Load data to port
 
 ENABLE_LCD; // Write data to LCD
 
 asm("nop");
 asm("nop");
 
 DISABLE_LCD; // Disable LCD
 
 _delay_ms(1); // wait for 1ms
}
 
 
// ********************************************************************* 
// *** Display a string at the specified row and column, from FLASH **** 
// ********************************************************************* 
void LCD_DisplayString (char row, char column, char *string)
{
 LCD_Cursor (row, column);
 while (*string)
  LCD_WriteData(*string++);
}
 
 
// *************************************************** 
// *** Position the LCD cursor at "row", "column". *** 
// *************************************************** 
void LCD_Cursor (char row, char column)
{
 switch (row) 
 {
  case 1: LCD_WriteCommand (0x80 + column - 1); break;
  case 2: LCD_WriteCommand (0xc0 + column - 1); break;
  default: break;
 }
}

LCD Interfacing Program with PIC16F877A

#include<pic.h>
#define _XTAL_FREQ 20e6
__CONFIG(0x3F3A);
#define RS RB2
#define EN RB1
#define databits PORTD
/*----------------PIC INITIALIZATION------------*/
void pic_init()
{
    TRISB2 = 0;
    TRISB1 = 0;
    TRISD = 0;
}
 
/*-------------LCD FUNCTIONS BEGIN--------------*/
void LCD_STROBE(void)
{
    EN = 1;
    __delay_us(1);
    EN = 0;
}
 
void data(unsigned char c)
{
    RS = 1;
    __delay_us(50);
    databits = (c >> 4);
    LCD_STROBE();
    databits = (c);
    LCD_STROBE();
}
 
void cmd(unsigned char c)
{
    RS = 0;
    __delay_us(50);
    databits = (c >> 4);
    LCD_STROBE();
    databits = (c);
    LCD_STROBE();
}
 
void clear(void)
{
    cmd(0x01);
    __delay_ms(2);
}
 
void lcd_init()
{
    __delay_ms(15);
    cmd(0x38);
    __delay_ms(1);
    cmd(0x38);
    __delay_us(100);
    cmd(0x38);
    cmd(0x28);            // Function set (4-bit interface, 2 lines, 5*7Pixels)
    cmd(0x28);            // Function set (4-bit interface, 2 lines, 5*7Pixels)
    cmd(0x0c);            // Make cursorinvisible
    clear();            // Clear screen
    cmd(0x6);            // Set entry Mode(auto increment of cursor)
}
 
void string(const char *q)
{
    while (*q) {
        data(*q++);
    }
}
 
/*-------------LCD END--------------------*/
 
main()
{
    __delay_ms(50);
    pic_init();
    lcd_init();
    TRISC = 0;
    while (1) {
        cmd(0x80);
        string("HELLO WORLD");
        cmd(0xc0);
        string("IT IS WORKING:-)");
         
    }
}

Switch Interfacing Program with PIC16F877A

#include <p18f2520.h>

#pragma config OSC    = XT  // 4MHz Crystal, (XT oscillator)
#pragma config PBADEN = OFF // PORTB<4:0> pins are configured as digital I/O on Reset)


void delay_ms(unsigned int duration);
unsigned char is_sw1_pressed(void);
unsigned char is_sw2_pressed(void);


void main()
{
   TRISCbits.TRISC0=0; // Set PortC bit 0 as output, LED1 is connected to thi pin
   TRISCbits.TRISC1=0; // Set PortC bit 0 as output, LED2 is connected to thi pin
    
   LATCbits.LATC0=0; // turn off LED1
   LATCbits.LATC1=0; // turn off LED2

   TRISBbits.TRISB3=1; // configure SW1 pin as input
   TRISBbits.TRISB4=1; // configure SW2 pin as input
    
    while(1)
    {
      if(is_sw1_pressed()==1)    // is key 1 pressed
      {                        // yes
         LATCbits.LATC0=1;     // turn ON LED1    
        }
        else
        {                        //no
            LATCbits.LATC0=0;    //turn off LED1
        }

        if(is_sw2_pressed()==1)    // is key 2 pressed
        {                        // yes
            LATCbits.LATC1=1;     // turn ON LED2    
        }
        else
        {                        //no
            LATCbits.LATC1=0;    //turn off LED2
        }
    }
}

/////////////////////////////////////////////////////////////////////////////////////////
//     this is delay routine
//     input: required Delay duration in mili Seconds
//    output: none
/////////////////////////////////////////////////////////////////////////////////////////

void delay_ms(unsigned int duration) // delay in miliseconds for 4.0MHZ crystal
{
    unsigned int i;
    for(;duration!=0;duration--)
    {
        for(i=0;i<=50;i++)
        {
            _asm
                nop
                nop
                nop
            _endasm
        }
        _asm
            nop
            nop
        _endasm
    }
}


/////////////////////////////////////////////////////////////////////////////////////////
//this routine is to check key1 pressings.
//input: none 
//output: 0 if switch is not pressed. 1 if switch is pressed. 
/////////////////////////////////////////////////////////////////////////////////////////
unsigned char is_sw1_pressed(void)
{
    if (PORTBbits.RB3==0)        // is SW1 pressed?
    {                            //yes
        delay_ms(10);            // wait 10mS for debounce.
        if (LATBbits.LATB3==0)    // is SW1 still has pressed status after 10mS delay?
        {                        // yes, we have key press
            return 1;
        }
    }
    return 0;// if key is not pressed, return 0
}

/////////////////////////////////////////////////////////////////////////////////////////
//this routine is to check key2 pressings.
//input: none 
//output: 0 if switch is not pressed. 1 if switch is pressed. 
/////////////////////////////////////////////////////////////////////////////////////////
unsigned char is_sw2_pressed(void)
{
    if (LATBbits.LATB4==0)        // is SW1 pressed?
    {                            //yes
        delay_ms(10);            // wait 10mS for debounce.
        if (LATBbits.LATB4==0)    // is SW1 still has pressed status after 10mS delay?
        {                        // yes, we have key press
            return 1;
        }
    }
    return 0;// if key is not pressed, return 0
}

LED Blinking Program with PIC16877A

void main()
        {
        TRISB = 0 ;     // set PORTB as OUTPUT         for(;;)         // forever
                {
                PORTB = 0xff ;          // turn all LEDs ON
                Delay_ms(500) ;         // wait 500 ms
                PORTB = 0 ;             // turn all LEDs OFF
                Delay_ms(500) ;         // wait 500 ms
                }
        }

Introduction to Microcontrollers