PIC18F67K22 TX pin low after UART enable - uart

I using PIC18F67K22 with MPLAB8.92 and ICD3. I set port registers for UART RC7-input and RC6-output. I then set the UART 1 for comms. The Tx Pin should go high after setting UART but stays low. When I send a byte the Tx sends data and goes high after byte sent. I have played with the BAUDCON(5)(4) but no luck. Is it possible to force the Tx pin to go high without sending a byte ? All the data on the TX pin is correct after the first byte is sent.
;// Zeta
movlw b'10010000' ;
MOVWF TRISC ;
banksel TXSTA1
movlw b'10000000' ;//
movwf TXSTA1
bsf BAUDCON1,3 ;// 16 byte
movlw .207 ;// 64 mhz
movwf SPBRG1
movlw .0
movwf SPBRGH1
movlw b'10010000'
movwf RCSTA1 ;//Enable Serial
bsf PIE1,5

Before the UART is enabled use the TRISC and LATC registers to configure RC6 as an output and set the output state to one.
;
; Make the UART TX output a one.
;
BANKSEL LATC
BSF LATC,6 ; Make RC6 a 1
BANKSEL TRISC
BCF TRISC,6 ; Make RC6 an output
;
; Now configure the UART and enable the TX
;
EDIT 1
This is a complete program that initializes the PIC and UART1:
list n=0,c=250 ; Make list file pretty
list r=dec ; Use decimal as the default radix
;
; File: main.asm
; Author: dan1138
; Target: PIC18F67K22
; Compiler: MPASMWIN v5.51
; IDE: MPLAB v8.92
;
;
; PIC18F67K22
; +----------+ +----------+ +-----------+ +----------+
; <> 1 : RE1 : <> 17 : RF1 : <> 33 : RC2 : <> 49 : RD7 :
; <> 2 : RE0 : -> 18 : ENVREG : <> 34 : RC3 : <> 50 : RD6 :
; <> 3 : RG0 : 5V0 -> 19 : AVDD : <> 35 : RC4 : <> 51 : RD5 :
; <> 4 : RG1 : GND -> 20 : AVSS : <> 36 : RC5 : <> 52 : RD4 :
; <> 5 : RG2 : <> 21 : RA3 : PGD <> 37 : RB7/PGD : <> 53 : RD3 :
; <> 6 : RG3 : <> 22 : RA2 : 5V0 -> 38 : VDD : <> 54 : RD2 :
; VPP -> 7 : RG5/MCLRn: <> 23 : RA1 : <> 39 : OSC1/RA7 : <> 55 : RD1 :
; <> 8 : RG4 : <> 24 : RA0 : <> 40 : OSC2/RA6 : GND -> 56 : VSS :
; GND -> 9 : VSS : GND -> 25 : VSS : GND -> 41 : VSS : 5V0 -> 57 : VDD :
; 10uF -> 10 : VCAP : 5V0 -> 26 : VDD : PGC <> 42 : RB6/PGC : <> 58 : RD0 :
; <> 11 : RF7 : <> 27 : RA5 : <> 43 : RB5 : <> 59 : RE7 :
; <> 12 : RF6 : <> 28 : RA4 : <> 44 : RB4 : <> 60 : RE6 :
; <> 13 : RF5 : <> 29 : RC1 : <> 45 : RB3 : <> 61 : RE5 :
; <> 14 : RF4 : <> 30 : RC0 : <> 46 : RB2 : <> 62 : RE4 :
; <> 15 : RF3 : <> 31 : RC6/TX : <> 47 : RB1 : <> 63 : RE3 :
; <> 16 : RF2 : <> 32 : RC7/RX : <> 48 : RB0 : <> 64 : RE2 :
; +----------+ +----------+ +-----------+ +----------+
; TQFP-64
;
INCLUDE "p18f67k22.inc"
; CONFIG1L
CONFIG RETEN = ON ; VREG Sleep Enable bit (Enabled)
CONFIG INTOSCSEL = HIGH ; LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
CONFIG SOSCSEL = HIGH ; SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
CONFIG XINST = OFF ; Extended Instruction Set (Disabled)
; CONFIG1H
CONFIG FOSC = INTIO2 ; Oscillator (Internal RC oscillator)
CONFIG PLLCFG = OFF ; PLL x4 Enable bit (Disabled)
CONFIG FCMEN = OFF ; Fail-Safe Clock Monitor (Disabled)
CONFIG IESO = OFF ; Internal External Oscillator Switch Over Mode (Disabled)
; CONFIG2L
CONFIG PWRTEN = OFF ; Power Up Timer (Disabled)
CONFIG BOREN = OFF ; Brown Out Detect (Disabled in hardware, SBOREN disabled)
CONFIG BORV = 3 ; Brown-out Reset Voltage bits (1.8V)
CONFIG BORPWR = ZPBORMV ; BORMV Power level (ZPBORMV instead of BORMV is selected)
; CONFIG2H
CONFIG WDTEN = OFF ; Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
CONFIG WDTPS = 1048576 ; Watchdog Postscaler (1:1048576)
; CONFIG3L
CONFIG RTCOSC = SOSCREF ; RTCC Clock Select (RTCC uses SOSC)
; CONFIG3H
CONFIG CCP2MX = PORTC ; CCP2 Mux (RC1)
CONFIG MSSPMSK = MSK7 ; MSSP address masking (7 Bit address masking mode)
CONFIG MCLRE = ON ; Master Clear Enable (MCLR Enabled, RG5 Disabled)
; CONFIG4L
CONFIG STVREN = ON ; Stack Overflow Reset (Enabled)
CONFIG BBSIZ = BB2K ; Boot Block Size (2K word Boot Block size)
; CONFIG5L
CONFIG CP0 = OFF ; Code Protect 00800-03FFF (Disabled)
CONFIG CP1 = OFF ; Code Protect 04000-07FFF (Disabled)
CONFIG CP2 = OFF ; Code Protect 08000-0BFFF (Disabled)
CONFIG CP3 = OFF ; Code Protect 0C000-0FFFF (Disabled)
CONFIG CP4 = OFF ; Code Protect 10000-13FFF (Disabled)
CONFIG CP5 = OFF ; Code Protect 14000-17FFF (Disabled)
CONFIG CP6 = OFF ; Code Protect 18000-1BFFF (Disabled)
CONFIG CP7 = OFF ; Code Protect 1C000-1FFFF (Disabled)
; CONFIG5H
CONFIG CPB = OFF ; Code Protect Boot (Disabled)
CONFIG CPD = OFF ; Data EE Read Protect (Disabled)
; CONFIG6L
CONFIG WRT0 = OFF ; Table Write Protect 00800-03FFF (Disabled)
CONFIG WRT1 = OFF ; Table Write Protect 04000-07FFF (Disabled)
CONFIG WRT2 = OFF ; Table Write Protect 08000-0BFFF (Disabled)
CONFIG WRT3 = OFF ; Table Write Protect 0C000-0FFFF (Disabled)
CONFIG WRT4 = OFF ; Table Write Protect 10000-13FFF (Disabled)
CONFIG WRT5 = OFF ; Table Write Protect 14000-17FFF (Disabled)
CONFIG WRT6 = OFF ; Table Write Protect 18000-1BFFF (Disabled)
CONFIG WRT7 = OFF ; Table Write Protect 1C000-1FFFF (Disabled)
; CONFIG6H
CONFIG WRTC = OFF ; Config. Write Protect (Disabled)
CONFIG WRTB = OFF ; Table Write Protect Boot (Disabled)
CONFIG WRTD = OFF ; Data EE Write Protect (Disabled)
; CONFIG7L
CONFIG EBRT0 = OFF ; Table Read Protect 00800-03FFF (Disabled)
CONFIG EBRT1 = OFF ; Table Read Protect 04000-07FFF (Disabled)
CONFIG EBRT2 = OFF ; Table Read Protect 08000-0BFFF (Disabled)
CONFIG EBRT3 = OFF ; Table Read Protect 0C000-0FFFF (Disabled)
CONFIG EBRT4 = OFF ; Table Read Protect 10000-13FFF (Disabled)
CONFIG EBRT5 = OFF ; Table Read Protect 14000-17FFF (Disabled)
CONFIG EBRT6 = OFF ; Table Read Protect 18000-1BFFF (Disabled)
CONFIG EBRT7 = OFF ; Table Read Protect 1C000-1FFFF (Disabled)
; CONFIG7H
CONFIG EBRTB = OFF ; Table Read Protect Boot (Disabled)
;
; Define what we want the system clock frequency
; to be set to by the initialzation code.
;
#define FSYS (8000000)
#define FCYC (FSYS/4)
#define BAUD (9600)
#define BRG_VALUE (FSYS/BAUD)/4-1
;*******************************************************************************
; Reset Vector
;*******************************************************************************
RES_VECT CODE 0x0000 ; processor reset vector
GOTO START ; go to beginning of program
;*******************************************************************************
; MAIN PROGRAM
;*******************************************************************************
MAIN_PROG CODE ; let linker place main program
START
BSF LATC,6 ; Make TX output high
BCF TRISC,6 ; Turn on output driver
CLRF RCSTA1 ; Disable UART1
CLRF TXSTA1
CLRF BAUDCON1
BSF BAUDCON1,BRG16 ; Use 16-bit baud rate generator
BSF TXSTA1,BRGH ; Select high speed baud rate generator
BSF TXSTA1,TXEN ; Enable transmitter
BSF RCSTA1,CREN ; Enable reciever
MOVLW LOW(BRG_VALUE)
MOVWF SPBRG1
MOVLW HIGH(BRG_VALUE)
MOVWF SPBRGH1
BSF RCSTA1,SPEN ; Enable UART1
;
; With an 8MHz system clock this is about a
; 100ms wait for UART1 hardware to be ready.
;
MOVLW 0
CLRF PRODL
UART1_SpinWait:
DECFSZ PRODL,F
BRA UART1_SpinWait
DECFSZ WREG,F
BRA UART1_SpinWait
MOVLW '>'
CALL UART1_SendByte
GOTO $ ; loop forever
;
; Send a byte to UART1
;
UART1_SendByte:
BTFSS TXSTA1,TRMT ; Skip when transmitter is empty
BRA UART1_SendByte
MOVWF TXREG
RETURN
END
See how this works in your hardware.

