How to read a data frame PC serial over PIC UART

Status
Not open for further replies.

Garry P

New Member
Hi folks,
I am trying to send a data frame over uart of pic12F1572.
I want to send an frame from PC terminal [I use Hterm] in the format "RGBFF00F0\n" and receive it at PIC.
I have done code but somehow I found it's not working
anyone have the idea?
a code ,hint or solution is highly appreciated
thanks a lot
Here is my code
C:
#include <xc.h>
#include "main.h"
#include "config.h"
#include "TYPEDEF_Definitions.h"
#include "PIC_12_Timer0.h"
#include "PIC_12_UART.h"
#include "System_init.h"
#include "Pin_manager.h"
#include "LED.h"
#define BUFFER 0x10


#define _XTAL_FREQ 16000000
// // CONFIG1
// #pragma config FOSC     = INTOSC        //  (INTOSC oscillator; I/O function on CLKIN pin)
// #pragma config WDTE     = OFF           // Watchdog Timer Enable (WDT disabled)
// #pragma config PWRTE    = OFF           // Power-up Timer Disable (PWRT Enabled) //change
// #pragma config MCLRE    = OFF           // MCLR Pin Function Select (MCLR/VPP pin function is MCLR) //change
// #pragma config CP       = OFF           // Flash Program Memory Code Protection (Program memory code protection is disabled)
// #pragma config BOREN    = OFF           // Brown-out Reset Enable (Brown-out Reset disabled)
// #pragma config CLKOUTEN = OFF           // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)

// // CONFIG2
// #pragma config WRT      = OFF           // Flash Memory Self-Write Protection (Write protection off)
// #pragma config PLLEN    = OFF           // PLL Enable (4x PLL disabled)
// #pragma config STVREN   = ON            // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
// #pragma config BORV     = LO            // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
// #pragma config LPBOREN  = OFF           // Low Power Brown-out Reset enable bit (LPBOR is disabled)
// #pragma config LVP      = ON            // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming

// /*



