Timer1 on low priority doesn't work - embedded

I am using MPLAB XC8 compiler with PIC18F87J11 and I need to use the internal time1 for counting purposes. I noticed that my code works perfectly fine if the interrupt is set to high priority. However with low priority it doesn't work and I just can't figure it out.
Timer 1 Settings:
// 1/1 prescalar
T1CONbits.T1CKPS1 = 1;
T1CONbits.T1CKPS0 = 1;
// Use Internal Clock
T1CONbits.TMR1CS = 0;
// Timer1 overflow interrupt
PIE1bits.TMR1IE = 1;
// Enable Timer 1
T1CONbits.TMR1ON = 1;
INTCONbits.PEIE = 1; // Enable Perpherial Interrupt
INTCONbits.GIE = 1; // Enable Global Interrupt
This works fine
void interrupt high_priority lowISR(void) {
if (PIR1bits.TMR1IF == 1) {
Printf("\r\n 1 second");
PIR1bits.TMR1IF = 0;
}
}
However this doesn't and I don't know why.
void interrupt low_priority lowISR(void) {
if (PIR1bits.TMR1IF == 1) {
Printf("\r\n 1 second");
PIR1bits.TMR1IF = 0;
}
}
What did I miss?

Are you actually setting timer 1 to use the low-priority interrupt, and are you enabling interrupt priority control (by default, IIRC, all interrupts use high priority regardless of the individual-interrupt-source priority bit).

I was missing the following, adding them fixed my issue. I found them here.
IPR1bits.TMR1IP = 0; // Timer 1 -> Low priority interrupt group
PIE1bits.TMR1IE = 1; // Enable Timer1 interrupt
RCONbits.IPEN = 1; // Enable interrupt system priority feature
INTCONbits.GIEH = 1; // Enable high priority interrupts
INTCONbits.GIEL = 1; // Enable low priority interrupts

Related

atmega 328p interrupt and timer setup [C/C++]

