electronics forum

Rules | Recent posts | topic RSS | Search | Register  | Log in

help on Serial Communication using software not UART


Post new topic  Reply to topic    EDAboard.com Forum Index -> Microcontrollers -> help on Serial Communication using software not UART
Author Message
ece4afe



Joined: 16 Jun 2005
Posts: 16


Post22 Apr 2006 17:31   

uart serial communication


hello,

Pls advise me how to implement serial communication tru software programming. il be using a pic16f84a which doesnt have a built in UART. I know the theory of serial communication and I want to implement it thru software programming. Please teach me how to program it or if you have sample code for me to read and understand. This is my first time to program serial communication. my plan is to send ASCII characters from PIC to PC, which will be seen in the hyperterminal. I want to realize and appreciate the theory of serial communication.
Please help me on this.

Tnx,

Chris
Back to top
hermin



Joined: 19 Apr 2005
Posts: 135
Helped: 9


Post22 Apr 2006 17:50   

m_rs096.asm


first choose what programming language you would use so that your computer and mcu would communicate, you could use either C, visual basic and even matlab. For the mcu, you could either make one input be a serial input by just creating a program that would make that port receive serial data
Back to top
BeeBop



Joined: 19 Feb 2006
Posts: 161
Helped: 15


Post23 Apr 2006 3:46   

what is line feed in serial communication


Hi Chris,
I thought I had some of my own examples, but it has been a long time since I did anything with an F84, however, I did find something that is nicely coded, and should serve you well. I think it came from:http://www.electronic-engineering.ch/microchip/index.html
which is a helpful page. (and you may need some other header files from there)
Anyway, here is the example, I hope it works for you.
Best wishes,
Robert

PS, yes you will need to go to his site and get the m_wait, and m_bank files, but should you have any problems, let me know, and I'll help you as much as I can.
regards

Code:
;***************************************************************************
;                                                                     
;   RS232 Communication Test for PIC 16XXX
;   ======================================
;
;   written by Peter Luethi, 26.03.1999, Dietikon, Switzerland
;   http://www.electronic-engineering.ch
;   last update: 11.04.2004
;
;   V1.02:   Fixed copy/paste issue of ISR context store/restore
;      (nobody is perfect): Erroneously erased INTCON,INTF
;      clearing, resulting in endless ISR calling...
;      Re-structured entire ISR and RS232 echo sub-routines
;      (11.04.2004)
;   V1.01:   ISR context restore improvements (30.12.2000)
;   V1.00:   Initial release (26.3.1999)
;
;   This code and accompanying files may be distributed freely and
;   modified, provided this header with my name and this notice remain
;   intact. Ownership rights remain with me.
;   You may not sell this software without my approval.
;
;   This software comes with no guarantee or warranty except for my
;   good intentions. By using this code you agree to indemnify me from
;   any liability that might arise from its use.
;
;   
;   SPECIFICATIONS:
;   ===============
;   Processor:         Microchip PIC 16F84
;   Clock Frequency:      4.00 MHz XT
;   Throughput:         1 MIPS
;   Baud Rate:         9600 baud, 8 bit, no parity, 1 stopbit
;   Code Size of entire Program:   approx. 570 instruction words
;   Required Hardware:      MAX 232, dot matrix LCD display
;
;
;   DESCRIPTION:
;   ============
;   Developed and tested on PIC 16F84, executeable on all interrupt
;   featured PICs.
;   Program handles all aspects of
;      Transmission (Register TXD) and
;      Reception (Register RXD) through interrupt.
;   Display of received ASCII characters sent from RS232 host and
;   their decimal representation on the dot matrix LCD display.
;   The microcontroller sends feedback of received characters back to
;   the terminal window.
;
;***************************************************************************

;***** COMPILATION MESSAGES & WARNINGS *****

   ERRORLEVEL -207    ; found label after column 1
   ERRORLEVEL -302    ; register in operand not in bank 0

