dspic33ev256gm002 UART - uart

I'm developing a project with dsPIC33EV256GM002 and I want to use its UART.
So I decided to use PIN18 as RX and PIN17 as TX so I programed PPS as follow:
// UART1 RX1 18 RP41 RPINR18 010 1001 (41)
// UART1 TX1 17 RP40 RPOR3.RP40R 000 0001 (1)
RPINR18bits.U1RXR=41;
RPOR3bits.RP40R = 1;
and I put PIN18 (RB 9) as input setting the bit9 of TRISB.
I used an external 8M XTAL and I set M,N1 and N2 parameter as follow:
// Configure Oscillator to operate the device at 80MHz/40MIPs
// Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
// Fosc= 8M*40/(2*2)=80Mhz for 8M input clock
// To be safe, always load divisors before feedback
CLKDIVbits.PLLPOST = 0; // N1=2
CLKDIVbits.PLLPRE = 0; // N2=2
PLLFBD = 38; // M=(40-2), Fcyc = 40MHz for ECAN baud timer
// Disable Watch Dog Timer
RCONbits.SWDTEN = 0;
I want to configure the TX/RX port as 31250,N,8,1 (standard MIDI parameters)
// configure U1MODE
U1MODEbits.UARTEN = 0; // Bit15 TX, RX DISABLED, ENABLE at end of func
//U1MODEbits.notimplemented; // Bit14
U1MODEbits.USIDL = 0; // Bit13 Continue in Idle
U1MODEbits.IREN = 0; // Bit12 No IR translation
U1MODEbits.RTSMD = 0; // Bit11 Simplex Mode
//U1MODEbits.notimplemented; // Bit10
U1MODEbits.UEN = 0; // Bits8,9 TX,RX enabled, CTS,RTS not
U1MODEbits.WAKE = 0; // Bit7 No Wake up (since we don't sleep here)
U1MODEbits.LPBACK = 0; // Bit6 No Loop Back
U1MODEbits.ABAUD = 0; // Bit5 No Autobaud (would require sending '55')
U1MODEbits.URXINV = 0; // Bit4 IdleState = 1 (for dsPIC)
U1MODEbits.BRGH = 0; // Bit3 16 clocks per bit period
U1MODEbits.PDSEL = 0; // Bits1,2 8bit, No Parity
U1MODEbits.STSEL = 0; // Bit0 One Stop Bit
// U1BRG = (Fcy/(16*BaudRate))-1
// Fcy=40
// U1BRG = (40000000/(16*BaudRate))-1
// U1BRG = (40000000/(16*31250))-1 = 79
U1BRG = 79; // 40Mhz osc, 31250 Baud
// Load all values in for U1STA SFR
U1STAbits.UTXISEL1 = 0; //Bit15 Int when Char is transferred (1/2 config!)
U1STAbits.UTXINV = 0; //Bit14 N/A, IRDA config
U1STAbits.UTXISEL0 = 0; //Bit13 Other half of Bit15
//U1STAbits.notimplemented = 0; //Bit12
U1STAbits.UTXBRK = 0; //Bit11 Disabled
U1STAbits.UTXEN = 0; //Bit10 TX pins controlled by periph
U1STAbits.UTXBF = 0; //Bit9 *Read Only Bit*
U1STAbits.TRMT = 0; //Bit8 *Read Only bit*
U1STAbits.URXISEL = 0; //Bits6,7 Int. on character recieved
U1STAbits.ADDEN = 0; //Bit5 Address Detect Disabled
U1STAbits.RIDLE = 0; //Bit4 *Read Only Bit*
U1STAbits.PERR = 0; //Bit3 *Read Only Bit*
U1STAbits.FERR = 0; //Bit2 *Read Only Bit*
U1STAbits.OERR = 0; //Bit1 *Read Only Bit*
U1STAbits.URXDA = 0; //Bit0 *Read Only Bit*
IPC2bits.U1RXIP = 1; // Mid Range Interrupt Priority level, no urgent reason
IPC3bits.U1TXIP = 1; // Mid Range Interrupt Priority level, no urgent reason
IFS0bits.U1TXIF = 0; // Clear the Transmit Interrupt Flag
IEC0bits.U1TXIE = 1; // Enable Transmit Interrupts
IFS0bits.U1RXIF = 0; // Clear the Recieve Interrupt Flag
IEC0bits.U1RXIE = 1; // Enable Recieve Interrupts
U1MODEbits.UARTEN = 1; // And turn the peripheral on
for your reference this is the OSC configuration
_FOSCSEL(FNOSC_PRIPLL);
_FOSC(FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMD_XT);
// Startup directly into XT + PLL
// OSC2 Pin Function: OSC2 is Clock Output
// Primary Oscillator Mode: XT Crystal
_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software
_FICD(ICS_PGD1); // PGD3 for external PK3/ICD3/RealIce, use PGD2 for PKOB
_FDEVOPT( PWMLOCK_OFF );
_FOSCSEL(FNOSC_PRIPLL);
_FOSC(FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMD_XT);
// Startup directly into XT + PLL
// OSC2 Pin Function: OSC2 is Clock Output
// Primary Oscillator Mode: XT Crystal
Since I can't detect data from serial RX because I detect a framing error, I would know if the setting that I used are correct.
Have you similar experience ?

