I am beginner exploring PIC32MK1024MCM064 timers. Just want to write simple code with self triggering timer and some main program in the background. So I achieved my code to get into the ISR part, but the code gets stuck in the ISR after first time interrupt event. The code does not come back to the main loop with blinking leds. I investigated the datasheet quite well, but besides clearing the interrupt flag, I don`t know what to do else. I really thank you in advance for any help provided
// DEVCFG3
#pragma config USERID = 0xFFFF // Enter Hexadecimal value (Enter Hexadecimal value)
#pragma config PWMLOCK = OFF // PWM IOxCON lock (PWM IOxCON register writes accesses are not locked or protected)
#pragma config FUSBIDIO2 = ON // USB2 USBID Selection (USBID pin is controlled by the USB2 module)
#pragma config FVBUSIO2 = ON // USB2 VBUSON Selection bit (VBUSON pin is controlled by the USB2 module)
#pragma config PGL1WAY = OFF // Permission Group Lock One Way Configuration bit (Allow multiple reconfigurations)
#pragma config PMDL1WAY = OFF // Peripheral Module Disable Configuration (Allow multiple reconfigurations)
#pragma config IOL1WAY = OFF // Peripheral Pin Select Configuration (Allow multiple reconfigurations)
#pragma config FUSBIDIO1 = ON // USB1 USBID Selection (USBID pin is controlled by the USB1 module)
#pragma config FVBUSIO1 = ON // USB2 VBUSON Selection bit (VBUSON pin is controlled by the USB1 module)
// DEVCFG2
#pragma config FPLLIDIV = DIV_1 // System PLL Input Divider (1x Divider)
#pragma config FPLLRNG = RANGE_BYPASS // System PLL Input Range (Bypass)
#pragma config FPLLICLK = PLL_FRC // System PLL Input Clock Selection (FRC is input to the System PLL)
#pragma config FPLLMULT = MUL_2 // System PLL Multiplier (PLL Multiply by 1)
#pragma config FPLLODIV = DIV_2 // System PLL Output Clock Divider (2x Divider)
#pragma config BORSEL = HIGH // Brown-out trip voltage (BOR trip voltage 2.1v (Non-OPAMP deviced operation))
#pragma config UPLLEN = OFF // USB PLL Enable (USB PLL Disabled)
// DEVCFG1
#pragma config FNOSC = FRC // Oscillator Selection Bits (Internal Fast RC (FRC))
#pragma config DMTINTV = WIN_0 // DMT Count Window Interval (Window/Interval value is zero)
#pragma config FSOSCEN = OFF // Secondary Oscillator Enable (Disable Secondary Oscillator)
#pragma config IESO = OFF // Internal/External Switch Over (Disabled)
#pragma config POSCMOD = OFF // Primary Oscillator Configuration (Primary osc disabled)
#pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin (Disabled)
#pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection (Clock Switch Disabled, FSCM Disabled)
#pragma config WDTPS = PS1 // Watchdog Timer Postscaler (1:1)
#pragma config WDTSPGM = STOP // Watchdog Timer Stop During Flash Programming (WDT stops during Flash programming)
#pragma config WINDIS = NORMAL // Watchdog Timer Window Mode (Watchdog Timer is in non-Window mode)
#pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Disabled)
#pragma config FWDTWINSZ = WINSZ_25 // Watchdog Timer Window Size (Window size is 25%)
#pragma config DMTCNT = DMT31 // Deadman Timer Count Selection (2^31 (2147483648))
#pragma config FDMTEN = OFF // Deadman Timer Enable (Deadman Timer is disabled)
// DEVCFG0
#pragma config DEBUG = OFF // Background Debugger Enable (Debugger is disabled)
#pragma config JTAGEN = OFF // JTAG Enable (JTAG Disabled)
#pragma config ICESEL = ICS_PGx3 // ICE/ICD Comm Channel Select (Communicate on PGEC3/PGED3)
#pragma config TRCEN = OFF // Trace Enable (Trace features in the CPU are disabled)
#pragma config BOOTISA = MIPS32 // Boot ISA Selection (Boot code and Exception code is MIPS32)
#pragma config FECCCON = ECC_DECC_DISABLE_ECCON_WRITABLE// Dynamic Flash ECC Configuration Bits (ECC and Dynamic ECC are disabled (ECCCON<1:0> bits are writable))
#pragma config FSLEEP = OFF // Flash Sleep Mode (Flash is powered down when the device is in Sleep mode)
#pragma config DBGPER = PG_ALL // Debug Mode CPU Access Permission (Allow CPU access to all permission regions)
#pragma config SMCLR = MCLR_NORM // Soft Master Clear Enable (MCLR pin generates a normal system Reset)
#pragma config SOSCGAIN = G3 // Secondary Oscillator Gain Control bits (Gain is G3)
#pragma config SOSCBOOST = ON // Secondary Oscillator Boost Kick Start Enable bit (Boost the kick start of the oscillator)
#pragma config POSCGAIN = G3 // Primary Oscillator Coarse Gain Control bits (Gain Level 3 (highest))
#pragma config POSCBOOST = ON // Primary Oscillator Boost Kick Start Enable bit (Boost the kick start of the oscillator)
#pragma config POSCFGAIN = G3 // Primary Oscillator Fine Gain Control bits (Gain is G3)
#pragma config POSCAGCDLY = AGCRNG_x_25ms// AGC Gain Search Step Settling Time Control (Settling time = 25ms x AGCRNG)
#pragma config POSCAGCRNG = ONE_X // AGC Lock Range bit (Range 1x)
#pragma config POSCAGC = Automatic // Primary Oscillator Gain Control bit (Automatic Gain Control for Oscillator)
#pragma config EJTAGBEN = NORMAL // EJTAG Boot Enable (Normal EJTAG functionality)
// DEVCP
#pragma config CP = OFF // Code Protect (Protection Disabled)
// SEQ
#pragma config TSEQ = 0x0 // Boot Flash True Sequence Number (Enter Hexadecimal value)
#pragma config CSEQ = 0xFFFF // Boot Flash Complement Sequence Number (Enter Hexadecimal value)
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include <xc.h>
#include <toolchain_specifics.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include "stdio.h"
#include <sys/attribs.h>
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#define CPU_CLOCK_FREQUENCY 8000000
#define _CP0_GET_COUNT() _mfc0 (_CP0_COUNT, _CP0_COUNT_SELECT)
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void delay_ms ( uint32_t delay_ms)
{
uint32_t startCount, endCount;
endCount=((CPU_CLOCK_FREQUENCY/1000)*delay_ms)/2;
startCount=_CP0_GET_COUNT();
while((_CP0_GET_COUNT()-startCount)<endCount);
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void Timer2_setup(void){
PB2DIVbits.ON = 0b0; //PB2CLK is disabled
PB2DIVbits.PBDIVRDY = 0b1; //Enabling the PBDIV configuration
PB2DIVbits.PBDIV = 0b0000000; //PBCLKx is SYSCLK divided by 128
PB2DIVbits.PBDIVRDY = 0b0; //Disabling the PBDIV configuration
PB2DIVbits.ON = 0b1; //PB2CLK is enabled
//----------------------------------------------------
T2CONbits.ON = 0b0; //Timer2 is disabled
T2CONbits.TCS = 0b0; //Internal peripheral clock
T2CONbits.T32 = 0b1; //Timer2 is set to 32 bits
T2CONbits.TCKPS = 0b101; //1:256 prescale value
T2CONbits.SIDL = 0b1; //Timer2 does not work in idle mode
TMR2 = 0x0; //Clear counter
PR2 = 124999U; //Timer2 period is set to 1000 milliseconds
//----------------------------------------------------
//Interrupt setup
IEC0bits.T2IE = 0b1; //Enable timer interrupt
IPC2bits.T2IP = 0b001; //Interrupt priority set to 1
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
int main ( void )
{
TRISAbits.TRISA7 = 0;
LATAbits.LATA7 = 0;
TRISBbits.TRISB14 = 0;
LATBbits.LATB14 = 0;
TRISBbits.TRISB15 = 0;
LATBbits.LATB15 = 0;
Timer2_setup();
__builtin_enable_interrupts(); // VERY IMPORTANT Built in macro function to globally enable interrupts
T2CONbits.ON = 0b1; //Timer2 is enabled
while (1)
{
LATBbits.LATB14 = 1;
delay_ms(300);
LATBbits.LATB14 = 0;
LATBbits.LATB15 = 1;
delay_ms(300);
LATBbits.LATB15 = 0;
}
return (EXIT_FAILURE);
}
//INTERRUPTS-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void __ISR( _TIMER_2_VECTOR, IPL1SRS) Timer2_Handler (void){
T2CONbits.ON = 0b0; //Timer2 is disabled
TMR2 = 0x0; //Clear counter
LATAbits.LATA7 = 1;
delay_ms(300); //Interrupt indicator
LATAbits.LATA7 = 0;
IFS0bits.T2IF = 0b0; //Clear input change interrupt
T2CONbits.ON = 0b1; //Timer2 is enabled
}
You most definitely shouldn't call delay_ms() in your interrupt handler. I'm fairly sure that this is the reason of your problem. IRQ handlers should be as quick as possible.
Check out https://www.aidanmocke.com/blog/2018/11/15/timers/. This whole blog is great for learning firmware development on PIC32.
Related
I have already spent several nights debugging gated timer on PIC18F26K80. I use MPLAB v4.15 and XC8 v2.32. I want to run a long period timer, so I chose Timer 3 gated by Timer 4. I've read Microchip's documentation and tried to find answers anywhere, but I cannot understand:
Why it doesn't set TMR3IF flag (and doesn't fire appropriate interruption) using Fosc/4 as a clock source of Timer 3 (so I use Fosc with prescale 1:4 - it works, but... why Fosc/4 doesn't?)
Why TMR3IF flag fires in TMR3 state 0x0001? It should fire from 0xFFFF to 0x0000 and with PR4 = 0x63 there is no need to step over 0x0000 so fast.
So these 2 points are the most important points, there are some other miracles, but, if you could, help me with these.
/*
* Test file for Gated timer
*/
// PIC18F26K80 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1L
#pragma config RETEN = OFF // VREG Sleep Enable bit (Ultra low-power regulator is Disabled (Controlled by REGSLP bit))
#pragma config INTOSCSEL = HIGH // LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
#pragma config SOSCSEL = DIG // SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
#pragma config XINST = OFF // Extended Instruction Set (Disabled)
// CONFIG1H
#pragma config FOSC = INTIO2 // Oscillator (Internal RC 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)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include <stdint.h>
uint8_t tmr3Lprev = 0x00u;
void interrupt ISR(void){
if(TMR3IF){
if(TMR3L == 0x00u){ //after TMR3IF fires, TMR3L should be 0 (if PR4 is > cca 0x20)
asm("BTG LATA, 2, 0"); //toggles with an output
}else{
LATAbits.LATA6 = 1; // a failure flag
}
asm("BTG LATA, 1, 0"); //toggles with an output
TMR3IF = 0;
}
if(TMR4IF){
if(TMR3L == ++tmr3Lprev){ //TMR3L should increment on every T4 rollover
asm("BTG LATA, 0, 0"); //toggles with an output
}else{
LATAbits.LATA5 = 1; // a failure flag
}
TMR4IF = 0;
}
return;
}
void main(void) {
//Clock setting (clock for system and all modules)
OSCCONbits.IRCF = 0b111;
OSCTUNEbits.PLLEN = 1; //turn on 4x Phase Lock Loop = 64MHz Clock
//sets ports to output
TRISA = 0x00; //A vse prepnout na vystup
LATA = 0x00;
//Timer4 initialization
T4CONbits.T4OUTPS = 0; //postscale, I don't know why, but doesen't effect length of T4 rollover
T4CONbits.T4CKPS1 = 1; //I dont know why, but T4CKPS = 0x11 doesnt set T4CKPS1
PR4 = 0x63; //loop periode
T4CONbits.TMR4ON = 1; //1 = Timer 4 Enabled
//Timer3 initialization
T3CONbits.TMR3CS = 0b01; //Clock source, 1 = system clock = Fosc; 0 = instruction clock = Fosc/4
T3CONbits.T3CKPS = 0b10; // 0b11 = 1:8 Prescale value; 0b10 = 1:4 Prescale value; 0b01 = 1:2 Prescale value; 0b00 = 1:1 Prescale value
T3CONbits.SOSCEN = 0;
T3CONbits.RD16 = 1; //16bits wide register
T3CONbits.TMR3ON = 1; //1 = Timer 3 Enabled
T3GCONbits.TMR3GE = 1; //Timer 3 is gated
T3GCONbits.T3GPOL = 1; //high/low level of timer4 enables Timer3
T3GCONbits.T3GTM = 0; //Toggle mode disabled
T3GCONbits.T3GSPM = 0; //Single pulse mode disabled
T3GCONbits.T3GSS = 0x01; //TMR4 as a source
WRITETIMER3(0x0000ul);
TMR4 = 0x00;
//interrupts handling
PIE2bits.TMR3IE = 1;
PIE4bits.TMR4IE = 1;
INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;
//the infinite loop
while(1){
}
}
I have spent plenty of time solving this problem (even there: https://www.microchip.com/forums/m1211315.aspx) and my conclusion is, that it is most probably a HW bug. So Timers 1 and 3 with gated control (from Timer 2/4) works properly as a timer (their registers TMR1/3H/L increment well), but they fail in triggering interrupts and setting appropriate PIR flags.
So my resolution for another applications is:
let's use Timers 1/3 as counters of TMR2/4 rollovers (and make a 24bit wide timer), it works well and is useful;
but do not use any (including CCP) ISR function (or PIR values) rising from Timer 1/3 with gated control from Timer 2/4. I simply use ISR rising from Timer 2/4 and test Timer 1/3 state by SW.
I'm using a pic12f1840 width a pickit3 and mplab x ide (and x8 c compiler). It is probably really easy, but I can't figure out how to read the value of a pin!
void main(void) {
//setting up TESA
TRISA = 0b111111;
TRISA5 = 0; //pin 5 is output
TRISA1 = 1; //pin 1 in input
for (;;) {
RA5 = RA1;
}
}
This is my code at the moment (I left out the configs and include). I have a led connected to pin 5, and a button (with a pulldown resistor) connected to pin 1. I'm running the whole thing on 3.3 volts.
When dealing with Microchip controllers like the PIC it a real good idea to post a complete code that builds. From my experience the real issue is almost always in the stuff the Original Poster left out.
This code works for me in the simulator:
/*
* File: main.c
* Author: dan1138
* Compiler: XC8 v2.20
* IDE: MPLABX v5.40
*
* Created on September 29, 2020, 1:24 PM
*/
// PIC12F1840 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = ON // PLL Enable (4x PLL enabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = ON // Low-Voltage Programming Enable (Low-voltage programming enabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
void main(void) {
//setting up TESA
TRISA = 0b111111;
ANSELA = 0; /* make all of PORTA digital I/O */
TRISAbits.TRISA5 = 0; //pin 5 is output /* use Microchip suggested syntax */
TRISAbits.TRISA1 = 1; //pin 1 in input /* use Microchip suggested syntax */
for (;;) {
LATAbits.LATA5 = PORTAbits.RA1; /* use Microchip suggested syntax */
}
}
In your case it seems to be two things:
Not knowing you need to configure GPIO pins for digital operations.
Simple syntax errors.
My example code uses the syntax that's been typically supported by almost all versions of the XC8 compilers for about 10 years now.
The shorter forms you have used may not always available for every controller you could target.
I am programming my PIC and i am trying to put it in the deep sleep mode.
I want use Deep Sleep function and the wake up event should be created by WDT interupt. But my problem is, that it is impossible to reach the interrupt. Device will continue sleeping.
#include <xc.h>
// 'C' source line config statements
// CONFIG1L
#pragma config WDTEN = ON // Watchdog Timer (Enabled)
#pragma config PLLDIV = 1 // PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
#pragma config STVREN = ON // Stack Overflow/Underflow Reset (Enabled)
#pragma config XINST = OFF // Extended Instruction Set (Enabled)
// CONFIG1H
#pragma config CPUDIV = OSC1 // CPU System Clock Postscaler (No CPU system clock divide)
#pragma config CP0 = OFF // Code Protect (Program memory is not code-protected)
// CONFIG2L
#pragma config OSC = HS // Oscillator (HS, USB-HS)
#pragma config T1DIG = ON // T1OSCEN Enforcement (Secondary Oscillator clock source may be selected)
#pragma config LPT1OSC = OFF // Low-Power Timer1 Oscillator (High-power operation)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor (Enabled)
#pragma config IESO = ON // Internal External Oscillator Switch Over Mode (Enabled)
// CONFIG2H
#pragma config WDTPS = 32768 // Watchdog Postscaler (1:32768)
// CONFIG3L
#pragma config DSWDTOSC = INTOSCREF// DSWDT Clock Select (DSWDT uses INTRC)
#pragma config RTCOSC = INTOSCREF// RTCC Clock Select (RTCC uses INTRC)
#pragma config DSBOREN = ON // Deep Sleep BOR (Enabled)
#pragma config DSWDTEN = ON // Deep Sleep Watchdog Timer (Enabled)
#pragma config DSWDTPS = 8192 // Deep Sleep Watchdog Postscaler (1:8,192 (8.5 seconds))
// CONFIG3H
#pragma config IOL1WAY = ON // IOLOCK One-Way Set Enable bit (The IOLOCK bit (PPSCON<0>) can be set once)
#pragma config MSSP7B_EN = MSK7 // MSSP address masking (7 Bit address masking mode)
// CONFIG4L
#pragma config WPFP = PAGE_63 // Write/Erase Protect Page Start/End Location (Write Protect Program Flash Page 63)
#pragma config WPEND = PAGE_WPFP// Write/Erase Protect Region Select (valid when WPDIS = 0) (Page WPFP<5:0> through Configuration Words erase/write protected)
#pragma config WPCFG = OFF // Write/Erase Protect Configuration Region (Configuration Words page not erase/write-protected)
// CONFIG4H
#pragma config WPDIS = OFF // Write Protect Disable bit (WPFP<5:0>/WPEND region ignored)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
void sleep_f()
{
//INTCON &= ~0xF8; /* Disable all interrupt sources */
//INTCON3 &= ~0x38;
PIR2bits.OSCFIF = 1;
//RCONbits.IPEN = 0;
// OSCCON = 0b01110000;
OSCCONbits.IDLEN = 0 ; // 0 Sleep mode a 1 idle mod
//WDTCONbits.SWDTEN = 1; /* Enable the regular Watch Dog Time out too */
WDTCONbits.REGSLP = 0;
//DSCONLbits.DSBOR = 1;
//DSCONHbits.RTCWDIS = 0;
DSCONHbits.DSEN = 0; // We run deep slep
Sleep();
}
void main()
{
TRISD6 = 0;
TRISDbits.TRISD4 = 0;
LATD6 = 1;
int i;
while (1){
LATD4 = 0;
int i;
for (i = 0;i < 10000; i++) asm("nop");
LATD4 = 1; // Blink led if everything is OK.
sleep_f();
DSCONLbits.RELEASE = 0;
WDTCONbits.DS = 0;
for (i = 0;i < 30000; i++) asm("nop");
}
}
Do you have any idea what is wrong with my code ?
I am stacked on it already for 3 days.
I would be grateful for any help.
I'm not sure if you realize that the DSWDT period is set to 8192 and the normal WDT to 32768, which means it takes 8.5 seconds and 2.25 minutes to trigger according to the datasheet. I'd set it to a few seconds instead for debugging. When you're sure it's working increase the WDT to the desired period.
Maybe the delay loops are too short to notice any blinking? Does the led blink without the sleep function?
This line doesn't do anything as this bit is read only.
WDTCONbits.DS = 0;
This line
DSCONHbits.DSEN = 0; // We run deep slep
Should be
DSCONHbits.DSEN = 1; // We run deep sleep
The datasheet states that 1 is deep sleep, 0 is sleep. When your device enters normal sleep, the WDT triggers in 2.25 minutes (post scaler of 32768) instead of the DSWDT 8.5 seconds (DSWDT postscaler of 8192).
I want to use microcontrollers for communicating data by SPI. So, I have chosen firstly the Microchip USB Starter Kit III module which has a PIC32MX470F512L. I tried several ways to code its SPI, but only the clock signal SCK can be seen on an oscilloscope.
Then, i tried the same code (just adjusted a few code lines to the new PIC) with the Microchip Starter Kit I which has a PIC32MX360F512L. And all run perfectly. So, i don't understand why the USB Starter Kit III doesn't work for SPI communication?
I give you the code used to test the SPI SDO & /SS.
#define _SUPPRESS_PLIB_WARNING
#include <stdio.h>
#include <stdlib.h>
#include <plib.h>
#include <p32xxxx.h>
#include <xc.h>
#include <peripheral/spi.h>
// DEVCFG2
#pragma config FPLLIDIV = DIV_2 // PLL Input Divider (12x Divider)
#pragma config FPLLMUL = MUL_20 // PLL Multiplier (24x Multiplier)
#pragma config FPLLODIV = DIV_1 // System PLL Output Clock Divider (PLL Divide by 256)
// DEVCFG1
#pragma config FNOSC = PRIPLL // Oscillator Selection Bits (Primary Osc w/PLL (XT+,HS+,EC+PLL))
#pragma config FSOSCEN = OFF // Secondary Oscillator Enable (Disabled)
#pragma config IESO = ON // Internal/External Switch Over (Enabled)
#pragma config POSCMOD = HS // Primary Oscillator Configuration (HS osc mode)
#pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin (Disabled)
#pragma config FPBDIV = DIV_1 // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/8)
#pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection (Clock Switch Disable, FSCM Disabled)
#pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler (1:1048576)
#pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))
// DEVCFG0
#pragma config DEBUG = OFF // Background Debugger Enable (Debugger is Enabled)
#pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select (Communicate on PGEC1/PGED1)
#pragma config PWP = OFF // Program Flash Write Protect (Disable)
#pragma config BWP = OFF // Boot Flash Write Protect bit (Protection Disabled)
#pragma config CP = OFF // Code Protect (Protection Disabled)
int main(void) {
TRISGbits.TRISG6=0; //SCK2
TRISGbits.TRISG7=1; //SDI2
TRISGbits.TRISG8=0; //SDO2
TRISGbits.TRISG9=0; //SS2
OpenSPI2(SPI_MODE16_ON|SPI_SMP_ON|MASTER_ENABLE_ON|SEC_PRESCAL_5_1|PRI_PRESCAL_16_1, SPI_ENABLE);
int data;
PORTGbits.RG9 = 1;
while(1)
{
PORTGbits.RG9 = 0;
putcSPI2(0xaaaa);
data=getcSPI2();
PORTGbits.RG9 = 1;
}
return 0;
}
Thanks
Pin Mapping
Do you do the pin mapping ? It does not appear on the code your posted.
You need to assign the pin to the SPI Module using the PPS (peripheral pin select).
OpenSPI is a library function, but it's also needed to do the pin mapping with the pin peripheral select (PPS)
Point 12.3.1 http://ww1.microchip.com/downloads/en/DeviceDoc/60001120F.pdf
Pin State (analog / digital)
Check your pin are not in (default) analog state. If the pin also has an analog (AN) function, the default state will be analog and you cannot control that pin. You need to set the register ANSELx (or AD1PCFG) to set the pin.
In the chip PIC32MX470F512L the pin you are using (RG6-9) also has analog function (AN):
10 AN16/C1IND/RPG6/SCK2/PMA5/RG6
11 AN17/C1INC/RPG7/PMA4/RG7
12 AN18/C2IND/RPG8/PMA3/RG8
14 AN19/C2INC/RPG9/PMA2/RG9
Page 7 http://ww1.microchip.com/downloads/en/DeviceDoc/60001185F.pdf
Analog pin Section 12.2.5 http://ww1.microchip.com/downloads/en/DeviceDoc/60001120F.pdf
Hi everyone and thanks for your replies !
Thanks to your help, i found out that issue. Pin configuration was necesary. Below the code i added for pin configuration.
// Mapping SPI1 & SPI2
SDI1Rbits.SDI1R = 0xa; // SDI1 to C4
RPD0Rbits.RPD0R = 0x8; // SDO1 to D0
RPB2Rbits.RPB2R = 0x7; // SS1 to B2
SDI2Rbits.SDI2R = 0x1; // SDI2 to G7
RPG8Rbits.RPG8R = 0x6; // SDO2 to G8
RPG9Rbits.RPG9R = 0x6; // SS2 to G9
I'm working on a project and I need to use the PIC12LF1552. The code I'm trying to run is very simple, consists on reading the input on RA5 and then setting the output on RA2 to light an LED.
The problem is that it seems that the PIC is not reading the input on RA5. If I program the PIC to blink the LED without reading any input, it works correctly.
The program used to compile is MPLAB X 2.05, and the programmer being used is Pickit3.
The code that I'm using is this:
#include <xc.h>
#include "pic12lf1552.h"
#include <stdio.h>
#include <stdlib.h>
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
#define LED PORTAbits.RA2
#define SWITCH PORTAbits.RA5
void MSDelay (unsigned int);
void main(void)
{
//Set up I/O pins
TRISAbits.TRISA2 = 0; //RA2 = LED output
TRISAbits.TRISA5 = 1; //RA5 = switch
ADCON1=0b00100;
// ADCON1 = ;
//int b;
// int i;
if(SWITCH == 0)
{
LED=1;
MSDelay(2000);
LED=0;
}
else
{
LED=0;
MSDelay(2000);
}
}
void MSDelay(unsigned int itime)
{
unsigned int i;
unsigned char j;
for(i=0; i<itime;i++);
for(j=0; j<165;j++);
}
According to the datasheet http://www.alldatasheet.com/datasheet-pdf/pdf/504825/MICROCHIP/PIC12LF1552.html, on page 93 about the ANSELA register :
"The ANSELA bits default to the Analog
mode after Reset. To use any pins as
digital general purpose or peripheral
inputs, the corresponding ANSEL bits
must be initialized to ‘0’ by user software."
If you don't plan to use analog inputs, you may add something like ANSELA=0;
for the moment, output works because : "The state of the ANSELA bits has no effect on digital
output functions. A pin with TRIS clear and ANSEL set
will still operate as a digital output,...
"
Bye,