Thursday, 6 October 2016

USB INTERFACING OF PIC-MICRO-CONTROLLER WITH PC

1Objective-

The objective of this project is to enable the student to explorer the vast subject to micro controllers and gain the knowledge about registers, peripherals, drivers and top layer programming of the micro controllers. The project emphasizes on the application of ADC conversion and USB serial port communication. The main objective of the project is to successfully establish a communication between USB and MCU (micro controller unit) using a USB cable and build a complimenting application to support this communication. To begin the project a deep understanding of USB transfer protocols, Stack architecture, control events, client driver architecture and register, target peripheral list of the micro controller is a necessary condition to be satisfied. 

                       The project must be simulated first before doing any practical implementation. The software used for simulation is PROTEUS and CCS compiler for MCU programming. The drivers which are very crucial for the functioning of the project were expected to be dealt with utter care.
 
                      The application can be built using visual basic or any other convenient software.

2Problem Statement
USB Interfacing with PIC micro controller

Establishing a successful communication port for both the devices to be able to send and receive data. The choice of device class is left to the students, they can either choose HID or CDC depending on the convenience.


In order to enumerate a device via USB port, necessary drivers must be provided, these drivers need not necessarily be written by the students themselves but care must be exercised while selecting a third party driver, in case if the drivers are being written by the student then the compatibility issues must be taken care of, but the descriptor file and firmware for the PIC MCU (micro controller unit) must be written entirely by the students. The project can be verified using a simulation and then be implemented on the development board


3Project Methodology: -

a) Workflow: -

·         Begin with reading application notes 1140,1141, 1142
·         Study the hardware architecture of the respective PIC
             In this case it is PIC18F4550  


Important topic to be well aware of before starting any of the steps below

b) OSCILLATOR CONFIGURATIONS

i) Overview

Devices in the PIC18F2455/2550/4455/4550 family incorporate a different oscillator and microcontroller clock system than previous PIC18F devices. The addition of the USB module, with its unique requirements for a stable clock source, make it necessary to provide a separate clock source that is compliant with both USB low-speed and full-speed specifications.
To accommodate these requirements, PIC18F2455/ 2550/4455/4550 devices include a new clock branch to provide a 48 MHz clock for full-speed USB operation. Since it is driven from the primary clock source, an additional system of pre-scalers and post-scalers has been added to accommodate a wide range of oscillator frequencies.
Other oscillator features used in PIC18 enhanced microcontrollers, such as the internal oscillator block and clock switching, remain the same. They are discussed later in this chapter.
ii) OSCILLATOR CONTROL
The operation of the oscillator in PIC18F2455/2550/ 4455/4550 devices is controlled through two Configuration registers and two control registers. Configuration registers, CONFIG1L and CONFIG1H, select the oscillator mode and USB pre-scaler/post-scaler options. As Configuration bits, these are set when the device is programmed and left in that configuration until the device is reprogrammed.
The OSCCON register (Register 2-2) selects the Active Clock mode; it is primarily used in controlling clock switching in power-managed modes.
The OSCTUNE register (Register 2-1) is used to trim the INTRC frequency source, as well as select the low-frequency clock source that drives several special features.

iii) Oscillator Types

PIC18F2455/2550/4455/4550 devices can be operated in twelve distinct oscillator modes. In contrast with previous PIC18 enhanced microcontrollers, four of these modes involve the use of two oscillator types at once. Users can program the FOSC3:FOSC0 Configuration bits to select one of these modes:
1.     XT  Crystal/Resonator
2.     XTPLL         Crystal/Resonator with PLL enabled
3.     HS  High-Speed Crystal/Resonator
4.     HSPLL High-Speed Crystal/Resonator with PLL enabled
5.     EC  External Clock with FOSC/4 output
6.     ECIO          External Clock with I/O on RA6
7.     ECPLL External Clock with PLL enabled and FOSC/4 output on RA6
8.     ECPIO        External Clock with PLL enabled, I/O on RA6
9.     INTHS        Internal Oscillator used as microcontroller clock source, HS Oscillator used as USB clock source
10.   INTXT         Internal Oscillator used as microcontroller clock source, XT Oscillator used as USB clock source
11.   INTIO         Internal Oscillator used as microcontroller clock source, EC Oscillator used as USB clock source, digital I/O on RA6
12.   INTCKO Internal Oscillator used as microcontroller clock source, EC
Oscillator used as USB clock source,
FOSC/4 output on RA6
 c) OSCILLATOR MODES AND USB OPERATION