Related

What is wrong with this PIC16F877A HCSR04 example?

I am working on distance sensor with PIC16F877A.
I am using MPLAB IDE AND XC8 compiler.
My goal is to gradually turn on the right leds at certain distance levels, but the leds are blinking unstable. What am I doing wrong? distance/5
When it measures 5 cm, it is 5/5 and the result is 1 and 1 led is on.
When it measures 10 cm, it is 10/5 and the result is 2 and 2 leds are on.
When you measure 15 cm, it is 15/5 and the result is 3 and 3 LEDs are on.
When you measure 20 cm, it is 20/5 and the result is 4 and 4 leds are on.
If the distance is less than 5 cm or above 20 cm, no led lights are on
https://i.stack.imgur.com/fFKQg.png
#include <xc.h>
#include <pic16f877a.h>
#pragma config FOSC = XT // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
#define _XTAL_FREQ 4000000
#define trigger RC2
#define echo RC3
int calc_distance();
int calc_distance()
{
int distance=0;
trigger=1;
__delay_us(10);
trigger=0;
while(!echo); // normally the echo pin is logic 0. If we toggle the zero and throw it into the while, it returns idle until the echo arrives (until the signal becomes logic 1).
TMR1ON=1;//In the upper loop, while returning the command empty, echo comes and exits the upper loop and timer1 is activated.
while(echo);
TMR1ON=0;//
distance=TMR1/58;
return distance;
}
void main(void)
{
int dist=0; // Create Distance Variable
TRISB = 0x00; // Set PORTB To Be Output Port (All The 8 Pins)
PORTB = 0x00; // Set PORTB To Be LOW For initial State
TRISC2 = 0; // Set RC2 To Be Output Pin ( Trigger )
RC2 = 0;
TRISC3 = 1; // Set RC3 To Be Input Pin ( Echo )
//--[ Configure Timer Module To Operate in Timer Mode ]--
// Clear The Pre-Scaler Select Bits
T1CKPS0=0;
T1CKPS1=0;
TMR1CS=0;// Choose The Local Clock As Clock Source
while(1)
{
calc_distance();
dist = calc_distance()/5;
if(dist==1)
{PORTB = 0x01; __delay_ms(50);}
if(dist==2)
{PORTB = 0x03; __delay_ms(50);}
if(dist==3)
{PORTB = 0x07; __delay_ms(50);}
if(dist==4)
{PORTB = 0x0F; __delay_ms(50);}
else
{PORTB = 0x00; __delay_ms(50);}
}
return;
}