I am trying to set up one interrupt and one counter/timer. The interrupt is external, reading low logic from pin. Timer should increment every 100 us and add up to count variable.
I've set up the interrupt, which is working fine however, after setting up a timer, neither interrupt nor timer works. The code is such:
volatile boolean allowCount = false, timerFlag = false;
volatile unsigned int counter;
boolean pulseLow = false;
void setup(){
Serial.begin(9600);
// initialize external pin interrupt.
PCICR = 0b00000010; // 1. PCIE1: Pin Change Interrupt Enable 1
EICRA |= bit (ISC10); // set wanted flags (low logic level causes interrupt)
PCMSK1 = 0b00010000; // Enable Pin Change Interrupt for A4
// TODO Interrupt settings not working together
// initialize Timer1
cli(); // disable global interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
// set compare match register to desired timer count:
OCR1A = 0x18;
// turn on CTC mode:
TCCR1B |= (1 << WGM12);
// Set CS10 and CS12 bits for 64 prescaler:
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS11);
// enable timer compare interrupt:
TIMSK1 |= (1 << OCIE1A);
}
void loop(){
if (allowCount == true)
{ timer100_uS();
if (counter > 50 && pulseLow == false){
DDRC |= (1 << DDC3 ); // sets bit DDC3 to 1 within register DDRC
//set pin 3(A3) ouput as sourcing Vcc(HIGH)
PORTC |= (1 << PORTC3);
timerReset();
pulseLow = true;
}
if (pulseLow == true){
timer100_uS();
if (counter >= 500){
//set pin3 of port C to LOW (A3);
PORTC &= ~(1 << PORTC3);
pulseLow = false
timerReset();
}
}
// external pin interrupt
ISR(PCINT1_vect){
if (allowCount == false)
allowCount = true;
}
// timer/counter interrupt
ISR (TIMER1_COMPA_vect)
{
if (timerFlag == true){
counter++;
}
}
void timer_100uS(void){
timerFlag = true;
cli();
}
void timerReset(void){
sei();
timerFlag = false;
counter = 0;
}
Value of OCR0A is calculated to be 24 (0x18) with prescaler 64 and 16 MHz processor based on this formula:
OCRn = [ (clock_speed / Prescaler_value) * Desired_time_in_Seconds ] - 1
How to set up different interrupts so that they don't overlap eachother ?
Or better yet, is it possible to set up timer so that it does not use interrupt ?
Thanks for reading !
As I can see, you are using ATMega328 with Arduino libraries. Your problem is that Arduino library internally uses Timer 1 for its internal purposes. Therefore if you add your own interrupt handler for Timer 1, you override Arduino's interrupt handler for Timer 1 which breaks the library.
If you want to stay with Arduino library, use the library also to control the timer: Arduino Timer1
Thank you for answers #old_timer, #klasyc.
Quite late, but I solved it by using timer0 instead of timer1 with following settings in setup:
// initialize external pin interrupt.
PCICR = 0b00000010; // 1. PCIE1: Pin Change Interrupt Enable 1
EICRA |= bit (ISC10); // set wanted flags (falling edge causes interrupt)
PCMSK1 = 0b00001000; // Enable Pin Change Interrupt for A3
TCCR0B = 0;
TCCR0A = 0;
//set CTC mode
TCCR0A = ( 1 << WGM01 );
// set OCR0A value for 1 us counter (OCRxn = (freq/prescaler)*desired_value)-1
OCR0A = 15;
// set compare match counter
TIMSK0 |= (1 << OCIE0A);
//set prescaler
TCCR0B |= ( 1 << CS00);
and outside the loop:
ISR(TIMER0_COMPA_vect){
counter++;
}

PIC24FJ False interrupt trigger during first run

I am working on interrupt driven UART on PIC24FJ256GB606 device. My code works just fine except UART receive interrupt gets falsely triggered for the first time: e.g.
main routine is :
[code]
int main(){
System_init();
uart_init();
// UART2_PPS
RPINR19bits.U2RXR= 21;
RPOR13bits.RP26R = 5;
TRISGbits.TRISG6 = 1;
TRISGbits.TRISG7 = 0;
uart_puts("\n**********************************************");
uart_puts("\nMy project ");
uart_puts("\n x");
uart_puts("\n x");
uart_puts("\n"__DATE__);
uart_puts("\n**********************************************");
return -1;
}
}
[/code]
ISR is:
[code]void __attribute__ ( ( interrupt, no_auto_psv ) ) _U2RXInterrupt( void )
{
IFS1bits.U2RXIF = 0;
uart_puts("False Trigger");
__delay_ms(1000);
}[/code]
Initialization is:
[![\[code\]int uart_init()
{
int status = -1;
size_t i;
// STSEL 1; IREN disabled; PDSEL 8N; UARTEN enabled; RTSMD disabled; USIDL disabled; WAKE disabled; ABAUD disabled; LPBACK disabled; BRGH enabled; URXINV disabled; UEN TX_RX;
U2MODE = 0x8008;
// OERR NO_ERROR_cleared; URXISEL RX_ONE_CHAR; UTXBRK COMPLETED; UTXEN disabled; ADDEN disabled; UTXISEL0 TX_ONE_CHAR; UTXINV disabled;
U2STA = 0x0000;
// U2TXREG 0;
U2TXREG = 0x0000;
// BaudRate = 9600; Frequency = 4000000 Hz; U2BRG 103;
U2BRG = 0x0067;
// ADMADDR 0; ADMMASK 0;
U2ADMD = 0x0000;
rb_attr_t attr = {sizeof(_rbmem\[0\]), ARRAY_SIZE(_rbmem), _rbmem};
if (ring_buffer_init(&_rbd, &attr) == 0) {
U2MODEbits.UARTEN = 1; // And turn the peripheral on
U2STAbits.UTXEN = 1; //UART2 Transmit Enable
IFS1bits.U2RXIF = 0; //_U2RXIF = 0;
IEC1bits.U2RXIE = 1; //_U2RXIE = 1;
status = 0;
}
return status;
}\[/code\]][1]][1]
please see the image attached and consider following,
1) microcontroller is not expected to receive anything at this point. i tried to run the same code leaving rx line open i got the same result.
2) This code works just fine if i disable the receive interrupt IEC1bits.U2RXIE = 0;
Hi Doynax thank you for response. The initialization code was generated by MCC and was buggy!
i received a response on another forum:
Hi,
The initialization code for UART look like it may have been generated by MCC.
Despite this, it demonstrate bad programming practice, in that it enable the module before other setup operations.
What is done, is contrary to what is recommended in datasheet for this device,
and for all other devices that I have looked at.
Datasheet section 19.2 Transmitting in 8-Bit Data Mode and section 19.3 Receiving in 8-Bit or 9-Bit Data
Mode:
1. Set up the UARTx:
a) Write appropriate values for data, parity and Stop bits.
b) Write appropriate baud rate value to the UxBRG register.
c) Set up transmit and receive interrupt enable and priority bits.
2. Enable the UARTx.
2. Enable the UARTx by setting the URXEN bit (UxSTA<12>).
Also, in the generated code, there is a write to TXREG = 0000;
This do not only clear the register, it may also queue transmission of a first byte in the transmitter FIFO register.
Regards,
Mysil
changing the initialization sequence solved the problem!