//  */
//----------------Transmiter[Master]----------------------/
void main()
{
   uint8_t color , receivedByte ,data_flag;
   uint8_t input , i;
   uint8_t data [];
   SYSTEM_Initialize();
   LATA = 0x00;
   //TRISA = 0X05;
   UART_Init();                  //Initialize UART
 
   while (1)
   {
 
       if ( UART_DataReady() )            // If data is received,
       {
         //LATAbits.LATA1   = 0;
         receivedByte = UART_Read();
         LATAbits.LATA2   = 1;

         // if ( receivedByte == 'R')
         //       {
         //         LATAbits.LATA1   = 1;
         //       }
      
         for (i = 0; i<20 ; i++)
         {    
             //if ( receivedByte != '\n')
             if ( receivedByte == 'R')
             {
                 data[i] = receivedByte;
                 LATAbits.LATA1   = 1;
             }
             else
             {
                 LATAbits.LATA2   = 0;
                 data = '\0';
                 data_flag = 1;              //set flag
             }
         }


     }

   }
 
Last edited by a moderator:
Where is SYSTEM_Initialize(); code I want to see what the OSCCON is set to!!
 
Hi Garry,
I have some code that runs on a PIC12F1840 that sends and receives serial data. I think the PIC12F1840 and the PIC12F1572 are very similar. It is written in assembler so I don't know if it would be any use to you. I would have no idea how to write the code in "C". If it would be any help I can post it on the forum.

Les.
 
Please repost your code using code tags as I cannot see any indenting and can't work out where sections begin and end.

Edit, a quick look suggest your braces don't match!! 5*{, 6*}

Mike.
 
Last edited:
The way you have indented it shows that the main closing brace is missing (I'm good at counting ;)). However, it could be any of them.

Mike.
Here it is without comment and whitespace so you can see it on one page,
Code:
void main()
{
   uint8_t color , receivedByte ,data_flag;
   uint8_t input , i;
   uint8_t data [];
   SYSTEM_Initialize();
   LATA = 0x00;
   UART_Init();                  //Initialize UART
   while (1)
   {
       if ( UART_DataReady() )            // If data is received,
       {
         receivedByte = UART_Read();
         LATAbits.LATA2   = 1;
         for (i = 0; i<20 ; i++)
         {   
             if ( receivedByte == 'R')
             {
                 data[I] = [/I]receivedByte;
                 LATAbits.LATA1   = 1;
             }
             else
             {
                 LATAbits.LATA2   = 0;
                 data = '\0';
                 data_flag = 1;              //set flag
             }
         }
     }
   }
 
Assuming indentation is correct and baud rate is 9600 baud, the LED will only be on for 1mS - the time it takes to receive the 'R'. Also, unless in other code, the LED pin isn't set to output.

Mike.
Edit, here's the way I would try doing this,
Code:
   while (1){
      if (UART_DataReady()){                 // If data is received,
         for(i=0;i<9;i++)                    //scroll the buffer
             data[i]=data[i+1];
         data[9]=UART_Read();                //insert received char
         if(data[0]=='R'){
            //full packet received so do something with it.
         }
      }
   }
Edit, no need to clear the buffer as values are sent as ascii hex.
 
Last edited:
Ian Rogers , Here is my System Initilaize () code
I am pasting here as it is as my insert->code option for this site takes forever to happen

C:
void SYSTEM_Initialize(void)
{

    PIN_MANAGER_Initialize();
    OSCILLATOR_Initialize();
    WDT_Initialize();
    //UART_Init();
}

void OSCILLATOR_Initialize(void)
{
    // SCS FOSC; SPLLEN disabled; IRCF 16MHz_HF;
    OSCCON = 0x78;
    // TUN 0;
    OSCTUNE = 0x00;
    // Set the secondary oscillator
  
}

void WDT_Initialize(void)
{
    // WDTPS 1:65536; SWDTEN OFF;
    WDTCON = 0x16;
}

void PIN_MANAGER_Initialize(void)
{
    /**
    LATx registers
    */ 
    LATA = 0x00;   

    /**
    TRISx registers
    */   
    TRISA = 0x00;           // 0=output 1 =input direction

    /**
    ANSELx registers
    */ 
    ANSELA = 0x00;          //1 = analog input 0 = digital

    /**
    WPUx registers
    */
    WPUA = 0x3F;
    OPTION_REGbits.nWPUEN = 0;

  
    /**
    APFCONx registers
    */
    APFCON = 0x84;  //RA5 =RX/DT RA4 = TX/CK
 
  
}
 
Last edited by a moderator:
Hello,
I would like to get the code even if it is in the assembler
 
Gary,
The code in post #7 will probably work as is. If it needs commenting better let me know.

Mike.
 
Hello folks , SO by using Hterm now I can send and receive the data, and I have another question , if anybody could know this..I will creat a new thread before that I thank all the people and post my next query here.I have to manipulate the received data [ in the form of RGBXXYYZZMAABBCDD
where RGB is fix value
XX =HEx value for Red color,
YY= Hex value for green and
ZZ= Hex value for Blue LED,
M : mode 0,1,2

AA : hex value for the minimum intensity of glowing
BB : hex value for the maximum intensity of glowing
CC : glowing/blinking period
DD: hex value for the blinking ON/OFF ratio.
Each command line will be finished by “LF (\n)”

Now MY UART works Fine
I can send and receive the data and now I am on the management of the frame, can Anybody help me. any help , code , hint will be highly appreaciated
Here is my code :
Now I have
 
Your problem is you only read the usart once.... Data[] will only ever contain R..
 
Your problem is you only read the usart once.... Data[] will only ever contain R..
So what if I put do{} while(!RCIF) loop in another while loop?
because I am thinking once my all manipuilation of data to operate the LEDs done, I will make it for the forever reception...
 
No... You neen more recievedata = ReadUsart(); as that only gets one byte..
C:
if ( UART_DataReady() )            // If data is received,
       {
         // receivedByte = UART_Read(); // <-- wrong place
         LATAbits.LATA2   = 1;
         for (i = 0; i<20 ; i++)
         {  
           receivedByte = UART_Read(); // <---- read each byte in!!
             if ( receivedByte == 'R')
             {
                 data[i] = receivedByte;
                 LATAbits.LATA1   = 1;
             }
             else
             {
                 LATAbits.LATA2   = 0;
                 data = '\0';
                 data_flag = 1;              //set flag
             }
         }
 
If you check DataReady once and then read 20 bytes, you will get the same value 20 times.

Mike.
 
Status
Not open for further replies.