Jump to content

Clashlab

EstablishedMember
  • Content Count

    6
  • Joined

  • Last visited

Posts posted by Clashlab


  1. Well, what I wanna do is control a triac for light dimming. So I need to know when the power line crosses zero.

     

    I don't need a very high accuracy, 100 µs delay will be ok.

    But I don't want the interrupt to occur at the peak value of the sine curve nor the interrupt occurring at very different times if the sine curve is going down or up.

     

    So using a transformer to get a 9v sine curve is not acceptable because (50Hz) :

    Going from 0 to 1 needs 2v (TTL) => t = arcsin( 2 / 9 )/( 2 * pi * 50 ) = 0.7 ms later

    Going from 1 to 0 needs 0.8v (TTL) => t = arcsin( 2 / 9 )/( 2 * pi * 50 ) = 0.3 ms earlier

    This leads to a 1 ms different between two interrupts, on a 50Hz signal that is 10%, it's too much.


  2. They did answer me:

    That method was really just for the PIC16C54, and actually operated the device outside of its specifications. It was possible to get away with it on older devices, and was designed into a number of earlier products (at the users risk) and worked well, which is why the appnote was created about 10 years ago. Please note that the existance of an application note does not guarantee suitability, particularly for other devices.

     

    The diodes are desgined for intermittent operation only for ESD protection. The specifications to use the device state that you can not exceed 0+Vdd and Vss-0 (given as Vdd and Vss) - see the Electrical characteristics section Vih and Vil values. The values for 0.3V past Vdd and Vss are part of the Absolute Maximum Ratings. The device is not guaranteed to operate correctly when out of spec, even if within AMR values. However, not exceeding AMR means that you should not expect permanant device damage.

     

    If you plan to connect an AC signal to the device, you will need to limit it externally, such as with an external zener or other similar option. The an521 is old and requires revision. There should be a note stating that this is at the users own risk and violates the letter of the specification. It should also state that it was only used on older devices (PIC16C54 for example) where no ill effects were observed at the time. However, newer devices are prone to more problems when implementing this.

     

    Further, the ESD diodes may not fail immediately when using this note, but become weaker and weaker over time. This means that ill effects could be observed immediately, or possibly after considerable time. If you consider implemeting this, it would be best to just meet the input current specification (+/- 1uA) - say 5 uA or so. The less current conducted by the diodes the better. However, if you desire your design to be within specification, you should use external clamping to prevent from exceeding Vdd and Vss.

     

    While I have noted the best conditions here to make this work, please note this can not be interpreted as a guarantee or recommendation from myself or Microchip.

    So I will not use that method. Instead I will connect the power line thru a resistor to a NOT gate (which allows exceeding the voltage specifications as long as the current specification is meet, i.e. SN74AHC1G04) and connect that output to the pic (also thru a resistor).


  3. Hi,

     

    The way I connected the led to the pic is very simple:

    PIC (5v) ---- Resistor (470 Ohm) ---- Led ---- 0v

     

    I tried several other value for the resistor, form 47 Ohm to 2.7 kOhm but that doesn't change anything.

     

    I think your right about the origin of my problem, it explain the two situation I encountered.

    I also found that RA4 on a 16f88 is a schmitt trigger, but using RA3 (TTL) doesn't help.

     

    So how can I make sure that when I put a 1 on the led output I read a 1 after?


  4. Hello,

     

    In am experiencing a wired problem trying to make a led blink.

     

    I what to use a timer (TMR0) to know when I need to change the led state. So I have a function that turns on the led and sets the timer.

    Then every 20 timer overflow I test the led state and change it. This is where I have a problem.

    When I am directly testing the led state, the led never blinks (it is like reading the led state always returns 0) so I need to use a variable to keep track of the led state.

     

    I really don't understand the problem and need your help to figure this out.

     

    Here are the files (led.h, led.c, main.c) I am using BoostC 6.84 lite license on a 16f88. You only need to provide power to the pic and tie a led (+ resistor) to porta bit4.

    I included a #define PROBLEM1:

    • If you declare PROBLEM1, the led never blinks (which is wired).
    • If it is not declared the led blinks (using a state variable).

    Trying to figure out what was wrong I found another problem :

    When using a variable to keep track of the led state (PROBLEM1 not defined) if I set another led (LED_RED, porta bit3) to 1 at each timer overflow it get wired again.

    I included a #define PROBLEM2:

    • If you declare PROBLEM2, the LED_BLUE blinks but stays on for a short period of time and surprisingly LED_RED goes off for a very short time repetitively.
    • If it is not declared the led blinks (well if PROBLEM1 is not defined :)).

    I have included an archive containing the 3 source files and 3 hex files:

    • led.hex: PROBLEM1 and PROBLEM2 NOT defined ==> LED_BLUE blinks
    • ledProblem1.hex: only PROBLEM1 defined ==> LED_BLUE doesn't blink
    • ledProblem2.hex: only PROBLEM2 defined ==> LED_BLUE stays on furtively LED_RED goes off furtively

    What have I done wrong?

    Thanks for your help.

     

    led.h

    #ifndef LED_H
    #define LED_H
    
    #define LED_BLUE  porta.4
    #define LED_RED  porta.3
    
    #define ON	 1
    #define OFF	0
    
    #define TMR0_PRESCALER  6
    #define LED_PRELOAD  100
    
    /*
    CLOCK_FREQ = 8 MHz
    TMR0: Prescaler 1/128, preload: 100 => IT every 0.00998400 sec
    */
    void  ledInit  ( void);
    void  ledBlink ( unsigned char onDuration);
    void  IT_led   ( void);
    
    #endif /* LED_H */

     

    led.c

    #include <system.h>
    
    #include "led.h"
    
    #define PROBLEM1
    /*#define PROBLEM2*/
    
    static unsigned char ledTimer = 0;
    static unsigned char blink = 0;
    #ifndef PROBLEM1
    static bit ledState = 0;
    #endif
    
    void ledInit( void)
    {
      option_reg &= 0xC0;	 /* 0b11000000 We keep the 2 MBS unchanged */
      option_reg |= TMR0_PRESCALER;
    }
    
    void ledBlink( unsigned char duration)
    {
      /* Save duration for use in IT_led */
    blink = duration;
    /* Set the number of timer overflow */
    ledTimer = blink;
    
    LED_BLUE = ON;
    #ifndef PROBLEM1
      ledState = ON;
    #endif
    
    /* Load timer */
    tmr0 = LED_PRELOAD;
    
    /* Allow timer IT*/
      intcon.TMR0IF = 0;
      intcon.TMR0IE = 1;
    }
    
    void IT_led( void)
    {
    #ifdef PROBLEM2
      LED_RED = ON;
    #endif
    
      /* If duration has elapsed */
    if ( --ledTimer == 0 )
    {
    
      /* Change led state */
    #ifdef PROBLEM1
      /* DOESN'T WORK : LED_BLUE STAYS ON */
      if ( LED_BLUE == ON )
    	{
    	 LED_BLUE = OFF;
    	}
    	else
    	{
    	 LED_BLUE = ON;
    	}
    #else
      /* WORKS : LED_BLUE blink when using another variable to test the led state */
      if ( ledState == ON )
      {
    	 LED_BLUE = OFF;
    	 ledState = OFF;
      }
      else
      {
    	 LED_BLUE = ON;
    	 ledState = ON;
      }
    #endif
      /* Set the number of timer overflow */
      ledTimer = blink;
    }
      /* Load timer */
    tmr0 = LED_PRELOAD;
    }

     

    main.c

    #include <system.h>
    
    #include "led.h"
    
    #pragma DATA _CONFIG1, _WDT_OFF & _PWRTE_OFF & _INTRC_IO & _MCLR_OFF & _BODEN_OFF & _LVP_OFF & _CPD_OFF & _WRT_PROTECT_OFF & _DEBUG_OFF & _CCP1_RB0 & _CP_OFF;
    #pragma DATA _CONFIG2, _FCMEN_ON & _IESO_ON;
    
    
    static void init( void)
    {
      porta = 0;
      portb = 0;
      trisa = 0b00100100;
      trisb = 0b11000001;
    
      osccon = 0x72;
    }
    
    
    void interrupt(void)
    {
      if (intcon.TMR0IE == 1 && intcon.TMR0IF == 1)
      {
      IT_led();
    
      intcon.TMR0IF = 0;
      }
    }
    
    
    void main( void)
    {
      /* General initialisation */
      init();
    
      /* Module initialisation */
      ledInit();
    
      intcon.GIE = 1;
    
      ledBlink( 20);
    
      for (;;);
    }

    BlinkLed.zip

×
×
  • Create New...