Because of the unique requirements of the USB module, a different approach to clock operation is necessary. In previous PICmicro devices, all core and peripheral clocks were driven by a single oscillator source; the usual sources were primary, secondary or the internal oscillator. With PIC18F2455/2550/4455/4550 devices, the primary oscillator becomes part of the USB module and cannot be associated to any other clock source. Thus, the USB module must be clocked from the primary clock source; however, the microcontroller core and other peripherals can be separately clocked from the secondary or internal oscillators as before.
Because of the timing requirements imposed by USB, an internal clock of either 6 MHz or 48 MHz is required while the USB module is enabled. Fortunately, the microcontroller and other peripherals are not required to run at this clock speed when using the primary oscillator. There are numerous options to achieve the USB module clock requirement and still provide flexibility for clocking the rest of the device from the primary oscillator source.

1     Proceed by installing PROTEUS and CCS compilers

     Install virtual USB Drivers bundled with PROTEUS

         CCS Library Functions involved in the code
·        usb_cdc_putready()
         Returns TRUE if there is space in the transmit buffer for another character.
·        usb_cdc_putc()
                           The same as putc(), sends a character. It actually puts a character into the transmit buffer, and if the transmit buffer is full will wait indefinitely until there is space for the character.
·         setup_adc
         Sets up the a/d mode like off, the adc clock etc.
·        setup_adc_ports
                           Sets the available adc pins to be analog or digital.
·         set_adc_channel
                           Specifies the channel to be use for the a/d call.
·        lcd_init
         This function initializes LCD to receive data, resets rs and rw pins  Enables lcd. must be called before any other functions
·        lcd_gotoxy
        Set write position on LCD
·        usb_cdc_init
         Initializes the CDC transmit, defines the baud rate, character format and resets the buffers.
·        usb_init 
          Initializes the USB hardware. Will then wait in an infinite loop for the USB peripheral to be connected to bus (but that doesn't mean it has been enumerated by the PC). Will enable and use the USB interrupt
·         usb_cdc_connected
          Returns true if USB is connected to the host
·        read_adc
                       Reads the result of the last conversion and store it in //value. Assuming the device is a 10bit ADC module, //value will range between 0-3FF. If #DEVICE ADC=8 had //been used instead the result will yield 0-FF if
#DEVICE //ADC=16 had been used instead the result will yield 0-//FF

·        usb_task
                         If you use connection sense, and the usb_init_cs() for initialization, then you must periodically call this function to keep an eye on the connection sense pin. When the PIC is connected to the BUS, this function will then perpare the USB peripheral. When the PIC is disconnected from the BUS, it will reset the USB stack and peripheral. Will enable and use the USB interrupt.

·        usb_kbhit
                       Returns true if OUT endpoint contains data from the host

·        usb_cdc_getc
                      The same as getc(), reads and returns a character from the receive buffer.
If there is no data in the receive buffer, it will wait indefinitely until there a character has been received

·        lcd_putc
       will display the passed argument on the next position of the cursor

d) CODE: - (CCS Code)
#include <18F4550.h>
#device adc=10   
#fuses
HSPLL, MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOPBADEN
#use delay(clock=20000000)   
#include "LCD.C"

#include "usb_cdc.h"
#include "usb_desc_cdc.h"
#include "stdlib.h"
char TEXT []={"                                                               "};
char RECIEVE[],string[]={"0000"};
int d,n,t=0,w,temp;
int digital_reading; 