;***** PROCESSOR DECLARATION & CONFIGURATION *****

   PROCESSOR 16F84
   #include "p16f84.inc"
   
   ; embed Configuration Data within .asm File
   __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

;***** MEMORY STRUCTURE *****

   ORG     0x00         ; processor reset vector
     goto    MAIN         ; main program

   ORG     0x04         ; interrupt vector
   goto   ISR         ; Interrupt Service Routine (ISR)

;***** PARAMETERIZATION *****

   CONSTANT LCDWAIT =   0x02   ; LCD wait for initialization
   CONSTANT LCDSPEED =   0x01   ; configure according to PIC clock
   
;***** PORT DECLARATION *****

   #define   TXport   PORTA,0x00   ; RS232 output port, could be
   #define   TXtris   TRISA,0x00   ; any active push/pull port

   LCDtris   equ   TRISB
   LCDport   equ   PORTB

;***** CONSTANT DECLARATION *****

   CONSTANT BASE = 0x0C      ; base address of user file registers

;***** REGISTER DECLARATION *****

   TEMP1   set   BASE+d'0'   ; Universal temporary register
   TEMP2   set   BASE+d'1'   ; ATTENTION !!!
   TEMP3   set   BASE+d'2'   ; They are used by various modules.
   TEMP4   set   BASE+d'3'   ; If you use them, make sure not to use
   TEMP5   set   BASE+d'4'   ; them concurrently! No use in ISR!

   LO   equ   BASE+d'5'
   LO_TEMP   equ   BASE+d'6'

   FLAGreg   equ   BASE+d'7'
   #define   RSflag   FLAGreg,0x00   ; RS232 data reception flag
   #define LCDbusy FLAGreg,0x01   ; LCD busy flag
   #define   LCDcflag FLAGreg,0x02   ; LCD command/data flag
   #define   BCflag   FLAGreg,0x04   ; blank checker for preceeding zeros

   TXD   equ   BASE+d'8'   ; TX-Data register
   RXD   equ   BASE+d'9'   ; RX-Data register

   W_TEMP   equ   BASE+d'10'   ; context register (ISR)
   STATUS_TEMP equ   BASE+d'11'   ; context register (ISR)
   PCLATH_TEMP equ   BASE+d'12'   ; context register (ISR)
   FSR_TEMP equ   BASE+d'13'   ; context register (ISR)

;***** INCLUDE FILES *****

   #include "..\..\m_bank.asm"
   #include "..\..\m_wait.asm"
   #include "..\..\m_lcd_bf.asm"
   #include "..\..\m_lcdv08.asm"
   #include "..\..\m_rs096.asm"   ; standard RS232 baud rate

;***** MACROS *****

;***** SUB-ROUTINES *****

RSservice
   LCD_DDAdr 0x45
   movfw   RXD      ; get received RS232 data
   LCDw         ; send to LCD display
   LCD_DDAdr 0x4D
   movfw   RXD
   movwf   LO
   LCDval_08      ; display decimal value
   
   SEND   TAB
   SEND   'r'
   SEND   'e'
   SEND   'c'
   SEND   'e'
   SEND   'i'
   SEND   'v'
   SEND   'e'
   SEND   'd'
   SEND   ' '

   movfw   RXD      ; get received RS232 data
   SENDw         ; transmit across RS232

   SEND   ' '
   SEND   'o'
   SEND   'n'
   SEND   ' '
   SEND   'M'
   SEND   'i'
   SEND   'c'
   SEND   'r'
   SEND   'o'
   SEND   'c'
   SEND   'h'
   SEND   'i'
   SEND   'p'
   SEND   ' '
   SEND   'P'
   SEND   'I'
   SEND   'C'
   SEND   '1'
   SEND   '6'
   SEND   'F'
   SEND   '8'
   SEND   '4'
   SEND   CR      ; Carriage Return
   SEND   LF      ; Line Feed

   ; end of RS232 service (echo & display)
   bcf   RSflag      ; reset RS232 data reception flag
   bsf   INTCON,INTE   ; re-enable RB0/INT interrupt
   RETURN