PIC32MX795F512H UART communication to RS232

I am currently working for the first time with a PIC microcontroller. In the code I specified exactly which PIC, compiler, etc I am using. Maybe this is of help.
I am trying to set up UART communication on the PIC32 and send a hex code like 0x41 for example to a terminal on my computer through RS232. To convert the signal from the PIC UART to RS232 levels I am using a MAX232EPE.
At the moment I am running into the problem that when I send 0x41 for example from the PIC32 to the terminal or vice versa, the received data doesn't match. I think this being caused by a mistake in my baud rate settings, but I am not sure. Could someone please look over my code and see if someone can see a problem? Did I forget to define something? Did I define something wrong? Did I mis calculate the baud rate?
P.S. I know the data being received doesn't match the data send because i checked in the "watches" in debug mode in mplab and when I echo the data send from the terminal to the PIC32 back to the terminal it doesn't match either.
The Delay and interrupt code can be ignored, they are working as expected, so I really believe the problem has to do with the initial setting of the PIC/buad rate.
I hope this is clear enough, any help is very much appreciated
Thanks,
See code below
/*
The configuration below and in void UART1_Init should set up the UART correctly.
I want to achieve a buadrate of 9600. My external Crystal is 8MHz. So:
FPLLIDIV=2, FPLLMUL=20, FPLLODIV=1, FPBDIV=2, FNOSC=PRIPLL, BRGH = 0, and U1BRG = 259.
This should give me the desired baudrate of 9600.
- ((8MHz / 2) * 20)/2) = 40MHz PBclk.
- U1BRG = (PBclk/(16*Buad rate))-1 so 259
- 16*Buad rate because BRGH = 0
PIC32MX795F512H
MPLAB X IDE V3.26
XC32 Compiler
PICKit3
*/
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include <plib.h>
// Give useful names to pins
#define LED1_TRIS TRISDbits.TRISD6
#define LED1 LATDbits.LATD6
#define UART1TX_TRIS TRISDbits.TRISD3
#define UART1RX_TRIS TRISDbits.TRISD2
#define FOSC 8000000 // Crystal frequency = 8 MHz
#define SYS_FREQ (80000000UL) // SYSCLK is 80 MHz
#define GetSystemClock() (FOSC) // For delay
#pragma config FPLLIDIV=DIV_2 // PLL Input Divider Value (Divide by 2)
#pragma config FPLLMUL=MUL_20 // Phase-Locked Loop (PPL) muiltiplier, multiplier of 20
#pragma config FPLLODIV=DIV_1 // Postscaler for PLL, output divided by 1
#pragma config FPBDIV=DIV_2 // 2 = PBCLK is SYSCLK divided by 2 (80MHz/2 = 40MHz)
#pragma config FWDTEN=OFF // Watch Dog Timer (WDT) is not enabled. It can be enabled by software
#pragma config CP=OFF // Code-Protect, 1 = OFF/Disabled
#pragma config BWP=OFF // Boot Flash Write-protect, 1 = OFF/Disabled
#pragma config POSCMOD=XT // Primary oscillator configuration, HS = HS Oscillator mode selection
#pragma config FNOSC=PRIPLL // Oscillator selection, PRIPLL = Primary Oscillator with PLL module
#pragma config OSCIOFNC=OFF // CLKO output disabled
#pragma config FSOSCEN=OFF // Disable secondary Oscillator
int UART_RX_Count; // Counter variable for the UART1 receiver interrupt
int UART_TX_Count; // Counter varible for the UART1 transmitted interrupt
unsigned char RD_SER_NUM; // Variable to store command to read serial number
unsigned char UART_RX_OUTPUT; // Variable to store the UART output
unsigned char i;
void UART1_Init(void){
// UART1 initialization
U1MODEbits.ON = 1; // UART1 is enabled
U1MODEbits.SIDL = 0; // Continue operation in idle mode
U1MODEbits.IREN = 0; // Disable IrDA (IrDA Encoder and Decoder Enable bit)
U1MODEbits.RTSMD = 1; // !U1RTS! pin is in Simplex mode, 0 = !U1RTS! pin is in Flow Control mode
U1MODEbits.UEN = 0; // UxTX and UxRX pins are enabled and used; UxCTS and UxRTS/UxBCLK pins are controlled by corresponding bits in the PORTx register
U1MODEbits.WAKE = 1; // Enable Wake-up on Start bit Detect During Sleep Mode bit
U1MODEbits.LPBACK = 0; // UARTx Loopback Mode Select bit, 0 = disabled, loopback = UxTX output is internally connected to the UxRX input
U1MODEbits.PDSEL = 2; // Parity and Data Selection bits, 10 = 8-bit data, odd parity
U1MODEbits.STSEL = 0; // Stop Selection bit, 0 = 1 stop bit
U1MODEbits.BRGH = 0; // High Baud Rate Enable bit, 0 = Standard Speed mode 16x baud clock enabled
U1MODEbits.RXINV = 1; // Receive Polarity Inversion bit, 1 = UxRX Idle state is 0
U1STAbits.URXEN = 1; // 1 = UART1 receiver is enabled. U1RX pin is controlled by UARTx (if ON = 1)
U1STAbits.UTXEN = 1; // 1 = UART1 transmitter is enabled. U1TX pin is controlled by UARTx (if ON = 1)
U1STAbits.UTXINV = 1; // Transmit Polarity Inversion bit, 1 = UxTX Idle state is 0
U1STAbits.ADM_EN = 0; // 0 = Automatic Address Detect mode is disabled
U1BRG = 259; // Baud Rate Divisor bits (0-15 bits), set baud rate, 9600 # 40 MHz PBclk
__builtin_disable_interrupts(); // Tell CPU to stop paying attention to interrupts
INTCONbits.MVEC = 1; // Multi Vector interrupts
U1STAbits.URXISEL = 0; // 0x = Interrupt flag bit is set when a character is received
U1STAbits.UTXISEL = 1; // 01 = Interrupt flag bit is set when all characters have been transmitted
IPC6bits.U1IP = 5; // Set UART1 priority 5 of 7
IPC6bits.U1IS = 0; // Set UART1 sub priority to 0
IFS0bits.U1RXIF = 0; // Clear UART1 RX interrupt flag
IFS0bits.U1TXIF = 0; // Clear UART1 TX interrupt flag
IEC0bits.U1RXIE = 1; // Enable UART1 RX ISR
__builtin_enable_interrupts(); // Tell CPU to start paying attention to interrupts again
UART_RX_Count = 0; // Set initial UART1 received interrupts count to 0
UART_TX_Count = 0; // Set initial UART1 transmit interrupts count to 0
}
void __ISR(_UART_1_VECTOR, IPL5SRS) UART1_INT(void){
if(INTGetFlag(INT_U1RX)){ // Check if UART1 RX interrupt was triggered
LED1 = ~LED1; // Toggle LED1
UART_RX_Count++; // Add 1 to UART1 RX interrupt occurrence counter
// UART_RX_OUTPUT = U1RXREG; // Read UART1 RX buffer/register
U1TXREG = U1RXREG; // Transmit the received data back
// U1STAbits.OERR = 0; // Clear UART1 buffer overflow
IFS0bits.U1RXIF = 0; // Clear UART1 RX interrupt flag
}else{
if(INTGetFlag(INT_U1TX)){ // Check if UART1 TX interrupt was triggered
UART_TX_Count++; // Add 1 to UART1 TX interrupt occurrence counter
IEC0bits.U1TXIE = 0; // Disable UART1 TX ISR
IFS0bits.U1TXIF = 0; // Clear UART1 TX interrupt flag
}
}
}
// DelayMs creates a delay of given milliseconds using the Core Timer
void DelayMs(WORD delay){
unsigned int int_status;
while( delay-- ){
int_status = INTDisableInterrupts();
OpenCoreTimer(GetSystemClock() / 200);
INTRestoreInterrupts(int_status);
mCTClearIntFlag();
while( !mCTGetIntFlag() );
}
mCTClearIntFlag();
}
int main(){
UART1_Init(); // Call the initializations function of UART1
LED1_TRIS = 0; // Set the LED1 as an output
UART1TX_TRIS = 0; // Set UART1 TX pin as output
UART1RX_TRIS = 1; // Set UART1 RX pin as input
LED1 = 0; // Turn off LED1
while(1){
// DelayMs(1000);
// IEC0bits.U1TXIE = 1; // Enable UART1 TX ISR
// U1TXREG = 0x41; // Send command to U1TXREG
}
return 0;
}
As You are using PIC32MX795F512H, You can use the MPLAB Harmony framework tool for creating your project. So that you need not to play on bit level and stuck in minor error or most probabaly typo error.
Its convinient to generate drivers and all framework properly.
Thanks and regards
Ravi
Using Harmony will actually help you avoid simple errors like the one you have encountered. Especially for the clocks you even have auto calculating functions decreasing your implementation time significantly.

