Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] SPI glitch my PWM (pic33)

Status
Not open for further replies.

bestrider14

Member level 1
Joined
Feb 27, 2015
Messages
39
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
300
Hi

I have a dspic33FJ128MC802 and i try to put 4 PWM on it. This is not the bug but when i need to read data on my SPI, my PWM glitch. I put a led on it for make test at 100% of duty and i can see it blink very fast. How i can read my SPI whitout glitching my PWM ?

thank
 

Can you show us your code and possibly your circuit diagram/physical layout?
What is the nature of the glitch? I'm guessing from your description that the SPI on the MCU is in slave mode and when it is 'active', it is stopping the PWM operation in some way.
Susan
 

Yeah its like its stoping. But my pic are in master mode.

Code:
void InitTimer1(){
  T1CON	 = 0x8000;
  T1IE_bit	 = 1;
  T1IF_bit	 = 0;
  IPC0		 = IPC0 | 0x1000;
  PR1		 = 20000;
}

void Timer1Interrupt() iv IVT_ADDR_T1INTERRUPT{
  T1IF_bit	 = 0;
  //Enter your code here
  readBuffer();

}



void Main()
{
  Init();
  InitTimer1();

  do
  {
  Lcd_Out(1,1, "Drone-X");
  

  PWM1_MC_Set_Duty(Data_in[1]*100, 1);
  PWM1_MC_Set_Duty(0*100, 2);



  ByteToHex(Data_in[0], txt);
  Lcd_Out(2, 1, txt);

  ByteToHex(Data_in[1], txt);
  Lcd_Out(2, 4, txt);

  ByteToHex(Data_in[2], txt);
  Lcd_Out(2, 7, txt);

  ByteToHex(Data_in[3], txt);
  Lcd_Out(2, 10, txt);

  ByteToHex(Data_in[4], txt);
  Lcd_Out(2, 13, txt);


  }while (1);
}

void Init()
{
  Unlock_IOLOCK();
  RPINR20 = 0b0000000000000111;
  RPOR2 = 0b0000100000000111;
  lock_IOLOCK();

  AD1PCFGL = 0xFFFF;                           // digital not analog
  CMCON = 7;

  TRISB.B8 = 0;
  TRISB.B14 = 0;
  TRISB.B12 = 0;
  
  Lcd_Init();
  Lcd_Cmd(_LCD_CURSOR_OFF);

  SPI1_Init();
  Delay_ms(100);
  RF_init_TX();
  Delay_ms(100);
  
  PWM1_MC_Init(1000, 3, 0xff, 0);
  PWM1_MC_Set_Duty(1000, 1);
  PWM1_MC_Start();

}

char readBuffer(){
     char i, s;
     Ce_pin = 0;
     s = Get_FIFO_Flags();
     if((s & 2) != 0){
         toggleCSN();
         SPI1_Write(R_RX_PAYLOAD);
         for(i=0; i < dataLength; i++){ Data_In[i] = SPI1_Read(0);} //ITS HERE THAT seem to stop my PWM *********************************
     }
     Csn_pin = 1;
     Ce_pin = 1;
     return s;
}

i try to put i timer on my fonction. its a little better but i can always see the led blink. if i remove the SPI_READ it work but i need it :p
 

I am not sure but maybe it has to do something with Alternate Pin Configuration register ? Can PWM pins be used for SPI communication ?

Zip and post the complete mikroC PRO dsPIC project files.
 
Last edited:

here its my project

EDIT: if i plug a led directly on my PSU it blink too but again if a delete the fonction SPI_read its fine. So why a led that its not conectec on the PIC blink too
 

Attachments

  • Drone.rar
    91.1 KB · Views: 77
Last edited:

I found that there is no APFCON (Alternate Pin Function Configuration) register in your dsPIC.

TRISx settings are not correct.

Code:
sbit Irq_pin   at LATA4_bit; sfr;
is incorrect.

It should be

Code:
sbit Irq_pin   at RA4_bit; sfr;

Which is your SDI, SDO, SCK pins ? SDI pin should be set as input pin. SDO and SCK should be set as Output pins. Also set TRIS properly for LCD pins.

At libstock mikroE has nRF library.

- - - Updated - - -

Try attached project but set TRIS properly for SPI lines that is for SDO, SDI and SCK pins.
 