;***** INTERRUPT SERVICE ROUTINE *****

ISR   ;************************
   ;*** ISR CONTEXT SAVE ***
   ;************************

   bcf   INTCON,GIE   ; disable all interrupts
   btfsc   INTCON,GIE   ; assure interrupts are disabled
   goto   ISR
   movwf   W_TEMP      ; context save: W
   swapf   STATUS,W   ; context save: STATUS
   movwf   STATUS_TEMP   ; context save
   clrf   STATUS      ; bank 0, regardless of current bank
   movfw   PCLATH      ; context save: PCLATH
   movwf   PCLATH_TEMP   ; context save
   clrf   PCLATH      ; page zero, regardless of current page
   bcf   STATUS,IRP   ; return to bank 0
   movfw   FSR      ; context save: FSR
   movwf   FSR_TEMP   ; context save
   ;*** context save done ***

   ;**************************
   ;*** ISR MAIN EXECUTION ***
   ;**************************
   
   ;*** determine origin of interrupt ***
   btfsc   INTCON,INTF   ; check for RB0/INT interrupt
   goto   _ISR_RS232   ; if set, there was a keypad stroke

   ; catch-all
   goto   ISRend      ; unexpected IRQ, terminate execution of ISR

   ;******************************
   ;*** RS232 DATA ACQUISITION ***
   ;******************************
_ISR_RS232
   ; first, disable interrupt source
   bcf   INTCON,INTE   ; disable RB0/INT interrupt
   ; second, acquire RS232 data
   RECEIVE         ; macro of RS232 software reception
   bsf   RSflag      ; enable RS232 data reception flag
   goto   _ISR_RS232end   ; terminate RS232 ISR properly

   ;***********************************
   ;*** CLEARING OF INTERRUPT FLAGS ***
   ;***********************************
   ; NOTE: Below, I only clear the interrupt flags! This does not
   ; necessarily mean, that the interrupts are already re-enabled.
   ; Basically, interrupt re-enabling is carried out at the end of
   ; the corresponding service routine in normal operation mode.
   ; The flag responsible for the current ISR call has to be cleared
   ; to prevent recursive ISR calls. Other interrupt flags, activated
   ; during execution of this ISR, will immediately be served upon
   ; termination of the current ISR run.
_ISR_RS232error
   bsf   INTCON,INTE   ; after error, re-enable IRQ already here
_ISR_RS232end
   bcf   INTCON,INTF   ; clear RB0/INT interrupt flag
   ;goto   ISRend      ; terminate execution of ISR

   ;*****************************************
   ;*** ISR TERMINATION (CONTEXT RESTORE) ***
   ;*****************************************

ISRend   movfw   FSR_TEMP   ; context restore
   movwf   FSR      ; context restore
   movfw   PCLATH_TEMP   ; context restore
   movwf   PCLATH      ; context restore
   swapf   STATUS_TEMP,W   ; context restore
   movwf   STATUS      ; context restore
   swapf   W_TEMP,F   ; context restore
   swapf   W_TEMP,W   ; context restore
   RETFIE         ; enable global interrupt (INTCON,GIE)

;***** END OF INTERRUPT SERVICE ROUTINE *****


;************** MAIN **************