Related

dsPIC33EP128MC202 UART receiver doesn't work

I wrote the code for UART communication. TX is working fine, but RX is not working. I have searched a lot but found no solution.
I am transmitting character x to PC with time interval, and I am able see the data. But when transmits data pic is not receiving any thing.
Below are pins used for uart
//PGEC1/AN4/C1IN1+/RPI34/RB2 for receiver
RPINR18bits.U1RXR = 34;
//RP36/RB4 for transmitting data
RPOR1bits.RP36R = 1;
I am able transmit data to pc but PIC doesn't receive any charector from pc.
Thanks in advance
Here is my code.
DSPIC33EP128MC202
/*
* File: newmainXC16.c
* Author:
*
* Created on 27 December, 2017, 4:21 PM
*/
// FICD
#pragma config ICS = PGD3 // ICD Communication Channel Select bits (Communicate on PGEC3 and PGED3)
#pragma config JTAGEN = OFF // JTAG Enable bit (JTAG is disabled)
// FPOR
#pragma config ALTI2C1 = OFF // Alternate I2C1 pins (I2C1 mapped to SDA1/SCL1 pins)
#pragma config ALTI2C2 = OFF // Alternate I2C2 pins (I2C2 mapped to SDA2/SCL2 pins)
#pragma config WDTWIN = WIN25 // Watchdog Window Select bits (WDT Window is 25% of WDT period)
// FWDT
#pragma config WDTPOST = PS32768 // Watchdog Timer Postscaler bits (1:32,768)
#pragma config WDTPRE = PR128 // Watchdog Timer Prescaler bit (1:128)
#pragma config PLLKEN = ON // PLL Lock Enable bit (Clock switch to PLL source will wait until the PLL lock signal is valid.)
#pragma config WINDIS = OFF // Watchdog Timer Window Enable bit (Watchdog Timer in Non-Window mode)
#pragma config FWDTEN = OFF // Watchdog Timer Enable bit (Watchdog timer enabled/disabled by user software)
// FOSC
#pragma config POSCMD = NONE // Primary Oscillator Mode Select bits (Primary Oscillator disabled)
#pragma config OSCIOFNC = ON // OSC2 Pin Function bit (OSC2 is clock output)
#pragma config IOL1WAY = ON // Peripheral pin select configuration (Allow only one reconfiguration)
#pragma config FCKSM = CSDCMD // Clock Switching Mode bits (Both Clock switching and Fail-safe Clock Monitor are disabled)
// FOSCSEL
#pragma config FNOSC = FRCPLL // Oscillator Source Selection (Fast RC Oscillator with divide-by-N with PLL module (FRCPLL) )
#pragma config PWMLOCK = ON // PWM Lock Enable bit (Certain PWM registers may only be written after key sequence)
#pragma config IESO = ON // Two-speed Oscillator Start-up Enable bit (Start up device with FRC, then switch to user-selected oscillator source)
// FGS
#pragma config GWRP = OFF // General Segment Write-Protect bit (General Segment may be written)
#pragma config GCP = OFF // General Segment Code-Protect bit (General Segment Code protect is Disabled)
#include "xc.h"
#include <stdint.h>
#include <p33EP128MC202.h>
#define FP 60000000
#define BAUDRATE 115200
#define BRGVAL ((FP/BAUDRATE)/16)-1
#define DELAY_100uS asm volatile ("REPEAT, #5400"); Nop(); // 100uS delay
int main(void)
{
uint8_t c;
int i,j,a,b;
// Configure Oscillator to operate the device at 60Mhz
// Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
// Fosc= 8M*60/(2*2)=120Mhz for 8M input clock == 8*60/4 = 120/2 = 60
CLKDIVbits.PLLPOST=0; // PLLPOST (N1) 0=/2
while(!OSCCONbits.LOCK); // wait for PLL ready
PLLFBD = 58; // M=60
CLKDIVbits.PLLPOST = 0; // N1=2
CLKDIVbits.PLLPRE = 0; // N2=2
OSCTUN = 0; // Tune FRC oscillator, if FRC is used
/*Initialize the Ports */
TRISA = 0x00;
LATA = 0x0000;
PORTA = 0x0000;
ANSELAbits.ANSA1 = 0;
ANSELAbits.ANSA0 = 0;
__builtin_write_OSCCONL(OSCCON & ~(1<<6));
RPINR18bits.U1RXR = 34;
RPOR1bits.RP36R = 1;
__builtin_write_OSCCONL(OSCCON | (1<<6));
U1MODEbits.STSEL = 0;
U1MODEbits.PDSEL = 0;
U1MODEbits.ABAUD = 0;
U1MODEbits.BRGH = 0;
U1BRG = 30;
U1MODEbits.UARTEN = 1;
IEC0bits.U1TXIE = 0;
U1STAbits.UTXEN = 1;
U1STAbits.URXISEL = 0;
DELAY_100uS;
DELAY_100uS;
DELAY_100uS;
U1TXREG = 'X';
char ReceivedChar;
while(1){
//If data is received send data to TX
if(U1STAbits.URXDA == 1) {
ReceivedChar = U1RXREG + 2;
U1TXREG = 10;
U1TXREG = 13;
}
for(i=0;i<1000;i++){
a = a + 1;
for(j=0;j<2000;j++){
b = b + 1;
}
}
//LED Blink code for programme check
if(c == 0){
c = 1;
}else{
c = 0;
}
LATAbits.LATA0 = c;
LATAbits.LATA1 = c;
U1TXREG = 'x';
U1TXREG = 10;
U1TXREG = 13;
}
}
void __attribute__((interrupt, no_auto_psv)) _U1TXInterrupt( void )
{
IFS0bits.U1TXIF = 0; // Clear TX Interrupt flag
}
void __attribute__((interrupt, no_auto_psv)) _U1RXInterrupt( void )
{
IFS0bits.U1RXIF = 0; // Clear RX Interrupt flag
//cntr++;
U1TXREG='a';
U1TXREG = 10;
U1TXREG = 13;
}
I looked into the code, It works fine for me.
Please check the connection with your peripherals and their pins. If there is an extra connection to that pin remove it and try it again.
RB2 should be an an Input.
TRISB = 0x04;

