Interface PIC16F887 with PC (VB.net)

Discussion about projects that used PIC Microcontroller, Hardware Interface, Programming Algorithm and etc......

Interface PIC16F887 with PC (VB.net)

Postby kangory » Sun Sep 15, 2013 4:43 am

Hello ..I'm doing my FYP and am having problems with getting data from the PC (vb.net) to the microcontroller (PIC16f887) that will be displayed in LCD 2x16 .. The problem for example I wanna send (hello) to the microcontroller so I get ( hlo) instead of ( hello ) or sometimes i get the 3rd digit or char that am sending from the textbox in VB.net.. for the communication between the PIC and PC am using USB to UART converter ( UC00B ) and am using (SK40C) for the microcontroller .

Plz if there anyone could help with this or anyone has similar code .. Thanx in advance :)

here are my codes

PIC16F887 code:

CODE: SELECT_ALL_CODE
 

//========================================================================
//   include
//========================================================================
#include <pic.h>

//========================================================================
//   Configuration
//========================================================================
__CONFIG(FOSC_HS &            //External Crystal at High Speed
       WDTE_OFF &            //Disable Watchdog Timer
       PWRTE_ON  &                   //Enable Power Up Timer
       BOREN_OFF &                  //Disable Brown Out Reset
       MCLRE_ON &            //MCLR function is enabled
       LVP_OFF);            //Disable Low Voltage Programming

//=========================================================================                           
//   Define
//=========================================================================
#define   rs         RB4            //RS pin of the LCD display   
#define   e         RB5            //E pin of the LCD display
#define   b_light      RC1            //backlight of the LCD display (1 to on backlight)
#define   SW1         RB0            //button (active low)
#define   SW2         RB1            //button (active low)
#define   lcd_data           PORTD                //LCD 8-bit data PORT
#define   LED1             RB6                  //led 1 (active high)
#define   LED2              RB7                 //led 2 (active high)

//===========================================================================
//   Function prototype            
//===========================================================================
void delay(unsigned long data);         
void send_config(unsigned char data);
void send_char(unsigned char data);
void lcd_goto(unsigned char data);
void lcd_clr(void);
void send_string(const char *s);
unsigned char uart_rec(void);
void beep(void);

void uart_send(unsigned char data);
void uart_str(const char *s);
void send_cmd(unsigned char num, unsigned int data, unsigned int ramp);

//===========================================================================
//   Main function            
//===========================================================================
void main(void)
{
                                                      
   unsigned char a;                                 
      
   PORTA = 0;                     // Clear Port
   PORTB = 0;
   PORTC = 0;
   PORTD = 0;

   TRISA = 0b00000000;               // set PortA as OUTPUT
   TRISB = 0b00000011;               // set PORTB<1:0> as INPUT
   TRISC = 0b00000000;
   TRISD = 0b00000000;               // set PORTD as OUTPUT
      
   ANSEL = 0;                  // Set PORTA as Digital I/O   for PIC16F887
   ANSELH = 0;                   // SET PORTB as DIGITAL I/O for PIC16F887

   
   //setup USART
   SPBRG = 0x81;                  //set baud rate to 9600 for 20Mhz
   BRGH = 1;                     //baud rate high speed option
   TXEN = 1;                     //enable transmission
   CREN = 1;                     //enable reception
   SPEN = 1;                     //enable serial port
   TX9 =0;            //8-bit transmission
   RX9 =0;            //8-bit reception
   
   
   //setup ADC
   ADCON1 = 0b00000110;            //set ADx pin digital I/O
   
   //configure lcd
   send_config(0b00000001);         //clear display at lcd
   send_config(0b00000010);         //lcd return to home
   send_config(0b00000110);         //entry mode-cursor increase 1
   send_config(0b00001100);         //display on, cursor off and cursor blink off
   send_config(0b00111000);         //function set
         
   
//infinity loop

//uart_init();      
while(1)
   {
      CREN=1;
         a = uart_rec();
      lcd_clr();      
      lcd_goto(0);
      send_string("The value is:");   
      lcd_goto(20);   
      send_char(a);

        CREN=0;   
      }
      
   }                  