MAIN   LCDinit         ; LCD Initialization
   RS232init      ; RS232 Initialization
   clrf   FLAGreg      ; initialize all flags

   ;*** START-UP MESSAGE of LCD ***
   LCDchar   'R'
   LCDchar   'S'
   LCDchar   '2'
   LCDchar   '3'
   LCDchar   '2'
   LCDchar   ' '
   LCDchar   'C'
   LCDchar   'o'
   LCDchar   'm'
   LCDchar   'm'
   LCDchar   'u'
   LCDchar   'n'
   LCDchar   'i'
   LCDchar   'c'
   LCDchar   'a'
   LCDchar   '-'

   LCDline   2
   
   LCDchar   't'
   LCDchar   'i'
   LCDchar   'o'
   LCDchar   'n'
   LCDchar   ' '
   LCDchar   'o'
   LCDchar   'n'
   LCDchar   ' '
   LCDchar   'P'
   LCDchar   'I'
   LCDchar   'C'
   LCDchar   '1'
   LCDchar   '6'
   LCDchar   'F'
   LCDchar   '8'
   LCDchar   '4'

   ;*** START-UP MESSAGE to RS232 ***
   ; this is done by reading a look-up table
   ; define amount of table items for start-up message
   #define   tab_size4 d'48'
   movlw   tab_size4   ; store amount of table items in counter
   movwf   TEMP5
   ; transmit message
_ILOOP1   movlw   HIGH WelcomeTable ; get correct page for PCLATH
   movwf   PCLATH      ; prepare right page bits for table read
   movfw   TEMP5      ; get actual count-down value
   sublw   tab_size4   ; table offset: w = tab_size4 - TEMP6
   call   WelcomeTable   ; call lookup table
   SENDw         ; RS232 output
   decfsz   TEMP5,f      ; decrement counter
   goto   _ILOOP1

   WAITX   0x1A,  b'00000111'   ; wait some time

   ; a little bit animation...
   SEND   'a'
   SEND   'n'
   SEND   'i'
   SEND   'm'
   SEND   'a'
   SEND   't'
   SEND   'i'
   SEND   'n'
   SEND   'g'
   SEND   ' '
   SEND   'L'
   SEND   'C'
   SEND   'D'
   SEND   '.'
   SEND   '.'
   SEND   '.'
   SEND   CR      ; Carriage Return
   SEND   LF      ; Line Feed

   movlw   d'16'
   movwf   TEMP5
_SHL1   LCDcmd   LCDSL      ; shift left LCD display content
   WAIT   0xC0
   decfsz   TEMP5,f
   goto   _SHL1

   ; finally, reset/clear LCD
   LCDcmd   LCDCLR
   
   LCDchar   'R'
   LCDchar   'S'
   LCDchar   '2'
   LCDchar   '3'
   LCDchar   '2'
   LCDchar   ' '
   LCDchar   'R'
   LCDchar   'e'
   LCDchar   'c'
   LCDchar   'e'
   LCDchar   'p'
   LCDchar   't'
   LCDchar   'i'
   LCDchar   'o'
   LCDchar   'n'
   LCDchar   ':'

   LCDline   2
   
   LCDchar   'C'
   LCDchar   'h'
   LCDchar   'a'
   LCDchar   'r'
   LCD_DDAdr 0x47
   LCDchar   'V'
   LCDchar   'a'
   LCDchar   'l'
   LCDchar   'u'
   LCDchar   'e'

   SEND   'r'
   SEND   'e'
   SEND   'a'
   SEND   'd'
   SEND   'y'
   SEND   '.'
   SEND   '.'
   SEND   '.'
   SEND   CR      ; Carriage Return
   SEND   LF      ; Line Feed
   
   ;******************************
LOOP   btfsc   RSflag      ; check RS232 data reception flag
   call   RSservice   ; if set, call RS232 echo & LCD display routine
   goto   LOOP
   ;******************************

   ;ORG   0x230      ; if necessary, move look-up tables

WelcomeTable
   addwf   PCL,F      ; add offset to table base pointer
   retlw   CR
   retlw   LF
   DT   "Microchip PIC16F84 connected and stand-by..." ; create table
   retlw   CR
WTableEND retlw   LF
   IF (HIGH (WelcomeTable) != HIGH (WTableEND))
      ERROR "WelcomeTable hits page boundary!"
   ENDIF

   END
Back to top
Google
AdSense
Google Adsense




Post23 Apr 2006 3:46   

Ads




Back to top
ece4afe



Joined: 16 Jun 2005
Posts: 16


Post24 Apr 2006 9:34   

uart theory


hello,