PIC32MZ UART RX Interrupt

Porting from PIC32MX to MZ (PIC32MZ2048EFG100) and am banging head against wall trying to generate a simple RX interrupt on UART3. Please see code below.
void main(void} {
__builtin_disable_interrupts();
//Ensuring all pins config as digital
ANSELA = 0x0000;
ANSELB = 0x0000;
ANSELC = 0x0000;
ANSELD = 0x0000;
ANSELE = 0x0000;
ANSELF = 0x0000;
ANSELG = 0x0000;
//Convenient macrso to do IOUNLOCK
#define PPSUnLock() {SYSKEY=0x0;SYSKEY=0xAA996655;SYSKEY=0x556699AA;CFGCONbits.IOLOCK=0;}
#define PPSLock() {SYSKEY=0x0;SYSKEY=0xAA996655;SYSKEY=0x556699AA;CFGCONbits.IOLOCK=1;}
//Peripheral Pin Select (PPS) Settings for UART3
PPSUnLock();
U3RXRbits.U3RXR = 0b1010;
RPA14Rbits.RPA14R = 0b0001;
PPSLock();
//Config UART3
U3MODEbits.UEN0 = 0; //no flow control
U3MODEbits.UEN1 = 0;
U3MODEbits.LPBACK = 0; // no loopback
U3MODEbits.ABAUD = 0; //no autobaud
U3MODEbits.BRGH = 0;
U3MODEbits.PDSEL0 = 0; //8 data bits, no parity
U3MODEbits.PDSEL1 = 0;
U3MODEbits.STSEL = 0; // 1 stop bit
U3STAbits.URXISEL0 = 0; //RX Interrupt on first byte in FIFO
U3STAbits.URXISEL1 = 0;
U3BRG = CLOSEST_UBRG_VALUE115200; //Macro defined elsewhere, but it works
//Int priorities
IPC39bits.U3EIP = 6;
IPC39bits.U3EIS = 3;
//Int flags
IFS4bits.U3RXIF = 0;
//Int enable/disable
IEC4bits.U3EIE = 0;
IEC4bits.U3TXIE = 0;
IEC4bits.U3RXIE = 1; //Enable int on RX
//Enable multi-vector interrupts
INTCONSET = _INTCON_MVEC_MASK;
__builtin_enable_interrupts();
//Turn on UART3
U3STAbits.URXEN = 1;
U3STAbits.UTXEN = 1;
U3MODEbits.ON = 1;
UART_txEXTCOMandWait('A'); //Function defined elsewhere - I get successful byte "A" sent to my terminal. So TX works.
while(1){Nop();}; //wait in endless loop for interrupt to occur on keystroke
}
Below is my ISR:
void __ISR_AT_VECTOR (_UART3_RX_VECTOR, IPL6SOFT) U3Interrupt(void) {
unsigned int test=0;
Nop(); //Setting a breakpoint here
}
I successfully see an "A" on my terminal screen when running the program, so settings are correct for TX. Typing in text in my terminal screen yields no interrupts. Have verified with scope that signal is making it to the PIC32.
What am I missing here? I'm burning a ton of time on something that should be trivial.
Thanks guys.
Figured it out... It should be:
//Int priorities
IPC39bits.U3EIP = 6;
IPC39bits.U3EIS = 3;
Interesting how this had been working in production on PIC32MX for years.

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.