PIC (dsPIC33EP 512MU810) : High Speed PWM module

I'm trying to generate a 10% duty cycle-1kHz PWM with a clock at 80Mhz (F_osc) using the inbuilt (Hardware) high speed PWM.
According to the documentation,
Base Period (number for the PTPER) is calculated by
PTPER = F_osc / [(F_pwm) x (PWM_Clk_Prescale)]
Substituting F_osc = 80Mhz, F_pwm = 1khz and Prescale = 8, I'm getting a count of PTPER=10,000.
However, from my output on an oscilloscope, I can see that I have PWM frequency of ~2khz..
Am I doing anything wrong? Below is my code --
#include<p33EP512MU810.h>
#include<p33Exxxx.h>
//---------------- compiler directives------------------
_FOSCSEL(FNOSC_FRC);
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT); // Clock Switching Enabled and Fail Safe Clock Monitor is disabled
// OSC2 Pin Function: OSC2 is Clock Output
// Primary Oscillator Mode: XT Crystal
_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software
//------------------------------------------------------
//function to initialise oscillator and set up clock
void Init_Oscillator(void)
{
// Configure Oscillator to operate the device at 40Mhz
// Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
// Fosc= 12M*40/(3*2)=80Mhz for 12M input clock
// 0.5M < Fin/N1 < 8MHz
// 100M < Fin*M/N2 < 200M
// Fcy = Fosc / 2 = 40 MIPS
PLLFBD = 38; // M=80
CLKDIVbits.PLLPOST = 0; // N2=2
CLKDIVbits.PLLPRE = 1; // N1=3
OSCTUN = 0; // Tune FRC oscillator, if FRC is used
RCONbits.SWDTEN=0; // Disable Watch Dog Timer
// Clock switch to incorporate PLL
__builtin_write_OSCCONH(0x03); // Initiate Clock Switch to
// Primary Oscillator with PLL (NOSC=0b011)
__builtin_write_OSCCONL(0x01); // Start clock switching
while (OSCCONbits.COSC != 0b011); // Wait for Clock switch (to XT w/ PLL) to occur
while(OSCCONbits.LOCK!=1) {}; // Wait for PLL to lock
}
void Init_PWM(void)
{
/**** PTCON: PWM Time Base Control Register ****/
PTCONbits.PTEN = 0; // Timer Enable bit: DISABLE MCPWM
//---------------------------------------------------------------
//Prescaler 1:8
PTCON2bits.PCLKDIV = 0b011; // PCLKSEL: 1,2,4,8,16,32,64
//mode selection
PWMCON1 = 0x0000; //PTPER holds period count of PWM
//Independent mode enable
IOCON1 = 0xCC00; //fig 14-35 of PWM manual
// 0xCC00 => PENH high, PENL high, PMOD: 11- True Independent PWM o/p
//---------------------------------------------------------------
/**** PTPER: PWM Time Base Period Register ****/
PTPER = 10000; // Period Value bits
//Enable PWM timer
PTCONbits.PTEN = 1; // Timer Enable bit: ENABLE MCPWM
}
//--- extra settings:
// 1) Stop in IDLE MODE :: PTCONbits.PTSIDL = 1 (yes)
// 2) Setting a particular pin as output ==> IOCONxbits.PENH(/L) = 1(enabled)
// 3) MDC,PDC,SDC et al depend on the PWM MODE.
// Resp, selection of PTPER,PHASE,SPHASE.
//---
int main(void)
{
Init_Oscillator();
Init_PWM();// Initialize PWM module
PDC1 = 1000; // This sets the duty cycle.
while(1); //loop forever //while
return 0;
}
Despite your comments, I believe you have
PLLDIV = 78 // M = 80
So,
FOSC = FIN * PLLDIV / ((PLLPRE + 2) * 2 * (PLLPOST + 1))
FOSC = 8MHz * 80 / ((1 + 2) * 2 * (0 + 1))
FOSC = 8MHz * 80 / 6
FOSC = ~ 107 MHz
your pwm CONFIG for 80MHZ is right but make sure that your input frequency is 12MHZ ...i already test pwm for 80mhz with the same config of PWM and its generating proper output as you need 1KHZ. so check your PLL and Fcrystal config. i think you are generating pll 160MHZ.if you are using M=80 then you have to replace it with M=40 (PLLFBD = 38;),correct your comment or code.