my target is to have a serial communication, which is purely software, no UART since f84 has no built in uart, and no interrupt as well. So therefore the program will look like this manner,

let say if i want to send capital C which is 43hex, to PC, i will send first the start bit which is a logic zero, then delay (9600kbps--->about 104us) then the data which is the letter C(01000011 in binary), where in, MSB first, then delay again, then the next bit, delay...............until I arrive at Last or LSB, delay then the stop bit, which is a logic one.

I am using C in programming.

Could you give me atleast a hint on how to attack this problem

Regards,

Chris
Back to top
hermin



Joined: 19 Apr 2005
Posts: 135
Helped: 9


Post24 Apr 2006 13:30   

communicate using uart in c


I believe the best thing you could use will be a constant bit rate, serial communication. and i also recommend to use a null character instead of a start or stop bit,
Back to top
BeeBop



Joined: 19 Feb 2006
Posts: 161
Helped: 15


Post24 Apr 2006 15:44   

how does software read serial communication


Chris,
If you looked at the assembly I gave you, it is for a 16F84, which I realize has no hardware UART. And if you look at the data sheet for your PIC you will find, on page 3 that it has:
Quote:
• Four interrupt sources:
- External RB0/INT pin
- TMR0 timer overflow
- PORTB<7:4> interrupt on change
- Data EEPROM write complete

You didn't say how you were programming it, but you did say you wanted
Quote:
to realize and appreciate the theory of serial communication
which led me to believe you wanted something in assembly. While C is closer to the hardware than most high level languages, it is still a high level language, and you will not get as much out of it as you would assembly. That said, which C compiler are you using? They each have thier own ways of producing hex code, and some even include some libraries. In many compilers, to get the right timing, you will have to inline assembly, at least for the delays, for this to work well.
If I remember, too, you send the LSB first, not the MSB.
Basically, you loop through the byte you want to send. Your line is high in idle, you clear it to send a start bit, then call your delay. Read the first bit of the data you wish to send. If it is a one, then set your pin and call your delay. (This is where is gets tricky with C - how many cycles does it take to get into the dely with your compiler?) Then you shift your bite to the right, and check the next bit. If your bit is high, set the pin. If your bit is low, clear the pin. Then call your delay again. Do this until you have shifted your byte out, and when you are done, send the stop bit.
I would recomend sending just one char until you have it working.
If you are just sending from the PIC, not receiving, you should be able to do it without interrupts, unless you choose to use them for timing.
Again, which compiler are you using?
Regards,
Robert

PS here is a tutorial on software serial comms:http://www.sparkfun.com/commerce/present.php?p=The%20Serial%20Biggie%20Page1
Back to top
Arabic versionBulgarian versionCatalan versionCzech versionDanish versionGerman versionGreek versionEnglish versionSpanish versionFinnish versionFrench versionHindi versionCroatian versionIndonesian versionItalian versionHebrew versionJapanese versionKorean versionLithuanian versionLatvian versionDutch versionNorwegian versionPolish versionPortuguese versionRomanian versionRussian versionSlovak versionSlovenian versionSerbian versionSwedish versionTagalog versionUkrainian versionVietnamese versionChinese version
Post new topic  Reply to topic    EDAboard.com Forum Index -> Microcontrollers -> help on Serial Communication using software not UART
Page 1 of 1 All times are GMT + 1 Hour
Similar topics:
Communication Controller >> Serial UART in Verilog Nee (1)
How to Create UART with Software (not used SBUF) on 8051 (7)
GSM with 8051 controller-not able to do serial communication (2)
Software UART for 8051 Using Embedded C (1)
Nice Serial communication monitor software (1)
Serial Communication Using VB (2)
Serial Communication using I2C (19)
Serial communication using Matlb... (2)
Y I can't compile pass using VC++ (Serial communication) (2)
Rx/Tx serial communication via Hyperteminal using PIC18f.. (2)


Abuse || Administrator || Moderators || Support us || sitemap
topic RSS