Pic18F67K22 Unable to set SPBRGH1

PIC1867K22 # 64 Mhz with MPLAB 8.92.
Trying to set baud rate to 9600 and unable to get the SPBRGH1 register to change its stuck on 0xC2. Set ports RC6, RC7 as needed or I/0. The UART sends and receives data but wrong baud. Using 16 byte baud rate
movlw b'10010000' ;// UART RC.6 RF TX out
MOVWF TRISC
banksel TXSTA1
movlw b'10000100' ;// 9600 baud
movwf TXSTA1
bsf BAUDCON1,3 ;// 16 byte
bcf BAUDCON1,5 ;// Data NOT inverted (Rx)
bcf BAUDCON1,4 ;// Data NOY inverted (Tx)
movlw 0x66 ;// 64 mhz
movwf SPBRG1
movlw 0x16
movwf SPBRGH1
movlw b'10010000'
movwf RCSTA1 ;//Enable Serial
The PIC18F67K22 has all of the Special Function Registers located in memory common to all banks.
I suspect that whatever your problem is, it may on be in the code you have yet posted.
This complete application will setup the UART and build with MPASM:
list n=0,c=250 ; Make list file look pretty
list r=dec ; use decimal numbers as the default
;
; Author : Dan1138
; Date : 2021-APRIL-06
; Target : PIC18F67K22
; IDE : MPLAB v8.92
; Compiler : MPASM
; PIC18F67K22
; +---------------+ +---------------+ +---------------+ +---------------+
; <> : 1 RE1 : <> : 17 RF1/AN6 : <> : 33 RC2/ECCP1 : <> : 49 RD7 :
; <> : 2 RE0 : 3v3 -> : 18 ENVREG : <> : 34 RC3/SCL1 : <> : 50 RD6/SCL2 :
; <> : 3 RG0/ECCP3 : 3v3 -> : 19 AVDD : <> : 35 RC4/SDA1 : <> : 51 RD5/SDA2 :
; <> : 4 RG1/AN19 : GND -> : 20 AVSS : <> : 36 RC5 : <> : 52 RD4 :
; <> : 5 RG2/AN18 : <> : 21 RA3/AN3 : IDC_PGD <> : 37 RB7/PGD : <> : 53 RD3 :
; <> : 6 RG3/AN17 : <> : 22 RA2/AN2 : 3v3 -> : 38 VDD : <> : 54 RD2 :
; ICD_VPP -> : 7 RG5/MCLR : <> : 23 RA1/AN1 : <> : 39 RA7/OSC1 : <> : 55 RD1 :
; <> : 8 RG4/AN16 : <> : 24 RA0/AN0 : <> : 30 RA6/OSC2 : GND-> : 56 VSS :
; GND -> : 9 VSS : GND -> : 25 VSS : GND -> : 41 VSS : 3v3-> : 57 VDD :
; 10uF -> : 10 VCAP : 3v3 -> : 26 VDD : ICD_PGC <> : 42 RB6/PGC : <> : 58 RD0 :
; <> : 11 RF7/AN5 : <> : 27 RA5/AN4 : <> : 43 RB5 : <> : 59 RE7/ECCP2 :
; <> : 12 RF6/AN11 : <> : 28 RA4/T0CKI : <> : 44 RB4 : <> : 60 RE6/CCP6 :
; <> : 13 RF5/AN10 : <> : 29 RC1/SOSCI : <> : 45 RB3 : <> : 61 RE5/CCP7 :
; <> : 14 RF4/AN9 : <> : 30 RC0/SOSCO : <> : 46 RB2 : <> : 62 RE4/CCP8 :
; <> : 15 RF3/AN8 : <> : 31 RC6/TX1 : <> : 47 RB1/INT1 : <> : 63 RE3/CCP9 :
; <> : 16 RF2/AN7 : <> : 32 RC7/RX1 : <> : 48 RB0/INT0 : <> : 64 RE2/CCP10 :
; +---------------+ +---------------+ +---------------+ +---------------+
; TQFP-64
;
; Include definitions of the special function registers
;
#include "p18f67k22.inc"
;
; Initialize all of the configuration word bits
;
; CONFIG1L
CONFIG RETEN = ON ; VREG Sleep Enable bit (Enabled)
CONFIG INTOSCSEL = HIGH ; LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
CONFIG SOSCSEL = HIGH ; SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
CONFIG XINST = OFF ; Extended Instruction Set (Disabled)
; CONFIG1H
CONFIG FOSC = INTIO2 ; Oscillator (Internal RC oscillator)
CONFIG PLLCFG = OFF ; PLL x4 Enable bit (Disabled)
CONFIG FCMEN = OFF ; Fail-Safe Clock Monitor (Disabled)
CONFIG IESO = OFF ; Internal External Oscillator Switch Over Mode (Disabled)
; CONFIG2L
CONFIG PWRTEN = OFF ; Power Up Timer (Disabled)
CONFIG BOREN = OFF ; Brown Out Detect (Disabled in hardware, SBOREN disabled)
CONFIG BORV = 3 ; Brown-out Reset Voltage bits (1.8V)
CONFIG BORPWR = ZPBORMV ; BORMV Power level (ZPBORMV instead of BORMV is selected)
; CONFIG2H
CONFIG WDTEN = OFF ; Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
CONFIG WDTPS = 1048576 ; Watchdog Postscaler (1:1048576)
; CONFIG3L
CONFIG RTCOSC = SOSCREF ; RTCC Clock Select (RTCC uses SOSC)
; CONFIG3H
CONFIG CCP2MX = PORTC ; CCP2 Mux (RC1)
CONFIG MSSPMSK = MSK7 ; MSSP address masking (7 Bit address masking mode)
CONFIG MCLRE = ON ; Master Clear Enable (MCLR Enabled, RG5 Disabled)
; CONFIG4L
CONFIG STVREN = ON ; Stack Overflow Reset (Enabled)
CONFIG BBSIZ = BB2K ; Boot Block Size (2K word Boot Block size)
; CONFIG5L
CONFIG CP0 = OFF ; Code Protect 00800-03FFF (Disabled)
CONFIG CP1 = OFF ; Code Protect 04000-07FFF (Disabled)
CONFIG CP2 = OFF ; Code Protect 08000-0BFFF (Disabled)
CONFIG CP3 = OFF ; Code Protect 0C000-0FFFF (Disabled)
CONFIG CP4 = OFF ; Code Protect 10000-13FFF (Disabled)
CONFIG CP5 = OFF ; Code Protect 14000-17FFF (Disabled)
CONFIG CP6 = OFF ; Code Protect 18000-1BFFF (Disabled)
CONFIG CP7 = OFF ; Code Protect 1C000-1FFFF (Disabled)
; CONFIG5H
CONFIG CPB = OFF ; Code Protect Boot (Disabled)
CONFIG CPD = OFF ; Data EE Read Protect (Disabled)
; CONFIG6L
CONFIG WRT0 = OFF ; Table Write Protect 00800-03FFF (Disabled)
CONFIG WRT1 = OFF ; Table Write Protect 04000-07FFF (Disabled)
CONFIG WRT2 = OFF ; Table Write Protect 08000-0BFFF (Disabled)
CONFIG WRT3 = OFF ; Table Write Protect 0C000-0FFFF (Disabled)
CONFIG WRT4 = OFF ; Table Write Protect 10000-13FFF (Disabled)
CONFIG WRT5 = OFF ; Table Write Protect 14000-17FFF (Disabled)
CONFIG WRT6 = OFF ; Table Write Protect 18000-1BFFF (Disabled)
CONFIG WRT7 = OFF ; Table Write Protect 1C000-1FFFF (Disabled)
; CONFIG6H
CONFIG WRTC = OFF ; Config. Write Protect (Disabled)
CONFIG WRTB = OFF ; Table Write Protect Boot (Disabled)
CONFIG WRTD = OFF ; Data EE Write Protect (Disabled)
; CONFIG7L
CONFIG EBRT0 = OFF ; Table Read Protect 00800-03FFF (Disabled)
CONFIG EBRT1 = OFF ; Table Read Protect 04000-07FFF (Disabled)
CONFIG EBRT2 = OFF ; Table Read Protect 08000-0BFFF (Disabled)
CONFIG EBRT3 = OFF ; Table Read Protect 0C000-0FFFF (Disabled)
CONFIG EBRT4 = OFF ; Table Read Protect 10000-13FFF (Disabled)
CONFIG EBRT5 = OFF ; Table Read Protect 14000-17FFF (Disabled)
CONFIG EBRT6 = OFF ; Table Read Protect 18000-1BFFF (Disabled)
CONFIG EBRT7 = OFF ; Table Read Protect 1C000-1FFFF (Disabled)
; CONFIG7H
CONFIG EBRTB = OFF ; Table Read Protect Boot (Disabled)
;
; Define what we are going to setup as the system oscillator frequency
;
#define FSYS (64000000)
#define FCY (FSYS/4)
;
; Reset vector
;
RES_VECT CODE 0x0000 ; processor reset vector
GOTO START ; go to beginning of program
;
; High priority interrupt vector
;
ISR_HIGH_VECTOR code 0x00008
goto ISR_HIGH_HANDLER
;
ISR_LOW_DATA udata_acs
wreg_temp: res 1
status_temp: res 1
pclath_temp: res 1
;
; Low priority interrupt handler
;
ISR_LOW_VECTOR code 0x00018
ISR_LOW_HANDLER:
movwf wreg_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
clrf STATUS ; force to bank zero
movwf status_temp ; save off contents of STATUS register
movf PCLATH,W
movwf pclath_temp
movlw HIGH(ISR_LOW_HANDLER)
movwf PCLATH
; isr code can go here or be located as a called subroutine elsewhere
movf pclath_temp,W
movwf PCLATH
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf wreg_temp,f
swapf wreg_temp,w ; restore pre-isr W register contents
retfie ; return from interrupt
;
; High priority interrupt handler
;
ISR_HIGH_HANDLER:
retfie FAST
;
; Main application
;
MAIN_PROG CODE
;
; Turn off interrupts
; Make all GPIO pins digiatl outputs
;
START:
clrf INTCON
movlw 0x70
MOVWF OSCCON
clrf OSCTUNE
bsf OSCTUNE,PLLEN
;
clrf ANCON0
clrf ANCON1
clrf ANCON2
;
clrf LATA
clrf LATB
clrf LATC
clrf LATD
clrf LATE
clrf LATF
clrf LATG
clrf TRISA
clrf TRISB
clrf TRISC
clrf TRISD
clrf TRISE
clrf TRISF
clrf TRISG
;
; Setup UART1
;
#define U1_BAUD 9600
#define U1_BRGH_VALUE 1
#define U1_BRG16_VALUE 1
;
; Compute the value for the UART1 baud rate registers
;
#if U1_BRG16_VALUE
#if U1_BRGH_VALUE
#define U1_BRGH_SCALE 1
#else
#define U1_BRGH_SCALE 4
#endif
#else
#if U1_BRGH_VALUE
#define U1_BRGH_SCALE 4
#else
#define U1_BRGH_SCALE 16
#endif
#endif
#define U1_SPBRG_VALUE (((FCY+(U1_BRGH_SCALE*U1_BAUD/2))/(U1_BRGH_SCALE*U1_BAUD))-1)
#if U1_BRG16_VALUE
#if (U1_SPBRG_VALUE >> 16)
error "Cannot set up UART1 for the FCY and BAUDRATE."
#endif
#else
#if (U1_SPBRG_VALUE >> 8)
error "Cannot set up UART1 for the FCY and BAUDRATE."
#endif
#endif
;
; Check if the real baud rate is within 2.5 percent of the require baud rate
;
#define REAL_BAUDRATE (FCY/(U1_BRGH_SCALE*(U1_SPBRG_VALUE+1)))
#if (REAL_BAUDRATE > (U1_BAUD+(U1_BAUD*25)/1000))
error "UART baudrate error greater than 2.5 percent for the FCY and U1_BAUD."
#endif
#if (REAL_BAUDRATE < (U1_BAUD-(U1_BAUD*25)/1000))
error "UART baudrate error greater than 2.5 percent for the FCY and U1_BAUD."
#endif
;
bsf LATC,LATC6 ; Set U1_TXD high
bsf TRISC,TRISC7 ; Set U1_RXD as digital input
clrf TXSTA1
clrf RCSTA1
clrf BAUDCON1
#if (U1_BRG16_VALUE)
bsf BAUDCON1,BRG16
#endif
#if (U1_BRGH_VALUE)
bsf TXSTA1,BRGH
#endif
#if (U1_BRG16_VALUE)
movlw HIGH(U1_SPBRG_VALUE)
movwf SPBRGH1
#endif
movlw LOW(U1_SPBRG_VALUE)
movwf SPBRG1
bsf TXSTA1,TXEN
bsf RCSTA1,CREN
bsf RCSTA1,SPEN
;
; Send a "Start" message
;
movlw 0x0d
call U1_Putc
movlw 0x0a
call U1_Putc
movlw 'S'
call U1_Putc
movlw 't'
call U1_Putc
movlw 'a'
call U1_Putc
movlw 'r'
call U1_Putc
movlw 't'
call U1_Putc
movlw 0x0d
call U1_Putc
movlw 0x0a
call U1_Putc
;
; Application process loop
;
AppLoop:
GOTO AppLoop
;
; Send a character out UART
;
U1_Putc:
btfss TXSTA1,TRMT
bra U1_Putc
movwf TXREG1
return
END