No interrupts being triggered in UART Receive on PIC18F2680

I have been working with this code for days and cannot figure out why my interrupts are not being triggered. I know data is coming through successfully because I used a probe on a logic analyzer, also my baud rate is correct as I can transmit with UART successfully.
At this point I'm lost, I've read the datasheet over and over and can't figure out my problem. I will try to include only the relative code but enough that you can see how things work in my project.
Please let me know if you see issues with this code.
Thank you!
Code snippets from main.c:
// USART RX interrupt priority
IPR1bits.RCIP = 0;
IPR1bits.TXIP = 0;
// configure the hardware USART device
OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
USART_CONT_RX & USART_BRGH_LOW, 14);
Code snippets from interrupts.c
//----------------------------------------------------------------------------
// Low priority interrupt routine
// this parcels out interrupts to individual handlers
#pragma code
#pragma interruptlow InterruptHandlerLow
// This works the same way as the "High" interrupt handler
void InterruptHandlerLow() {
// check to see if we have an interrupt on USART RX
if (PIR1bits.RCIF) {
PIR1bits.RCIF = 0; //clear interrupt flag
uart_recv_int_handler();
}
// check to see if we have an interrupt on USART TX
if (PIR1bits.TXIF && PIE1bits.TXIE) {
// cannot clear TXIF, this is unique to USART TX
// so just call the handler
uart_tx_int_handler();
}
}
UART RX Interrupt Handler snippet:
void uart_recv_int_handler() {
int msgLen;
//if (DataRdyUSART()) {
uc_ptr->buffer[uc_ptr->buflen] = RCREG;
//uc_ptr->buffer[uc_ptr->buflen] = ReadUSART();
uc_ptr->buflen++;
}
}
Did you
- Set trisC6/7 correctly?
- if you have a part with analog inputs multiplexed on those pins, did you disable them?
- Is your BRG value validated for this part and these oscillator settings?
See also
http://www.piclist.com/techref/microchip/rs232.htm
I migrated to dspic, but I used to do the serial receive under interrupt. This I had in the interrupt (serialin1 is a power of two circular buffer, lastserialin1 the pointer into it, and ser1bufinmask is size of buffer-1)
if (PIR1bits.RCIF == 1) /* check if RC interrupt (receive USART) must be serviced
{
while (PIR1bits.RCIF == 1) /* flag becomes zero if buffer/fifo is empty */
{
lastserialin1=(lastserialin1+1)&ser1bufinmask;
serialin1[lastserialin1]=RCREG;
}
}
To initialize the uart I had:
// Configure USART
TXSTA = 0x20; // transmit enable
RCSTA = 0x90; // spen en cren
RCONbits.IPEN = 1; /* Interrupt Priority Enable Bit. Enable priority levels on interrupts */
INTCONbits.GIE = 1; /* Set GIE. Enables all high priority unmasked interrupts */
INTCONbits.GIEL = 1; /* Set GIEL. Enables all low priority unmasked interrupts */
TRISCbits.TRISC6 = 0; // page 237
TRISCbits.TRISC7 = 1; // page 237
Open1USART (
USART_TX_INT_OFF
&
USART_RX_INT_ON &
USART_ASYNCH_MODE &
USART_EIGHT_BIT & // 8-bit transmit/receive
USART_CONT_RX & // Continuous reception
// USART_BRGH_HIGH, 155); // High baud rate, 155 eq 19k2
USART_BRGH_HIGH, brgval); // High baud rate, 25 eq 115k2
IPR1bits.RCIP = 0;
PIR1bits.RCIF = 0;
with brgval calculated using
#define GetInstructionClock() (GetSystemClock()/4)
#define GetPeripheralClock() GetInstructionClock()
// See if we can use the high baud rate setting
#if ((GetPeripheralClock()+2*BAUD_RATE)/BAUD_RATE/4 - 1) <= 255
#define BRGVAL ((GetPeripheralClock()+2*BAUD_RATE)/BAUD_RATE/4 - 1)
#define BRGHVAL (1)
#else // Use the low baud rate setting
#define BRGVAL ((GetPeripheralClock()+8*BAUD_RATE)/BAUD_RATE/16 - 1)
#define BRGHVAL (0)
#endif