//===========================================================================
//   Functions
//===========================================================================

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

void send_config(unsigned char data)   //send lcd configuration
{
   rs=0;                        //set lcd to configuration mode
   lcd_data=data;                  //lcd data port = data
   e=1;                        //pulse e to confirm the data
   delay(50);
   e=0;
   delay(50);
}

void send_char(unsigned char data)      //send lcd character
{
   rs=1;                        //set lcd to display mode
   lcd_data=data;                  //lcd data port = data
   e=1;                        //pulse e to confirm the data
   delay(10);
   e=0;
   delay(10);
}

void lcd_goto(unsigned char data)      //set the location of the lcd cursor
{                              //if the given value is (0-15) the
    if(data<16)                     //cursor will be at the upper line
   {                           //if the given value is (20-35) the
       send_config(0x80+data);         //cursor will be at the lower line
   }                           //location of the lcd cursor(2X16):
   else                        // -----------------------------------------------------
   {                           // | |00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15| |
       data=data-20;               // | |20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35| |
      send_config(0xc0+data);         // -----------------------------------------------------   
   }
}

void lcd_clr(void)                  //clear the lcd
{
    send_config(0x01);
   delay(600);   
}

void send_string(const char *s)         //send a string to display in the lcd
{         
   unsigned char i=0;
     while (s && *s)send_char (*s++);

}

unsigned char uart_rec(void)         //receive uart value
{
   unsigned char rec_data;
   while(RCIF==0);                  //wait for data
   rec_data = RCREG;            
   return rec_data;               //return the data received
}

void uart_send(unsigned char data)
{
while(TXIF==0); //only send the new data after
TXREG=data; //the previous data finish sent
}
 
void uart_str(const char *s)
{
while(*s)uart_send(*s++); // UART sending string
}




The VB code :

CODE: SELECT_ALL_CODE

Imports System.IO.Ports
Public Class Form2

    Delegate Sub AddText(ByVal Text As String)
    Dim myEnc As System.Text.Encoding = System.Text.Encoding.GetEncoding(28591)

    Private Sub SerialPort1_DataReceived(ByVal sender As Object, _
                       ByVal e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        Dim br As Integer = SerialPort1.BytesToRead
        If br > 0 Then
            Dim b(br - 1) As Byte
            br = SerialPort1.Read(b, 0, br)
            Dim s As String = myEnc.GetChars(b)
            RichTextBox1.Invoke(New AddText(AddressOf RichTextBox1.AppendText), s)
        End If
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If SerialPort1.IsOpen Then
            SerialPort1.Close()
        Else
            Try
                SerialPort1.PortName = "COM8"
                SerialPort1.BaudRate = 9600
                SerialPort1.Encoding = myEnc
                SerialPort1.Open()
                MsgBox("The port is open", MsgBoxStyle.Information)
            Catch ex As Exception
                MessageBox.Show(ex.ToString)
            End Try
        End If
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        SerialPort1.Write(TextBox1.Text)
 
    End Sub

kangory
Freshie
 
Posts: 5
Joined: Sat Jul 27, 2013 6:49 am

Re: Interface PIC16F887 with PC (VB.net)

Postby yonghui » Tue Sep 17, 2013 10:46 am

use interrupt for uart_rec function.

your while(1) loop takes too long time that cause the controller to miss the bytes from computer.

while(1)
{
CREN=1;
a = uart_rec();
lcd_clr();
lcd_goto(0);
send_string("The value is:");
lcd_goto(20);
send_char(a);

CREN=0;
}

}




lcd_clr() and send_string function takes very long time.
thanks&regards,
yh
yonghui
Moderator
 
Posts: 732
Joined: Mon Sep 28, 2009 3:27 pm

Re: Interface PIC16F887 with PC (VB.net)

Postby kangory » Tue Sep 17, 2013 11:55 am

Thanx for your reply yonghui , Yeah you are right it takes long time, i modified it as shown below and I got the complete data, but the problem now i wanna put the data that it get from the PC in the 2nd line of the LCD.