Writing to non-volatile memory without disrupting UART interrupts execution on STM32F4XX

I have several OVERRUN errors on UART peripheral because I keep receiving UART data while my code is stall because I'm executing a write operation on flash.
I'm using interrupts for UART and has it is explained on Application Note AN3969 :
EEPROM emulation firmware runs from the internal Flash, thus access to
the Flash will be stalled during operations requiring Flash erase or
programming (EEPROM initialization, variable update or page erase). As
a consequence, the application code is not executed and the interrupt
can not be served.
This behavior may be acceptable for many applications, however for
applications with realtime constraints, you need to run the critical
processes from the internal RAM.
In this case:
Relocate the vector table in the internal RAM.
Execute all critical processes and interrupt service routines from the internal RAM. The compiler provides a keyword to declare functions
as a RAM function; the function is copied from the Flash to the RAM at
system startup just like any initialized variable. It is important to
note that for a RAM function, all used variable(s) and called
function(s) should be within the RAM.
So I've search on the internet and found AN4808 which provides examples on how to keep the interrupts running while flash operations.
I went ahead and modified my code :
Linker script : Added vector table to SRAM and define a .ramfunc section
/* stm32f417.dld */
ENTRY(Reset_Handler)
MEMORY
{
ccmram(xrw) : ORIGIN = 0x10000000, LENGTH = 64k
sram : ORIGIN = 0x20000000, LENGTH = 112k
eeprom_default : ORIGIN = 0x08004008, LENGTH = 16376
eeprom_s1 : ORIGIN = 0x08008000, LENGTH = 16k
eeprom_s2 : ORIGIN = 0x0800C000, LENGTH = 16k
flash_unused : ORIGIN = 0x08010000, LENGTH = 64k
flash : ORIGIN = 0x08020000, LENGTH = 896k
}
_end_stack = 0x2001BFF0;
SECTIONS
{
. = ORIGIN(eeprom_default);
.eeprom_data :
{
*(.eeprom_data)
} >eeprom_default
. = ORIGIN(flash);
.vectors :
{
_load_vector = LOADADDR(.vectors);
_start_vector = .;
*(.vectors)
_end_vector = .;
} >sram AT >flash
.text :
{
*(.text)
*(.rodata)
*(.rodata*)
_end_text = .;
} >flash
.data :
{
_load_data = LOADADDR(.data);
. = ALIGN(4);
_start_data = .;
*(.data)
} >sram AT >flash
.ramfunc :
{
. = ALIGN(4);
*(.ramfunc)
*(.ramfunc.*)
. = ALIGN(4);
_end_data = .;
} >sram AT >flash
.ccmram :
{
_load_ccmram = LOADADDR(.ccmram);
. = ALIGN(4);
_start_ccmram = .;
*(.ccmram)
*(.ccmram*)
. = ALIGN(4);
_end_ccmram = .;
} > ccmram AT >flash
.bss :
{
_start_bss = .;
*(.bss)
_end_bss = .;
} >sram
. = ALIGN(4);
_start_stack = .;
}
_end = .;
PROVIDE(end = .);
Reset Handler : Added vector table copy SRAM and define a .ramfunc section
void Reset_Handler(void)
{
unsigned int *src, *dst;
/* Copy vector table from flash to RAM */
src = &_load_vector;
dst = &_start_vector;
while (dst < &_end_vector)
*dst++ = *src++;
/* Copy data section from flash to RAM */
src = &_load_data;
dst = &_start_data;
while (dst < &_end_data)
*dst++ = *src++;
/* Copy data section from flash to CCRAM */
src = &_load_ccmram;
dst = &_start_ccmram;
while (dst < &_end_ccmram)
*dst++ = *src++;
/* Clear the bss section */
dst = &_start_bss;
while (dst < &_end_bss)
*dst++ = 0;
SystemInit();
SystemCoreClockUpdate();
RCC->AHB1ENR = 0xFFFFFFFF;
RCC->AHB2ENR = 0xFFFFFFFF;
RCC->AHB3ENR = 0xFFFFFFFF;
RCC->APB1ENR = 0xFFFFFFFF;
RCC->APB2ENR = 0xFFFFFFFF;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOEEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOFEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOGEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOHEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOIEN;
RCC->AHB1ENR |= RCC_AHB1ENR_CCMDATARAMEN;
main();
while(1);
}
system_stm32f4xxx.c : Uncommented VECT_TAB_SRAM define
/*!< Uncomment the following line if you need to relocate your vector Table in
Internal SRAM. */
#define VECT_TAB_SRAM
#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
Added a definition of RAMFUNC to set section attributes :
#define RAMFUNC __attribute__ ((section (".ramfunc")))
Addded RAMFUNC before UART related function and prototypes so it gets run from RAM.
RAMFUNC void USART1_IRQHandler(void)
{
uint32_t sr = USART1->SR;
USART1->SR & USART_SR_ORE ? GPIO_SET(LED_ERROR_PORT, LED_ERROR_PIN_bp):GPIO_CLR(LED_ERROR_PORT, LED_ERROR_PIN_bp);
if(sr & USART_SR_TXE)
{
if(uart_1_send_write_pos != uart_1_send_read_pos)
{
USART1->DR = uart_1_send_buffer[uart_1_send_read_pos];
uart_1_send_read_pos = (uart_1_send_read_pos + 1) % USART_1_SEND_BUF_SIZE;
}
else
{
USART1->CR1 &= ~USART_CR1_TXEIE;
}
}
if(sr & (USART_SR_RXNE | USART_SR_ORE))
{
USART1->SR &= ~(USART_SR_RXNE | USART_SR_ORE);
uint8_t byte = USART1->DR;
uart_1_recv_buffer[uart_1_recv_write_pos] = byte;
uart_1_recv_write_pos = (uart_1_recv_write_pos + 1) % USART_1_RECV_BUF_SIZE;
}
}
My target runs properly with vector table and UART function in RAM but I still I get an overrun on USART. I'm also not disabling interrupts when performing the flash write operation.
I also tried to run code from CCM RAM instead of SRAM but has I saw on this post code can't be executed on CCM RAM on STMF32F4XX...
Any idea ? Thanks.
Any attempt to read from flash while a write operation is ongoing causes the bus to stall.
In order to not be blocked by flash writes, I think not only the the interrupt code, but the interrupted function has to run from RAM too, otherwise the core cannot proceed to a state when interrupts are possible.
Try relocating the flash handling code to RAM.
If it's possible, I'd advise switching to an MCU with two independent banks of flash memory, like the pin- and software-compatible 427/429/437/439 series. You can dedicate one bank to program code and the other to EEPROM-like data storage, then writing the second bank won't disturb code running from the first bank.
As suggested, it might be necessary to execute code from RAM; or, rather, make sure that no flash read operations are performed while the write is in progress.
To test, you might want to compile the entire executable for RAM, rather than flash (i.e., place everything into RAM and not use the flash at all).
You could then use gdb to load the binary and start execution... test your uart and make sure it is working as expected. At least this way you can be sure the flash is unused.
Some micros have READ WHILE WRITE sections that do not have a problem performing multiple operations simultaneously.