void put_temp(){
            if(usb_cdc_putready()){
        
            usb_cdc_putc(temp);}
}
void main() {
      setup_adc(ADC_CLOCK_INTERNAL);
      setup_adc_ports(AN0|VSS_VDD);
      set_adc_channel(0);           
      lcd_init();
      usb_cdc_init();
      usb_init();   
     
      while(!usb_cdc_connected())
      do{
     
      DELAY_MS(100);
      digital_reading = read_adc();   
      if(temp != digital_reading){
      temp = digital_reading;
    
     
      put_temp();
     
      }
     
      usb_task();
     
      if(usb_cdc_kbhit()){            
            RECIEVE=usb_cdc_getc();
            switch(RECIEVE){
         
            case '\b'  : lcd_gotoxy(17,1);break;
            case '\v'  : lcd_putc('\v');break;
            case '\f'  : lcd_putc('\f');break;
           
         default    : lcd_putc(RECIEVE);break;
        }
       
        //put_temp();
       
        }               
      }
      while (true);
}

Compile this code to create a firmware file.

Create the Proteus schematic as shown below in the designs section and upload the generated firmware into the corresponding MCU
Install the drivers and verify if at all any COM port is created,
and then we have to create a GUI using visual basics or any convenient software to communicate through the COM port that has been created.

e) Code: - (Visual Basics)
Imports System
Imports System.Threading
Imports System.IO.Ports
Imports System.ComponentModel

Public Class Form1
    Dim myPort As Array
    Delegate Sub SetTextCallback(ByVal [text] As String)

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles WRITEButton.Click
        SerialPort1.Write(INPUTTextBox.Text & vbCr)
    End Sub
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles INTButton.Click
        SerialPort1.PortName = PORTComboBox.Text
        SerialPort1.BaudRate = RATEComboBox.Text
        SerialPort1.Open()

        INTButton.Enabled = False
        WRITEButton.Enabled = True
        CLOSEButton.Enabled = True

    End Sub
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles CLOSEButton.Click
        SerialPort1.Close()
        INTButton.Enabled = True
        WRITEButton.Enabled = False
        CLOSEButton.Enabled = False
    End Sub


    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        myPort = IO.Ports.SerialPort.GetPortNames()
        PORTComboBox.Items.AddRange(myPort)

        WRITEButton.Enabled = False
    End Sub


    Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        ReceivedText(SerialPort1.ReadExisting())
    End Sub
    Private Sub ReceivedText(ByVal [text] As String)
        If Me.OUTPUTTextBox.InvokeRequired Then
            Dim x As New SetTextCallback(AddressOf ReceivedText)
            Me.Invoke(x, New Object() {(text)})
        Else
            Me.OUTPUTTextBox.Text &= [text]
        End If
    End Sub

End Class


4Project Design

       a) Proteus circuit Diagram



 b)  Windows Form Application Design for Interface between
COM Port and MCU




5) Results: -


6) CONCLUSION


As an intern we were exposed to Instrumentation and Control Department. Throughout our internship, we could understand more about a micro-controller and its programming and peripherals and Not only did we gain the practical skills but also had the opportunity to meet many fantastic people. Along our training period, we realized that the observation is the main element to find the root cause of a problem. Not only for our project but also daily activities. During our project, our cooperation with the colleagues and operators was a deterministic factor. Moreover, the project indirectly enabled us to learn independently, to be considerate/patient, self-motivated and taking initiatives. Besides, our communication skills strengthened as well while interacting with various people. During our training period, we received criticism and advice from scientists and technician when mistakes were made. However, those advises were useful in order to change ourselves and avoid making the same mistakes again. Apart from that, we also developed our programming skills by working on various compilers. This also helped us enhance our skills in Visual Basics, MPLAB, MikroC and Proteus. To sum it up, the activities that we learnt during industrial training will probably come in handy in the future while handling challenges in a working environment.