Announcement

Collapse
No announcement yet.

Proton Mag Info

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    Below is the code for the 90S2313 micro. I compiled it in Codevision and had no errors. There are two warnings that will come up "unreferenced variable count_h" and "unreferenced variable T0_count". You will also have to increase the Data Stack size.

    The included files near the start are part of Codevision. If you use another compiler you will have to use the corresponding files for that compiler.

    Have fun and I hope you get something working from it.

    Rick

    This program was produced by the
    CodeWizardAVR V1.24.3b Evaluation
    Automatic Program Generator
    © Copyright 1998-2004 Pavel Haiduc, HP InfoTech s.r.l.
    http://www.hpinfotech.com
    e-mail:office@hpinfotech.com

    Project :
    Version :
    Date : 8/15/2004
    Author : Freeware, for evaluation and non-commercial use only
    Company :
    Comments:


    Chip type : AT90S2313
    Clock frequency : 10.000000 MHz
    Memory model : Tiny
    External SRAM size : 0
    Data Stack size : 32
    ************************************************** ***/

    #include <90s2313.h>

    // Alphanumeric LCD Module functions
    #asm
    .equ __lcd_port=0x18
    #endasm
    // included files are all in Codevision
    #include <lcd.h>
    #include <90s2313.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <delay.h>
    //
    #define enable_i #asm("sei") // global enable interrupts
    #define disable_i #asm("cli") // global disable interrupts
    //
    // now a bunch of port definitions
    //
    #define relay_ON PORTD.2 = 1
    #define relay_OFF PORTD.2 = 0
    #define polarize_ON PORTD.3 = 1
    #define polarize_OFF PORTD.3 = 0
    #define squelch_ON PORTD.6 = 1
    #define squelch_OFF PORTD.6 = 0
    //
    // Declare your global variables here
    //
    flash float alpha = 2.4051189e11; // value for 1024 proton cylces and

    a 10 MHz clock
    long value;
    flash char SignOnLogo[]="RICK'S MAG";
    #pragma regalloc-
    //
    unsigned char counth, error, T0_count;
    //
    // the following global variables are used in the UART receive

    interrupt routine
    //

    //
    // prototype declarations
    //
    void polarize(void);
    void WriteResult(void);
    void measure(void);
    void report(void);

    //


    void main(void)
    {
    // Declare your local variables here

    // Input/Output Ports initialization
    // Port B initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In

    Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T

    State0=T
    PORTB=0x00;
    DDRB=0x00;

    // Port D initialization
    // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTD=0x00;
    DDRD=DDRD|00x4c;

    // Timer/Counter 0 initialization
    // Clock source: T0 pin Falling Edge
    TCCR0=0x06;
    TCNT0=0x00;

    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: 10000.000 kHz
    // Mode: Normal top=FFFFh
    // OC1 output: Discon.
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    TCCR1A=0x00;
    TCCR1B=0x01;
    TCNT1H=0x00;
    TCNT1L=0x00;
    OCR1H=0x00;
    OCR1L=0x00;

    // External Interrupt(s) initialization
    // INT0: Off
    // INT1: Off
    GIMSK=0x00;
    MCUCR=0x00;

    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x82;

    // UART initialization
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // UART Receiver: On
    // UART Transmitter: On
    // UART Baud rate: 9600
    UCR=0x18;
    UBRR=0x40;

    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    ACSR=0x80;


    // LCD module initialization
    lcd_init(16);

    // Global enable interrupts
    #asm("sei")
    //
    lcd_init(16);
    lcd_gotoxy(0,0);
    lcd_putsf(SignOnLogo);
    //
    polarize();
    //
    measure();
    //
    report();
    //
    WriteResult();
    //
    }
    //
    void polarize(void)
    {
    //
    // the routine which turns the HEXFET's and relay on and off
    //

    squelch_ON;
    delay_ms(3); // wait three mS
    relay_ON;
    delay_ms(20); // wait 20 mS
    polarize_ON;
    delay_ms(5000); //polarization time
    polarize_OFF;
    delay_ms(10);
    relay_OFF;
    delay_ms(70);
    squelch_OFF;
    delay_ms(15);

    }

    void measure(void){
    /*

    This is all done in assembler. Basically, the program looks at

    the T0 input
    and waits for a trailing edge. Just to be on the safe side, it first

    looks for a trailing edge,
    then a leading edge and finally, another trailing edge. The T0 timer

    is set up to read this
    signal as an input and to toggle on a trailing edge.The T0 interrupt

    routine is set to be activated on
    T0 overflow. It is zeroed to start with and the number of overflows is

    counted with T0_COUNT.
    After 1024 cycles of the signal (four T0 overflows) T1 is turned off in

    this routine.

    While this is happening,the T1 timer is running at the clock
    rate of 10.0 MHz. On each overflow of T1, it's interrupt routine

    increments the variable,
    COUNTH. When T0 overflows, the T1 timer is stopped. At this time, the

    total number
    of clock cycles will be a three byte number with COUNTH as the most

    significant byte
    with T1H, the next most and T1L the least significant byte.

    */
    #asm
    .equ pd = 0x10 ; PIND
    .equ t0 = 0x32 ; TCNT0
    .equ t1h = 0x2d ; TCNT1H
    .equ t1l = 0x2c ; TCNT1L
    .equ t0cntl = 0x33 ; TCCR0
    .equ t1cntl = 0x2e ; TCCR1B
    .equ tmsk = 0x39 ; TIMSK

    push r31
    cli ; disable interrupts
    clt ; clear T flag
    ldi r31,0
    out t0cntl,r31 ; stop T0 tcnto
    out t1cntl,r31 ; stop T1 tccr1b
    out t0,r31 ; reset counter 0 to 0 tcnto
    out t1h,r31 ; reset counter 1 HIGH to 0 tcnt1h
    out t1l,r31 ; reset counter 1 LOW to 0 tcnt1l
    sts _counth,r31 ; set COUNTH to 0
    sts _error,r31 ; set ERROR to 0
    sts _T0_count,r31 ; set T0_count to 0 also
    ldi r31,0x82
    out tmsk,r31 ; enable T0 and T1 overflow interrupts

    loop1:
    sbic pd,4 ; skip if input is low
    rjmp loop1 ; otherwise, go back
    ;
    ; it only gets here if the input is low
    ;
    loop2:
    sbis pd,4 ; skip if the input is high
    rjmp loop2
    ;
    ; it only gets here if the input is high
    ;
    loop3:
    sbic pd,4 ; skip if the input is low
    rjmp loop3

    ; finally, the input has just gone low when it gets here
    ; and we''re ready to count trailing edges
    ;
    ldi r31,0x06 ; set T0 to count on external input,

    trailing edge
    out t0cntl,r31
    ldi r31,1 ; set T1 to count at the clock rate
    out t1cntl,r31
    sei ; and ENABLE interrupts to let ''er

    rip!
    ;
    ; when it is done, the T0_COUNT will be 4
    ;
    waitloop:
    lds r31,_T0_count
    cpi r31,4 ; is it four overflows?
    breq is_done
    lds r31, _counth
    subi r31,90 ; subtract 90 from counth
    brpl is_error ; if result is negative, it is OK
    rjmp waitloop ; otherwise, it is an error
    is_error:
    ldi r31,1
    sts _error,r31
    is_done:
    ldi r31,0
    out t1cntl,r31 ; stop T1
    out t0cntl,r31 ; and T0
    pop r31
    #endasm
    }
    //
    void report(void){
    //

    #asm
    push r23
    ldi r23,0
    sts _value+3,r23
    lds r23,_counth
    sts _value+2,r23
    in r23,0x2c ; TCNT1L
    sts _value,r23
    in r23,0x2d ; TCNT1H
    sts _value+1,r23
    pop r23
    #endasm

    value = (long) (alpha / value);

    if (error) value = 999999L; //returns 99999 on lcd

    }



    void WriteResult(void)
    {
    //
    char str[16];
    lcd_gotoxy(0,1);
    ltoa(value,str);
    lcd_puts(str);
    }
    //Below are the timer interrupt routines.

    #pragma savereg-
    interrupt [TIM1_OVF] void timer1_overflow(void) {

    #asm
    push r30
    in r30,SREG
    push r30
    lds r30,_counth
    inc r30
    sts _counth,r30
    pop r30
    out SREG,r30
    pop r30
    #endasm
    }

    interrupt [TIM0_OVF] void timer0_overflow(void)
    {

    // TCCR1B = 0; // stop T1
    // #asm("set") // set T flag

    #asm
    push r30
    in r30,SREG
    push r30
    lds r30, _T0_count
    inc r30
    sts _T0_count,r30
    cpi r30,4
    brne isnt_finished
    ;
    ; if here, it is finished counting so I should clear TCCR1B
    ;
    clr r30 ; set TCCR1B to 0
    out 0x2e,r30
    isnt_finished:
    pop r30
    out SREG,r30
    pop r30
    #endasm


    }

    #pragma savereg+

    Comment


    • #17
      Listing

      Hello Rick.

      Thanks for the file you send, I study it and hope to understand something ,
      You used the schematics from Koehler for this listing ?

      There is also some more info on http://www.exstrom.com/magnum.html

      Best regards.

      Ap

      Comment


      • #18
        Yes, I used Jim's schematics but with some modifications. They are all pretty obvious. The LCD is connected directly to the 90S2313. The pushbutton is also connected directly to the micro. The relay, polarize and squelch again are connected to the PORT.D pins as described in the code. I also connected a reset supervisor to the micro. I used it to take the readings. I believe I wired a pushbutton to the Vcc supply to the reset supervisor. As soon as the normally closed pushbutton is depressed, low Vcc is detected and the micro is reset which triggers it to take another reading. The first one I built did not have that feature. I just put a pushbutton directly on the Vcc to the 90S2313. You could also experiment a bit and use a spare pin on the micro and wire a pushbutton on it. You would have to add some lines of code. For the Mega162 I did that.

        I also see one line in the code I posted that should have two slashes in front of it:

        // the following global variables are used in the UART receive

        interrupt routine

        interrupt routine should have // in front of it. The two slashes in C programming tell the compiler that these are only comments and not part of the actual code. Similarily in the assembly parts of the code you will see a semicolon in front of a line. That also tells the compiler to ignore that line.

        I hope you have success. I started on this a few years ago and got hooked. Now in the cold winter months I play with it. Too busy in the summer with golf and hopefully some prospecting.

        Rick

        Comment


        • #19
          You should probably delete that line "interrupt routine". It looks like when I was cleaning up the code before posting it I did not delete all of one unused section.

          Rick

          Comment


          • #20
            I have built a polarization circuit using only one mosfet based on the one in the original posting. I have written a new piece of code to activate the circuit. I don't know if anyone is interested but here it is:

            Add the define

            #define measure2 (PIND.6==0)

            Change

            polarize_ON=PORTD.3=0
            polarize_off=PORTD.3=1

            Change PORTD to:

            PORTD= 0x48
            DDRD= 0x08

            remove the statement

            #asm("sei")

            Add

            While(1)

            if measure2

            measure();

            Use the code as posted from here.

            The connection as shown on the schematic PB0 to Pin2 on the optocoupler will be made to PD6 (pin 11 on the '2313) instead. I am using PortB for the lcd so the pin on the schematic is already in use.

            Rick

            Comment


            • #21
              I forgot to mention that I built this on a breadboard just as a test. To add in the other 7 mosfets will be simple.

              A couple of 'fets will have to used to isolate the coil from the amp during polarization as well. I plan to use the squelch to control them. I have not done this yet.

              Rick

              Comment


              • #22
                Rick wrote:
                I have built a polarization circuit using only one mosfet based on the one in the original posting. I have written a new piece of code to activate the circuit. I don't know if anyone is interested but here it is

                Hello Rick.

                Thanks for the info. I like the polarizarion circuit form Extrom (look at the internet site) Aslo the idee from two separate coils ... this way we can use a heavy polarization coil and a pick up coil that has more windings.


                Regards.

                Ap

                Comment

                Working...