Mike McLaren - K8LH (Westland, MI) says:
I just finished cleaning up an assembly lanugauge source file for a little 12F683 demo' program that shows one way (of probably many) to do reliable 9600 baud bit-banged serial I/O on this chip... It uses TMR2 generated 104-usec interrupts, as well as interrupt-on-change to detect the start bit, using the built-in 12F683 8-MHz INTOSC... Please feel free to use it if you think it may be useful...
list p=12F683, b=8, c= 102, n=71, t=on, st=off, f=inhx32 ;****************************************************************** ;* * ;* Filename: 12F683 Serial.asm * ;* Author: Mike McLaren, K8LH (k8lh@arrl.net) * ;* Date: 27-Nov-04 (rev 22-Dec-04) * ;* * ;* Test 'bit-banged' 9600 baud serial I/O Routines * ;* Uses 12F683 INTOSC at 8-MHz * ;* * ;* * ;* * ;* MPLab: 7.00 (tabs=8) * ;* MPAsm: 3.90 * ;* * ;****************************************************************** #include <p12f683.inc> errorlevel -302 __config _FCMEN_OFF & _IESO_OFF & _BOD_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTOSC ; ; file register variables ; PROC232 equ 0x20 ;RS-232 Process Latch TXCNT equ 0x21 ;TX-232 bit count TXVAR equ 0x22 ;TX-232 data byte RXCNT equ 0x23 ;RX-232 bit count RXVAR equ 0x24 ;RX-232 data byte ; ; PROC232 flag bits ; RXFLAG equ 0x00 ;1=rx in progress RXCHAR equ 0x01 ;1=rx char available TXFLAG equ 0x02 ;1=tx in progress ; other constants RXPIN equ 0x03 ;RS-232 RX (GP3) TXPIN equ 0x04 ;RS-232 TX (GP4) BAUDX equ .208 ;208 for 9600 baud ; ; file locations used by ISR for saving and restoring the stack ; W_ISR equ 0x70 ;ISR 'W' S_ISR equ 0x71 ;ISR 'STATUS' P_ISR equ 0x72 ;ISR 'PCLATH' ; ; other vars ; PTRL equ 0x78 ;PRTSTR routine PTRH equ 0x79 ;PRTSTR routine ; Hardware notes: ; ; <1> Using INTOSC 8-MHz, 500-nsec instruction cycle ; <2> Using GP3 for 9600 baud 'bit banged' serial input ; <3> Using GP4 for 9600 baud 'bit banged' serial output ; <4> RS-232 signals inverted with MAX232 or 2N7000 drivers ; <5> Using 2700 ohm pull-up resistor on GP3 ; ; This program simply prints a text string to Hyperterminal ; and echos typed characters back to Hyperterminal... ; ; Setup Hyperterminal for 9600, 8, 1, none... Use a MAX232 or ; similar level shifting circuit (I use a pair of 2N7000s) for ; connection between the 12F683 and PC... ; ;****************************************************************** ;* * ;* * ;* * ;* * ;* * ;****************************************************************** org 0x0000 START clrf STATUS ; |B0 movlw b'00010000' ;tx pin in 'stop' condition |B0 movwf GPIO ;setup GPIO latch |B0 goto MAIN ; |B0 ;****************************************************************** ;* * ;* Interrupt Service Routine for 'bit-banged' Serial I/O * ;* * ;* Interrupts are generated every 104-us by TMR2 for 9600 * ;* baud shift operations and by IOC (interrupt on change) * ;* on the RX start bit leading edge on RX pin GP3... * ;* * ;* On detecting the RX start bit leading edge, GP3 IOC is * ;* turned off, RXFLAG is set to indicate rx-in-progress, * ;* RXCNT bit count variable is set, and TMR2 is advanced * ;* by 1/2 bit (52-usec)... Note - advancing TMR2 could * ;* potentially mess up a tx-in-progress, so, don't send & * ;* receive at the same time... * ;* * ;****************************************************************** org 0x0004 ; ; save W and STATUS registers on entry ; ISR movwf W_ISR ;save W-reg |B? swapf STATUS,W ;doesn't change STATUS bits |B? movwf S_ISR ;save STATUS reg |B? clrf STATUS ;bank 0 |B0 movf PCLATH,W ;get PCLATH |B0 movwf P_ISR ;save PCLATH |B0 ; ; 27-Nov-04, test for GP3 (RXPIN) start bit leading edge ; btfss INTCON,GPIF ;IOC "start bit" interrupt? |B0 goto ISR_TX ;no, branch |B0 movf GPIO,W ;yes, read GPIO |B0 bcf INTCON,GPIF ;clear IOC interrupt flag |B0 bsf PROC232,RXFLAG ;indicate RX in progress |B0 movlw d'10' ;10 bits (start + 8 data + stop) |B0 movwf RXCNT ;initialize RX bit counter |B0 movlw BAUDX/2 ; |B0 movwf TMR2 ;inc TMR2 by 1/2 bit (52-usec) |B0 goto ISR_X ;turn off GP3 IOC & exit |B0 ; ; 23-Nov-04, code to test bit-banged serial output... ; RS-232 code processed each 104-usec interrupt for 9,600 baud... ; ISR_TX btfss PROC232,TXFLAG ;TX in progress? |B0 goto ISR_RX ;no, branch |B0 movf TXCNT,W ;get TX bit count |B0 xorlw b'00001011' ;start bit? |B0 btfsc STATUS,Z ;no, branch |B0 goto ISR_TX1 ;yes, send start bit |B0 rrf TXVAR,f ;shift lsb into C |B0 bsf TXVAR,7 ;set bit 7 for stop bits |B0 btfsc STATUS,C ;skip if C=0 |B0 bsf GPIO,TXPIN ;set TX pin |B0 btfss STATUS,C ;skip if C=1 |B0 ISR_TX1 bcf GPIO,TXPIN ;clear TX pin |B0 decf TXCNT,f ;decrement bit counter |B0 btfsc STATUS,Z ;last bit? |B0 bcf PROC232,TXFLAG ;yes, indicate end of TX |B0 ; ; 25-Nov-04, code to test bit-banged serial input... ; ISR_RX btfss PROC232,RXFLAG ;RX in progress? |B0 goto ISR_XIT ;no, branch |B0 bcf STATUS,C ;assume bit=0 |B0 btfsc GPIO,RXPIN ;is it a 0? |B0 bsf STATUS,C ;no, bit=1 |B0 rrf RXVAR,f ;shift bit into RXVAR |B0 decfsz RXCNT,f ;all 10 bits? |B0 goto ISR_XIT ;no, branch |B0 rlf RXVAR,f ;yes, get rid of the stop bit |B0 bcf PROC232,RXFLAG ;clear RX-in-progress flag |B0 bsf PROC232,RXCHAR ;indicate character available |B0 ISR_X bsf STATUS,RP0 ;select bank 1 |B1 movlw b'00001000' ;mask for bit 3 |B1 xorwf IOC,f ;toggle GP3 IOC |B1 bcf STATUS,RP0 ;select bank 0 |B0 ; ISR_XIT bcf PIR1,TMR2IF ;clear TMR2 irq flag |B0 movf P_ISR,W ; |B0 movwf PCLATH ;restore PCLATH |B0 swapf S_ISR,W ; |B0 movwf STATUS ;restore STATUS |B? swapf W_ISR,f ;don't screw up STATUS |B? swapf W_ISR,W ;restore W-reg |B? retfie ;return from interrupt |B? ; ;****************************************************************** ;****************************************************************** ; ; Initialization ; MAIN movlw b'00000111' ; |B0 movwf CMCON0 ;digital I/O |B0 bsf STATUS,RP0 ;bank 1 |B1 clrf ANSEL ;digital I/O |B1 movlw b'01110001' ; |B1 movwf OSCCON ;8-mhz INTOSC system clock |B1 movlw b'00001000' ;GP3 input, all others output |B1 movwf TRISIO ; |B1 ; ; 27-Nov-04, code for interrupt-on-change on GP3 (RXPIN) to detect ; RS-232 RX start bit ; movlw b'00001000' ; |B1 movwf IOC ;set IOC for GP3 input |B1 ; ; wait for INTOSC to become stable before doing anything else ; STABLE btfss OSCCON,HTS ;oscillator stable? |B1 goto STABLE ;no, branch |B1 bcf STATUS,RP0 ;bank 0 |B0 ; ; clear RS-232 flags before turning on interrupts ; clrf PROC232 ;clear process latch variable |B0 ; ; configure TIMER2 for 104-usec interrupts (8-MHz clock)... ; clrf TMR2 ;clear TMR2 register |B0 bsf STATUS,RP0 ;select Bank 1 |B1 bsf INTCON,PEIE ;enable peripheral irqs |B1 clrf PIE1 ;mask all peripheral irqs |B1 bsf PIE1,TMR2IE ;except for TMR2 irqs |B1 bcf STATUS,RP0 ;select Bank 0 |B0 clrf PIR1 ;clear peripheral irq flags |B0 movlw b'00000000' ;pre 1, post 1:1 |B0 movwf T2CON ;for 500-nsec ticks (8-mhz clock) |B0 bsf STATUS,RP0 ;select Bank 1 |B1 movlw BAUDX-1 ;number of 500-nsec ticks |B1 movwf PR2 ;104-usec interrupts |B1 bcf STATUS,RP0 ;select Bank 0 |B0 bsf INTCON,GIE ;enable global irqs |B0 bsf INTCON,GPIE ;enable interrupt-on-change irqs |B0 bsf T2CON,TMR2ON ;start TMR2 |B0 ;****************************************************************** ; ; Print a string ; movlw low GREET ;Greeting string address lo |B0 movwf PTRL ; |B0 movlw high GREET ;Greeting string address hi |B0 movwf PTRH ; |B0 call PRTSTR ;print greeting string |B0 ; ; Echo characters coming from Hyperterminal... ; TEST call RX232 ;receive character |B0 call TX232 ;echo character |B0 goto TEST ; |B0 ;****************************************************************** ;****************************************************************** ; ; TX232 - enter with character to be sent in W ; TX232 btfsc PROC232,TXFLAG ;TX in progress? |B0 goto TX232 ;yes, branch and wait |B0 movwf TXVAR ;stuff character |B0 movlw b'00001011' ; |B0 movwf TXCNT ;set TX bit count |B0 bsf PROC232,TXFLAG ;initiate TX |B0 return ; |B0 ;****************************************************************** ; ; RX232 - exit with received character in W ; RX232 btfss PROC232,RXCHAR ;character available flag? |B0 goto RX232 ;no, loop |B0 movf RXVAR,W ;yes, get character |B0 bcf PROC232,RXCHAR ;clear flag |B0 return ; |B0 ;****************************************************************** ; PRTSTR call GETSTR ;Get a string character |B0 andlw b'11111111' ; |B0 btfsc STATUS,Z ;Last character? |B0 return ;Yes, return |B0 call TX232 ;Output char |B0 incfsz PTRL,F ;Increment pointer |B0 goto PRTSTR ; |B0 incf PTRH,F ; |B0 goto PRTSTR ; |B0 GETSTR movf PTRH,W ; |B0 movwf PCLATH ; |B0 movf PTRL,W ; |B0 movwf PCL ; |B0 GREET dt 0x1b, 0x5b, a'H' ;home cursor dt 0x1b, 0x5b, a'J' ;clear screen dt "K8LH 12F683 Serial Test Code v1.0" dt 0x0d, 0x0a, 0x0a, 0x00 end
Questions:
--- 12F683Serial-original.asm 2008-04-21 17:56:20.000000000 -0400 +++ 12F683Serial.asm 2008-05-03 19:58:40.000000000 -0400 @@ -20,3 +20,3 @@ - __config _FCMEN_OFF & _IESO_OFF & _BOD_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTOSC + __config _FCMEN_OFF & _IESO_OFF & _BOD_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTOSCIO ; @@ -39,4 +39,4 @@ -RXPIN equ 0x03 ;RS-232 RX (GP3) -TXPIN equ 0x04 ;RS-232 TX (GP4) +RXPIN equ 0x00 ;RS-232 RX (GP0) +TXPIN equ 0x01 ;RS-232 TX (GP1) BAUDX equ .208 ;208 for 9600 baud @@ -48,2 +48,3 @@ P_ISR equ 0x72 ;ISR 'PCLATH' +RX_MASK equ 0x73 ; Mask with RXPIN on others off ; @@ -82,4 +83,4 @@ START clrf STATUS ; |B0 - movlw b'00010000' ;tx pin in 'stop' condition |B0 - movwf GPIO ;setup GPIO latch |B0 + clrf GPIO ; clear it + bsf GPIO,TXPIN ; init TXPIN in stop condition goto MAIN ; |B0 @@ -134,3 +135,3 @@ movf TXCNT,W ;get TX bit count |B0 - xorlw b'00001011' ;start bit? |B0 + xorlw b'00001010' ;start bit? |B0 btfsc STATUS,Z ;no, branch |B0 @@ -161,4 +162,5 @@ ISR_X bsf STATUS,RP0 ;select bank 1 |B1 - movlw b'00001000' ;mask for bit 3 |B1 + movf RX_MASK,w xorwf IOC,f ;toggle GP3 IOC |B1 + bcf STATUS,RP0 ;select bank 0 |B0 @@ -202,4 +204,5 @@ movwf OSCCON ;8-mhz INTOSC system clock |B1 - movlw b'00001000' ;GP3 input, all others output |B1 + movlw b'00000000' ; Set mask as needed - 1 is input |B1 movwf TRISIO ; |B1 + bsf TRISIO,RXPIN ; make the RXPIN an input ; @@ -208,4 +211,13 @@ ; - movlw b'00001000' ; |B1 - movwf IOC ;set IOC for GP3 input |B1 + movlw b'00000000' ;set mask as needed |B1 + movwf IOC ;set IOC off initially |B1 + bsf IOC,RXPIN ; Set the receive pin for IOC + +; enabled weak pull up on RXPIN + clrf WPU ; set off weak pull ups |B1 + bsf WPU,RXPIN ; make the receive pin a pull up + +; Set the RX_MASK properly + clrf RX_MASK + bsf RX_MASK,RXPIN ; @@ -216,2 +228,3 @@ bcf STATUS,RP0 ;bank 0 |B0 + ; @@ -264,3 +277,3 @@ movwf TXVAR ;stuff character |B0 - movlw b'00001011' ; |B0 + movlw b'00001010' ; |B0 movwf TXCNT ;set TX bit count |B0+
file: /Techref/microchip/12F683-rs232-9600-mm.htm, 15KB, , updated: 2020/6/5 19:56, local time: 2024/12/25 20:20,
3.148.115.43:LOG IN
|
©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://linistepper.com/techref/microchip/12F683-rs232-9600-mm.htm"> PIC 12F683 9600 RS232</A> |
Did you find what you needed? |