News:

PROTON pic BASIC Compilers for PIC, PIC24, dsPIC33

Main Menu

UART Stop

Started by Teo, Apr 27, 2026, 09:58 PM

Previous topic - Next topic

Teo

Hello everyone,
I need to send a BMP via UART to a printer.
How can I stop sending when an interrupt occurs and resume it after handling the interrupt?
Does anyone have any idea? 
Thanks in advance,
Teo

Oskar-svr

Hi friend, you need to find the manual for the printer you're using. To do this, you should ask the manufacturer or look for the ESCPOS command manual. This contains the commands to program communication and initialize the printer, such as paper size, UART communication configuration, and other things you need to do to get the printer working.

And what printer are you planning to use?

Teo

Hello,
I will use the RTS signal given by the printer.
The problem is how I can stop the data stream transmission when the microcontroller detects an IOC (RTS) interrupt.
How can I stop the UART from transmitting and resume the transmission after the printer gives OK?
Thank you in advance,
Teo

trastikata

Use the hardware UART module where the buffer there is 1 byte, transmission is interrupt driven i.e. you load new byte in the buffer as soon as the old one is shifted out.

So use priorities when you detect IOC, go there, set a bit marker that will hold the UART hardware, execute the high priority IOC and return to the UART interrupt to load new byte in the buffer.

But you can not cut a transmission in half a byte (unless you disable the module). For something like this you will have to write own software based UART to hold and resume mid byte transmission.

Teo

Hi Trastikata,
Thank you for the response.
I send something on UART like this:
HRSOUT "OK",$0D,$0A,_
$1B,$4B,$40,$01,_
$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00, ..........
approximately 14000 bytes. It is a BMP.
How can I stop the transmission if an interruption occurs and then continue transmitting from where I left off?

Thanks in advance,
Teo

trastikata

Hello Teo,

I would organize it like the code bellow. Check the logic branching again, maybe I missed a branching case somewhere. The idea is like this:

- There's no interrupt priority because you might use older devices
- The Proc SendImage(dAddress As dFlashImage, dBytes As dBytesToSend) initiates the transfer
- Timer0 starts the actual transfer after 100ms and the timer is turned off
- UART transfer continues until end of the BMP (dFlashCounter > dBytesToSend)
- If Interrupt is detected on INT0 and clears a bit marker pFreeToSend and starts Timer0
- That bitmarker prevents data being sent
- In the main loop you monitor INT0IF and do something if interrupt occurs, then clear the INT0IF
- Timer0 Overflows again and if INT0IF is cleared the timer is stopped and the bit pFreeToSend is set
- If there's still data to be sent, the transfer continues dFlashCounter <= dBytesToSend
- The order in which I placed the flag checking in the ISR is important for the program logic.

Note, it is important how the receiving device will handle the data break? You might need to use SENDB - "Send Sync Break on next transmission", depending on firmware. A Break means the TX line is held low for longer than a normal character frame. In asynchronous UART, idle is high, so holding TX low might look like a framing-error condition to the receiver.

Device = 18F25J50       
Declare Xtal  = 48

Symbol TMR0ON = T0CON.7
Symbol TMR0IF = INTCON.2   
Symbol INT0IF = INTCON.1
Symbol TX2IF = PIR3.4

Dim pReadyToSend    As Bit      '0 - Nothing to TX / 1 = Data ready to TX
Dim pFreeToSend     As Bit      '0 - No / 1 - Yes
Dim dFlashImage     As Dword    'BMP address in the flash
Dim dFlashCounter   As Dword    'Flash address counter
Dim dBytesToSend    As Dword    'Number of bytes to send
Dim bTemp           As Byte     'Just temp variable

On_Hardware_Interrupt GoTo Isr
    GoTo Main

Isr:
    Context Save
        'External interrupt
        If INT0IF = 1 Then
            'Hold sending data
            pFreeToSend = 0
            TMR0ON = 1
        EndIf
       
        'Timer0 interrupt every 100ms
        If TMR0IF = 1 Then
            If INT0IF = 0 Then
                pFreeToSend = 1
                TMR0ON = 0
            EndIf
            TMR0H = $6D : TMR0L = $84
            TMR0IF = 0
        EndIf
       
        'EUSART TX ready interrupt
        If TX2IF = 1 Then
            pReadyToSend = 1
        EndIf
       
        If pFreeToSend = 1 And pReadyToSend = 1 And dFlashCounter <= dBytesToSend Then
            bTemp = CRead8 dFlashImage[dFlashCounter]
            TXREG2 = bTemp
            Inc dFlashCounter 
            pReadyToSend = 0
        EndIf   
    Context Restore

Main:
    SetInterrupts()
    SetUart2()
    SetTimer0()
    SendImage(CAT_BW, 96)   
   
MyLoop:
    'Do something
   
    'Interrupt on INT0 detected, do someting
    If INT0IF = 1 Then
        '.... 
        'Finished handling the interrupt, continue
         INT0IF = 0
         pFreeToSend = 1
    EndIf 
   
    GoTo MyLoop       
    End
   
Proc SendImage(dAddress As dFlashImage, dBytes As dBytesToSend)
    dFlashCounter = 0
    pReadyToSend = 1 
    TMR0ON = 1
EndProc   
   
Proc SetTimer0()
    T0CON = %00000100
    '100ms
    TMR0H = $6D : TMR0L = $84   
EndProc   

Proc SetInterrupts()
    pFreeToSend = 1
   
    'Global Interrupt Enable
    'Peripheral Interrupt Enable
    'TMR0 Overflow Interrupt Enable
    'INT0 External Interrupt Enable
    INTCON = %11110000   
   
    'PORTB Pull-up Enable
    'External Interrupt 0 Interrupt on rising edge
    INTCON2 = %01111111
EndProc

Proc SetUart2()
    '16-Bit Baud Rate Register Enable
    BAUDCON2 = %01001000
   
    'Transmit Enable     
    'EUSART Mode Select Asynchronous mode
    'High Baud Rate Select Low speed
    TXSTA2 = %00100010
   
    'Baudrate 38400
    SPBRGH2 = 0   
    SPBRG2 = 77   
   
    'Serial port Enable
    RCSTA2 = %10000000
EndProc

'Bmp I want to send - 96 bytes
Dim CAT_BW As Flash8 = 0x01,0x08,0x00,0xB0,0x00,0x08,0x04,0x12,0x48,0x08,0x21,0x14,0x54,0x01,0x0A,0x91,0x04,0x49,0x04,0x24,0x40,0x11,0x48,0x10,_
0x0A,0x14,0x50,0x80,0x20,0x15,0x00,0x14,0xB5,0x2A,0x57,0xFE,0xBA,0xB5,0x10,0x22,0x00,0x84,0x81,0x08,0x11,0x2A,0x88,0x02,_
0x48,0x51,0x00,0x10,0x01,0x00,0x04,0x00,0x05,0x11,0x02,0x0A,0x88,0x89,0x55,0x11,0x0B,0x48,0xA5,0xBA,0xD5,0xD7,0x4A,0x40,_
0x88,0x90,0x12,0x08,0x20,0x44,0x52,0x41,0x09,0x11,0x08,0x12,0x01,0x00,0x09,0x20,0x12,0x48,0x44,0x48,0x91,0x40,0x02,0x15

Teo

Hi Trastikata,
Thanks for your help.
I am using PIC18F2685 because I need memory over 64k.
Tomorrow I will test it and tell you what happens.
Have a good day,
Teo