UART RX not working on PIC16F1704

I have got the UART TX working on one pic but cannot get the UART RX working on another PIC. My plan is to have the first PIC send data to the second PIC.
My initialisation code for the first PIC TX is,
Code:
void configure_TX_port(){
/*Port configurations*/
OSCCON = 0X68;
//Push button
TRISC3 = 1;
INLVLC3 = 0;
ANSC3 = 0;
//Led output
TRISC2 = 0;
//TX output
TRISA2 = 0;
ANSA2 = 0;
/*PPS setup for RA2*/
PPSLOCK = 0x55;
PPSLOCK = 0xAA;
PPSLOCK = 0;
RA2PPS = 0x14;
PPSLOCK = 0x55;
PPSLOCK = 0xAA;
PPSLOCK = 1;
/*UART configuration*/
TXEN = 1;
SYNC = 0;
SPEN = 1;
TXSTA = (0x4|0x20);
SPBRG = (int)(4000000L/(16UL * 9600) -1);
}
My send data to the tx code is
Code:
void putch(unsigned char byte) {
/* output one byte */
while (!TXIF) /* set when register is empty */
TXREG = byte;
}
My initialisation code for the second PIC RX is,
void configure_RX_port(){
/*Port configurations*/
OSCCON = 0X68;
//Led output
TRISC3 = 0;
//RX input
TRISC5 = 1;
ANSC5 = 0;
/*UART configuration*/
CREN = 1;
SYNC = 0;
SPEN = 1;
TXSTA = (0x4|0x20);
RCSTA = 0x90;
SPBRG = (int)(4000000L/(16UL * 9600) -1);
}
My receive data code is,
unsigned char getch(void) {
/* retrieve one byte */
unsigned char ret;
while (!RCIF) { /* set when register is not empty */
}
ret = RCREG;
return ret;
}
When I debug the code the getch function gets blocked waiting on a character but my other PIC is sending data. On this PIC RC5 is a designated RX pin so I dont think I have to do any pps configuration.
Rahul
TX1STA = 0b00100100; This enablex TX (TXEN=1) and high baud rate (BRGH = 1)
RC1STA = 0b10000000; This enable the serial port (SPEN = 1)
The only important missing part is your Clock setting and the baudrate you want to have.
I saw 4000000 in the formula, means 4MHz, and /9600, so assume 9600BDS).
Result = 0x25.
SPBRGL = 0x25;
SPBRGH = 0;
This way, your TX should work. Your tx function is good.
Be sure to configure RX and TX pins as DIGITAL by disabling ANSELA, ANSELB and ANSELC.
Your PIC also use PPS, so be sure to configure it the right way.
*********EDITED POST, RECEIVE CONDITION************
The only difference here to get a working receiver is to enable the continuous receiver
bit, CREN.
RC1STA = 0b10010000; //Enable serial port(SPEN) and continuous receive(CREN).
Be sure to set RX pin (RC5 in your case) as an INPUT (TRISC5 = 1) so that it can read any entering data. You should also consider doing an interrupt routine instead of polling the receiver flag bit. That way you're sure not to skip any entering data.
By default at reset all pins on PIC16F1704 are set as analog.
So clear coresponding bits of RX and TX pins in registers ANSELA, ANSELB and ANSELC to set tham as digital.
You look to be using asynchronous mode with SYNC = 0, but do not set TXEN = 1.
Setting CREN = 1 only overrides TXEN in synchronous mode. Try setting TXEN = 1.
I added the following line, TXSTA = (0x4|0x20); to the receiver PIC code and it works now. There is no need for
CREN = 1;
SYNC = 0;
SPEN = 1;
as its setting the same bits.

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.