Attachments

  • Drone.rar
    94.3 KB · Views: 76
Last edited:

Some general comments:
1) in my experience it is rare to need to change the default priority of an interrupt. When you do set a priority, you should control all of the bits - what you are deign is to raise the priority from the default of 4 to 5 by setting the LSB of the field but that is not obvious form your code and there are no comments
2) don't play with the IOLOCK bit. The power on default settings are what you need for developing in that they let you reset the PPS registers as needed. One source of problems for beginners is that they lock the PPS registers (especially with the IOL1WAY config bit set as well) and then wonder why none of their PPS settings after that work. When everything else works, then come back to this if you really need to.
3) You need to comment the settings for the PPS registers, especially if you resource to using binary values! I *think* you have SDO mapped to RP4 (which is also RB4), SCK mapped to RP5 (RB5) and SDI mapped to RP7 (RB7).
4) A key part of using PPS mappings is to ensure that nothing else uses the pins you map on to. I can't see if you d or not but the things to check are that you do not use the secondary oscillator (for RP4), the ICSP pair PGEx3 (for debugging) for RP5 or the external interrupt INT0 (for RP7).
5) It is always good practice to set the TRIS register bits to the way you want them. There seems to be a little bit of inconsistency between devices as to whether they correctly set these bits as input or output when you enable peripherals that are PPS mapped, but setting the TRIS bits is always 'safe'.
6) There is a raging debate as to whether it is best to reset the IF flag at the start or end of an ISR. Clearing it at the start (as you have) means that, if the ISR takes longer to execute than the next trigger of the ISR, then the ISR will automatically be called again when it completes. Clearing it at the end means that this will not occur but, unless you are aware that this might occur, you can miss an interrupt. Both are reasonable options depending on your circumstances
7) your timer ISR calls a function which will lead to longer ISR execution times if only because the compiler will need to save and restore all registers. If no function is called, then the compiler only need save registers that the ISR actually uses and therefore executes much faster. Typically an ISR should be very quick and often simply sets a flag that is tested in the main loop or performs operations that are known to now block
8) and this brings me to what may be your problem: I don't know what happens in your SPI1_Read function ( I assume this is some library function) but if it blocks because, say, the peripheral is busy with a previous exchange, then the 'readBuffer' function will block the Timer1Interrupt ISR. As the ISR is running above the default priority, it will have stopped everything else while it executes. IF (and I have no idea if this is so) the library functions that are controlling the PWM have their own ISR, then it will not be allowed to operate while the readBuffer function is running and blocking.
9) I can't see the definition for 'Data_In' but it should be marked as volatile as it can be updated within an ISR.

If it were me, I would not be using library functions for simple peripherals such as SPI and PWM so that I had total control over how they are working. The next best alternative is to completely review the source code and understand what they are doing and their potential interactions.
Further I would probably not use an ISR for the timer but test the IF flag within the main loop. (Alternatively the timer ISR can set a volatile flag that is tested in the main loop.) That way the SPI exchanges will occur at the base processor priority (they generally are not time sensitive to any great extent) and let any PWM ISR that may exist run as needed.
Susan
 

Why Timer Interrupt is used to read nRF ? I think you have to use External Interrupt. When there is an external Interrupt detected coming from nRF's IRQ pin then you have to read the nRF.
 

i use it just for test but normaly its in my main loop, but like a said, a led direct on my supply rail (+ to -) blink when a do a SPI_READ
 

Just picking up on that last comment: I trust you have a resistor in series with the LED! Never connect a LED between a pin and Vss or Vdd (whichever is appropriate).
Also, I can't see if you are toggling a pin to make the LED flash, but again I hope you are not connecting the LED to a pin that also has any of the SPI signals on them.
Personally, I would step back a few paces and 1) get the SPI interface working in the main code, possibly triggered by the external interrupt; 2) get the PWM peripheral working with a fixed duty cycle in the main code; 3) put both working together in the main code. That way you are working with each part of the code in a known 'working' state and also know the last change that you made that "broke" the code so you can concentrate on that part only.
Susan
 

Yeah of course i put a resistor on it :). My spi work well i can get data from my rf perfectly and my pwm whitout spi work well. But i do some test and its when i do a spi read where all the led blink on pic or not. So now i know that not my pwm but something else
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top