SparkFun nRF52832 Breakout + SPI display

I'm using the TFT display ILI9341 linked to the Adafruit HUZZAH through SPI with the example skecth provided "graphictest" and everythings works fine.
// HUZZAH DEVICE Spakfun nRf52
// Violet -- 12 --> MISO <-- 12 -- Violet
// Rouge -- 3V --> LED <-- 3V3-- Orange
// Vert -- 14 --> SCK <-- 13 -- Vert
// Bleu -- 13 --> MOSI <-- 11 -- Bleu
// Blanc #-- 4 --> D/C <-- 9 -- Marron
// Bleu -- 3V --> RESET <-- 3v3-- Gris
// Blanc o-- 5 --> CS <-- 10 -- Jaune
// Noir -- GND--> GND <-- GND-- Noir
// Rouge -- 3V --> VCC <-- 3V3-- Vcc
I want to do the same things with the SparkFun nRF52832 Breakout but the sketch stop during "tft.begin()"
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
void setup() {
Serial.begin(9600);
Serial.println("ILI9341 Test!");
tft.begin();
I also checked the header : variant.h
/*
* SPI Interfaces
*/
#define SPI_INTERFACES_COUNT 1
#define PIN_SPI_MISO (12)
#define PIN_SPI_MOSI (11)
#define PIN_SPI_SCK (13)
static const uint8_t SS = 10 ;
static const uint8_t MOSI = PIN_SPI_MOSI ;
static const uint8_t MISO = PIN_SPI_MISO ;
static const uint8_t SCK = PIN_SPI_SCK ;
I try to use SDcard slot built-in on the ILI9341 display, it's fine with HUZZAH but KO with Sparkfun nRf52.
If some of you could help me, it would be very kind.
Thanks.

pic 18F46k80 EUART

i´m trying to transfer data to computer via EUSART. I have already set all the configurate bits but serial communication still not working well. I receive only wrong data in my Pc. Here is my code for setting uart (i am using mplab compiler XC8):
TRISC6 = 1; \\ set in datasheet
TRISC7 = 1; \\ set in datasheet
SPBRG1=25; \\ 4 MHz oscilator
SPBRGH1=0;
TXSTA1bits.BRGH = 1; \\ high speed uart
BAUDCON1bits.BRG16 = 0; \\ 8 bit data
TXSTA1bits.TX9 = 0;
TXSTA1bits.SYNC = 0; \\ asynchronus mode
RCSTA1bits.SPEN = 1; \\ enable serial port
INTCONbits.GIE = 0; \\ set off interrupt
TXSTA1bits.TXEN = 1; \\ transmitter is enabled
while (1) {
TXSTA1bits.TXEN = 1;
//UART_Write_Text("Bye pic \n");
TXREG = 76;
__delay_ms(100);
TXSTA1bits.TXEN = 0;
}
Thanks for help
The transmit buffer register must be empty before loading the next byte to send. From the data sheet: "Once the TXREGx register transfers the data to the TSR register (occurs in one TCY), the TXREGx register is empty and the TXxIF flag bit is set."
It appears the object is to repeatedly send 'L' at 9600 baud with a delay to allow the host to process the received data. So change to last lines to:
TXSTA1bits.TXEN = 1;
while(1){
while (PIR1bits.TX1IF == 0);
TXREG = 76;
__delay_ms(100);
}
This is my code with configurate bits my external oscilator is for 100% 4 MHz and i dont have oscilloscope :(
#include <xc.h>
#include <String.h>
#include <pic18f46k80.h>
#define _XTAL_FREQ 4000000
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1L
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1L
#pragma config RETEN = OFF // VREG Sleep Enable bit (Ultra low-power regulator is Disabled (Controlled by REGSLP bit))
#pragma config INTOSCSEL = LOW // LF-INTOSC Low-power Enable bit (LF-INTOSC in Low-power mode during Sleep)
#pragma config SOSCSEL = DIG // SOSC Power Selection and mode Configuration bits (Digital (SCLKI) mode)
#pragma config XINST = OFF // Extended Instruction Set (Enabled)
// CONFIG1H
#pragma config FOSC = XT // Oscillator (XT oscillator)
#pragma config PLLCFG = OFF // PLL x4 Enable bit (Disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF // Internal External Oscillator Switch Over Mode (Disabled)
// CONFIG2L
#pragma config PWRTEN = OFF // Power Up Timer (Disabled)
#pragma config BOREN = SBORDIS // Brown Out Detect (Enabled in hardware, SBOREN disabled)
#pragma config BORV = 3 // Brown-out Reset Voltage bits (1.8V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)
// CONFIG2H
#pragma config WDTEN = SWDTDIS // Watchdog Timer (WDT enabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 1048576 // Watchdog Postscaler (1:1048576)
// CONFIG3H
#pragma config CANMX = PORTB // ECAN Mux bit (ECAN TX and RX pins are located on RB2 and RB3, respectively)
#pragma config MSSPMSK = MSK7 // MSSP address masking (7 Bit address masking mode)
#pragma config MCLRE = ON // Master Clear Enable (MCLR Enabled, RE3 Disabled)
// CONFIG4L
#pragma config STVREN = ON // Stack Overflow Reset (Enabled)
#pragma config BBSIZ = BB2K // Boot Block Size (2K word Boot Block size)
// CONFIG5L
#pragma config CP0 = OFF // Code Protect 00800-03FFF (Disabled)
#pragma config CP1 = OFF // Code Protect 04000-07FFF (Disabled)
#pragma config CP2 = OFF // Code Protect 08000-0BFFF (Disabled)
#pragma config CP3 = OFF // Code Protect 0C000-0FFFF (Disabled)
// CONFIG5H
#pragma config CPB = OFF // Code Protect Boot (Disabled)
#pragma config CPD = OFF // Data EE Read Protect (Disabled)
// CONFIG6L
#pragma config WRT0 = OFF // Table Write Protect 00800-03FFF (Disabled)
#pragma config WRT1 = OFF // Table Write Protect 04000-07FFF (Disabled)
#pragma config WRT2 = OFF // Table Write Protect 08000-0BFFF (Disabled)
#pragma config WRT3 = OFF // Table Write Protect 0C000-0FFFF (Disabled)
// CONFIG6H
#pragma config WRTC = OFF // Config. Write Protect (Disabled)
#pragma config WRTB = OFF // Table Write Protect Boot (Disabled)
#pragma config WRTD = OFF // Data EE Write Protect (Disabled)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protect 00800-03FFF (Disabled)
#pragma config EBTR1 = OFF // Table Read Protect 04000-07FFF (Disabled)
#pragma config EBTR2 = OFF // Table Read Protect 08000-0BFFF (Disabled)
#pragma config EBTR3 = OFF // Table Read Protect 0C000-0FFFF (Disabled)
// CONFIG7H
#pragma config EBTRB = OFF // Table Read Protect Boot (Disabled)
void main(void) {
TRISD = 0;
ANCON0 = 0;
ANCON1 = 0;
TRISA = 0b00001111;
TRISE = 0b00000000;
TRISB = 0;
TRISCbits.TRISC6 = 1; // set in datasheet
TRISCbits.TRISC7 = 1; // set in datasheet
SPBRG1=25; // 4 MHz oscilator
SPBRGH1=0;
TXSTA1bits.BRGH = 1; // high speed uart
BAUDCON1bits.BRG16 = 0;// 8 bit data
TXSTA1bits.TX9 = 0;
TXSTA1bits.SYNC = 0; // asynchronus mode
RCSTA1bits.SPEN = 1; // enable serial port
INTCONbits.GIE = 0; // set off interrupt
TXSTA1bits.TXEN = 1; // transmitter is enabled
while (1) {
while (PIR1bits.TX1IF == 0);
TXREG = 76;
__delay_ms(100);
}
return;
}