Serial Io Pic

  • October 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Serial Io Pic as PDF for free.

More details

  • Words: 1,063
  • Pages: 6
Serial I/O with a PIC I was working on a project to control a stepper motor from a PC serial port. I needed to receive characters from the serial port, and change the motor actions based on the character received. The sample code shown here demonstrates how to receive characters from a serial line. The source code is shown below. Alternatively, you can click here to save the source onto your system, or download the hex code to download directly into the PIC. It is based on source from Tom Coonan that I simplified by restricting it to 9600 baud, 8-N-1 settings. If the digit 1 is received then it turns on an LED connected to pin RB4, if a digit 0 is received, it turns off the LED. The LED is driven via a 1K resistor. There is a 10K resistor between pin 3 of the serial plug and pin RA0 on the PIC to reduce the current into the pin. Connect a serial line to your computer, and wire the TX line of the serial cable to pin RA0, via a resistor. Start up a terminal program on the PC and set the terminal settings to 9600 baud 8-N-1. On Windows you will have to choose a COM port that corresponds to your computer's serial device. On Linux, I ran minicom configured to use port /dev/ttyS0, which corresponds to COM1 in Windows. ;

; led-ctrl.asm ; ; Accept serial data at 9600 8N1 and interpret it ; If a '1' is received, turn on an LED connected to RB4 ; If a '0' is received, turn off the LED connected to RB4 ; ; Serial TX line is connected via a 10K resistor to RA0 ; ; PORT MAP ; ; PORTA ; 0 Input Serial ; ; PORTB ; 4 Output LED ; ; Based on code by Tom Coonan ; ; Copyright 1998-2003 Mark Crosbie 9/29/98 ; include p16c84.inc

radix dec processor 16c84 SERIAL_BIT LED_BIT

equ

0 equ

; Bit 0 on PORTA 4 ; Bit 4 on PORTB

;**** Application's Memory Variables INCHAR equ 0xc ; Input character COUNTHI equ 0x10 ; Counter for Delay routine (MSB) COUNTLO equ 0x11 ; Counter for Delay routine (LSB) DELAYHI equ 0x12 ; Argument for DELAY subroutine (MSB) DELAYLO equ 0x13 ; Argument for DELAY subroutine (LSB) MASK equ 0x14 ; Mask register for each serial bit input TEMP equ 0x15 ; ; After the baud rates are established through the jumpers, the right ; delay constants are written into here. These are the constants ; used in all the run-time delays for serial. ; DELAY_HALF_SERIAL_HI equ 20 ; DELAY_HALF_SERIAL_LO equ 21 ; DELAY_FULL_SERIAL_HI equ 22 ; DELAY_FULL_SERIAL_LO equ 23 ; ;*** End MEMORY Registers ********************************** ; DELAY Constants. ; ; Delays were set emperically - using a Logic Analyzer and ; looking at peek signals for bit timing. ASSUMES the ; current design's 4MHz crystal, of course. DELAY_FULL_9600_HI equ 1 DELAY_FULL_9600_LO equ 25 DELAY_HALF_9600_HI equ 1 DELAY_HALF_9600_LO equ 12 DELAY_50MS_HI DELAY_50MS_LO

equ 0x34 equ 0x95

org 0 ; Reset Vector goto Start ; Main entry point of program ;**************************************** ; *

; Start Up Initializtion Stuff * ; * ;**************************************** ; Remember, INCHAR started out as all zeros.. ; Therefore, we only need to SET bits (when PORTA:0 = 0V) ; Also, remember, serial is inverted: ; 0V on PORTA:0 indicates a logic '1' ; 5V on PORTA:0 indicates a logic '0' ; ; The MASK variable is maintained by caller. ; ; GetSerialBit nop nop btfsc PORTA, SERIAL_BIT ; Get PORTA with a 'POSITIVE' serial bit on it retlw 0 ; Do nothing if we got 5V, or logic '0' GetSerialBitIsClr movf MASK, W iorwf INCHAR, f retlw 0

; SET the bit

;*********************************************************** ; * ; Specific Delay Functions. These are specific delays * ; which load specific delay counts. These routines then * ; call the generic DELAY subroutine. * ; * ;*********************************************************** DelayHalfSerial movf DELAY_HALF_SERIAL_HI, W movwf DELAYHI movf DELAY_HALF_SERIAL_LO, W movwf DELAYLO retlw 0 DelayFullSerial ; Baud rate is 9600, so set up accorsingly movf DELAY_FULL_SERIAL_HI, W movwf DELAYHI movf DELAY_FULL_SERIAL_LO, W movwf DELAYLO

retlw 0 Delay50MS movlw DELAY_50MS_HI movwf DELAYHI movlw DELAY_50MS_LO movwf DELAYLO retlw 0 InitDelay200MS call Delay50MS call Delay call Delay50MS call Delay call Delay50MS call Delay call Delay50MS call Delay retlw 0 ; General DELAY routine ; Inputs: ; DELAYHI - Initial Countdown value MSB ; DELAYLO - Initial Countdown value LSB ; Uses: ; COUNTHI - Counter value MSB ; COUNTLO - Counter value LSB Delay movf DELAYHI, W movwf COUNTHI movf DELAYLO, W movwf COUNTLO DelayLoop decfsz COUNTLO goto DelayLoop decfsz COUNTHI goto DelaySetup2 goto DelayDone DelaySetup2 movf DELAYLO, W movwf COUNTLO goto DelayLoop DelayDone retlw 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ***** Main Program Entry !!!

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Start clrf PORTA clrf PORTB ; Set up input and output bits bsf STATUS, RP0 bsf TRISA, SERIAL_BIT bcf TRISB, LED_BIT bcf STATUS, RP0 call call

Delay50MS Delay

; PORTA.0 is input ; PORTB.4 is output

; Wait for tristate to settle...?...

;** Set up Baud Constants movlw DELAY_FULL_9600_HI movwf DELAY_FULL_SERIAL_HI movlw DELAY_FULL_9600_LO movwf DELAY_FULL_SERIAL_LO movlw DELAY_HALF_9600_HI movwf DELAY_HALF_SERIAL_HI movlw DELAY_HALF_9600_LO movwf DELAY_HALF_SERIAL_LO call

InitDelay200MS

;******* START Main Loop Here ************** ; Loop and read characters WaitChar

; Wait for start bit clrf INCHAR ; clear the input character movlw B'00000001' ; start out at bit 0 movwf MASK btfss PORTA, SERIAL_BIT ; If we get a '1' or a START bit, skip! goto WaitChar ; Nope.. no start bit. Keep looking ; Got an edge! nop nop call call btfss goto

DelayHalfSerial ; Delay half a bit Delay PORTA, SERIAL_BIT ; Serial bit *should* be zero. WaitChar ; False alarm..

BitLoop ; Delay one bit time call DelayFullSerial call Delay call GetSerialBit ; Get Bit into INCHAR bcf STATUS, C rlf MASK, F btfss STATUS, C goto BitLoop

; Clear the carry bit ; shift mask left one bit, thru carry ; is the carry set?

; Delay one bit time for the STOP bit call DelayFullSerial call Delay ; See if the character is 0, if so, turn off the LED movf INCHAR, w sublw '0' btfsc STATUS, Z bcf PORTB, LED_BIT ; turn off the LED btfss STATUS, Z bsf PORTB, LED_BIT ; turn on the LED ; A small pause between each sample call Delay50MS call Delay goto WaitChar end

Related Documents

Serial Io Pic
October 2019 9
7 - Serial Io
November 2019 11
Io
April 2020 29
Io
November 2019 42
Io
November 2019 42