CODE: SELECT_ALL_CODE
 while(1)
{
CREN=1;
        uc_uart_receive();
   a=RCREG;   
   send_char(a);
CREN=0;
}
}


I have tried interrupt code below for uart_rec function, but nothing has changed :(.. please if you could help me with this.
Thank you :)

CODE: SELECT_ALL_CODE
static void interrupt isr(void)
{
if(RCIF==1){
   data[z]=uart_rec();
   if(z<29) z++;
   y=z;
   counter=0;
   send=1;}
if(TMR0IF==1){
   TMR0IF=0;
   if(counter<COUNT) counter++;
   else z=0;}
}
kangory
Freshie
 
Posts: 5
Joined: Sat Jul 27, 2013 6:49 am

Re: Interface PIC16F887 with PC (VB.net)

Postby yonghui » Tue Sep 17, 2013 12:51 pm

u will need to enable interrupt in your code.

enable receive interrupt enable register,
enable peripheral interrupt , PEIE,
enable global interrupt, GIE,
refer datasheet on more details on setup UART for receive.

for the processing in the interrupt, i think u make the data receive in packet.
for example packet of 10 bytes. then after u receive ten bytes in buffer, then u can set a flag,
when main program detect the flag, then it start processing the the data to display, and off the interrupt to prevent override of your buffer, by possibly incoming data interrupt. OR, u make a double buffer for it.
thanks&regards,
yh
yonghui
Moderator
 
Posts: 732
Joined: Mon Sep 28, 2009 3:27 pm

Re: Interface PIC16F887 with PC (VB.net)

Postby kangory » Tue Sep 17, 2013 1:24 pm

I did it and this time i get it different , for example i send " hello" i get "o" or "12345" i get the "5" only.
plz if u could just show me example. thanx

CODE: SELECT_ALL_CODE
RCIE = 1;   
GIE = 1;
PEIE = 1;
kangory
Freshie
 
Posts: 5
Joined: Sat Jul 27, 2013 6:49 am

Re: Interface PIC16F887 with PC (VB.net)

Postby kangory » Tue Sep 17, 2013 2:26 pm

I get done :) Thanx for ur help , but i have small problem which in the while(1) loop i put sw1, if it pressed will transmit data for example "1" it does transmit , but its send many "1s" as "1111111111111111111" . i tried "if" and "while" but still the same
.. but if i put out of the while loop it works fine but only once as shown below

CODE: SELECT_ALL_CODE

while (SW1 == 0)
uart_putstr("1");

while (1)
   {
   while (SW1 == 0){
      uart_putstr("1");
   }
   if (SW2 == 0){
      uart_putstr("2");
   }


here is my uart_putstr function
CODE: SELECT_ALL_CODE

void uart_putstr(const char* csz_string)
{
   // Loop until the end of string.
   while (*csz_string != '\0') {
      uart_transmit(*csz_string);   
      // Point to next character.
      csz_string++;
   }
}



plz if u could help me with this . Thanx a lot :)
kangory
Freshie
 
Posts: 5
Joined: Sat Jul 27, 2013 6:49 am

Re: Interface PIC16F887 with PC (VB.net)

Postby yonghui » Tue Sep 17, 2013 3:38 pm

microcontroller is fast in this case. when u press the switch and while the switch is still pressed (0), it keep sending out.


change to this:

CODE: SELECT_ALL_CODE
while(1)
{
 if(SW1==0)
{while(SW1==0);
send_str("sw1");

if(SW2==0)
{
while(SW2==0);
send_str("sw2");
}
}
thanks&regards,
yh
yonghui
Moderator
 
Posts: 732
Joined: Mon Sep 28, 2009 3:27 pm

Re: Interface PIC16F887 with PC (VB.net)

Postby kangory » Tue Sep 17, 2013 8:12 pm

It works fine now .....You are the best ... Thanx a million :D
kangory
Freshie
 
Posts: 5
Joined: Sat Jul 27, 2013 6:49 am


Return to PIC Microcontroller

Who is online

Users browsing this forum: No registered users and 24 guests