This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

multiplier IC

i have analoge volts on the pins.

How can you achieve z=x*y with 8051? 2V*(-3V)=-6V for example

  • WHICH '8051'
    WHICH language (C, Pascal, assembler)
    WHICH a/d (internal/external)
    WHICH supply volatages do you have
    WHICH precision do you need
    WHICH resolution do you need
    WHICH fluency do you have in programming
    WHICH experience do you have in analog design

    Erik

  • Erik, you know those questions are futile. You are avoiding doing the work to provide the correct response. Let me go ahead and answer the question for you...

    Question: How can you achieve z=x*y with 8051? 2V*(-3V)=-6V
    for example

    Answer: (well, a partial answer at least) ...

    
    /*                          Keil_Forum_Example.C
    *****************************************************************************
    *
    *   Module Header information and list of code-monkeys to blame the errant
    *   history revisions on, along with the general disclaimers of liability
    *   and other information about how the source code is completely
    *   disconnected what the customer wants, what the specifications state,
    *   and the requirements spelled out within the contract.
    *
    *   --Cpt. Vince
    *
    *   ----------------------------------------------------------------------
    *   WARNING - This document contains technical data whose export is
    *   restricted by the Arms Export Control Act (Title 22, U.S.C., Sec 2751
    *   et seq.) or  the Export Administration Act of 1979, as amended, Title
    *   50 U.S.C., App 2401 et seq. Violation of these export laws are subject
    *   to severe criminal penalties. Dissemination only in accordance with
    *   provisions of DOD Directive 5230.25 (Reference C).
    *   ----------------------------------------------------------------------
    *
    */
    #include <everything.h>
    
    
    ////////////////////////////////////////////////////////////////////////////
    //                                                                        //
    //                      Module #defines                                   //
    //                                                                        //
    ////////////////////////////////////////////////////////////////////////////
    #define ADC_RESOLUTION      (2^12)      // My 12-bit ADC resolution
    #define ADC_GND_REF         (0)         // ...which is reference from here
    
    #define MAX_ADC             (ADC_RESOLUTION-5)  // five bits below Vref
    #define MIN_ADC             (ADC_GND_REF+5)     // five bits above GND
    
    #define MID_ADC_RANGE       ((u16)( ((MAX_ADC-MIN_ADC)/2) + MIN_ADC )
    
    #define ADC_LEADING_MASK    (0x0FFF)      // 0000.1111:1111.1111
    
    #define SAFE_ADC_VALUE      MID_ADC_RANGE // Determined to be 'safest' value
    
    #define TO_5mS              5 // (1mS per timer isr tick) ADC EOC spec'd at
                                  // less than 3mS.
                                  //
                                  // And don't get your panties in a bunch over
                                  // "mS" and "msec" as we all know, from the
                                  // context that it means milliseconds.
    
    #define FOREVER     0x1234    // '1' has only 1 non-zero bit. I like more.
    
    #define CHANNEL_A   0xAA    // define as required.
    #define CHANNEL_B   0xBB
    
    #define CHANNEL_0   0x00
    #define CHANNEL_1   0x10
    #define CHANNEL_2   0x20
    #define CHANNEL_3   0x30
    
    ////////////////////////////////////////////////////////////////////////////
    //                                                                        //
    //                   Module external references                           //
    //                                                                        //
    ////////////////////////////////////////////////////////////////////////////
    extern bit Check_End_Of_Convert( void );
    
    extern u16 Read_ADC( u8  );
    extern s16 Scale_ADC( u16 );
    
    extern void Start_ADC( u8 );
    
    extern void Start_Timer( u8 * );
    extern void Release_Timer( u8 * );
    
    extern void Log_Error( u8 );
    
    extern void Init_Port_IO( void );
    extern void Init_Debug( void );
    
    extern void Init_Time_Base( void );
    extern void Enable_Time_Base( void );
    
    extern void Enable_All_Interrupts( void );
    extern void Disable_Interrupts( void );
    
    

  • 
    /*
    **======================================================================
    **      Get_ADC_Value
    **======================================================================
    **
    **  Return the raw ADC value of the selected ADC channel.
    **
    **  This shall start the conversion, wait for it, and then return
    **  the value.  Since our ADC is 12-bits, we shall mask off the
    **  upper nibble here.
    **
    **----------------------------------------------------------------------
    **
    **  Parameters Passed:      u8 channel
    **  Parameters Returned:    u16 raw adc value
    **  Notes:
    **          If the ADC's EOC fails to assert, then this routine
    **          shall return a 'safe' value and flag the ADC as being
    **          problematic.
    **
    **----------------------------------------------------------------------
    */
    u16 Get_ADC_Value( u8 channel )
    {
        static  u8  time_out_timer; // an atomically accessed data-store
    
        u16         adc;    // ADC is 12 bits, so use a 16-bit storage
    
        bit         eoc;    // the End of Conversion signal
    
        /*------------------------------------------------------------------.
        ;  Start the selected ADC conversion process                        ;
        '------------------------------------------------------------------*/
        Start_ADC( channel );
    
        /*------------------------------------------------------------------.
        ;  Assign a time out period for protection against an infinate loop ;
        '------------------------------------------------------------------*/
        time_out_timer = TO_5mS;
    
        /*------------------------------------------------------------------.
        ;  Start timing the time-out timer (crude, but works)               ;
        '------------------------------------------------------------------*/
        Start_Timer( &time_out_timer );
    
        /*------------------------------------------------------------------.
        ;  Wait for the ADC to complete the conversion.                     ;
        '------------------------------------------------------------------*/
        while( time_out_timer > 0 )
        {
            eoc = Check_End_Of_Convert( );  // ADC reports status, get it
    
            /*--------------------------------------------------------------.
            ;   "Are we there yet?"  If so, then exit the while loop        ;
            '--------------------------------------------------------------*/
            if( eoc != FALSE )
            {
                time_out_timer = 0; // forces while to exit
                timed_out = FALSE;  // declare that we didn't run out of time
            }
            else
            {
                timed_out = TRUE;   // we ran out of time... note it
            }
        }
    
        /*------------------------------------------------------------------.
        ; Keep the time-out timer from stomping on 'retired' data-stores    ;
        ; (Although this has been declared 'static' the out-of-scope data   ;
        ;  needs to be released from the potential of an isr writting to    ;
        ;  the address, and hence, killing some random data-store)          ;
        '------------------------------------------------------------------*/
        Release_Timer( &time_out_timer );
    
        /*------------------------------------------------------------------.
        ;  If we timed out, then the EOC was abnormal.  Return as 'safe'    ;
        ; analog value, and set the corrisponding error flag.               ;
        '------------------------------------------------------------------*/
        if( timed_out != FALSE )
        {
            adc = SAFE_ADC_VALUE;        // Use a 'safe' value
    
            Log_Error( ADC_EOC_ERROR ); // make note of the error
    
            // adc &= ADC_LEADING_MASK; // Could encode an error nibble here
            // adc |= ADC_ERROR_CODE;   // but chose not to due to the
        }                               // possibilitiy of a 16-bit ADC
        else
        {
            adc  = Read_ADC( channel ); // Read it
    
            adc &= ADC_LEADING_MASK;    // clean it up
        }
    
        /*------------------------------------------------------------------.
        ;  The value has been prepared. Return it.                          ;
        '------------------------------------------------------------------*/
        return( adc );
    }
    
    

  • 
    /*
    **======================================================================
    **      main
    **======================================================================
    **
    **  This answers the question "How can you achieve z=x*y with 8051?"
    **  found in the origional contract.
    **
    **  Contract: http://www.keil.com/forum/docs/thread12890.asp
    **
    **  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    **
    **  This shall "infinately" read in two analog voltage values, then
    **  multiply them together, and with that result control a heat-lamp
    **  to keep the french-fries from becoming solid blocks of Crisco.
    **
    **----------------------------------------------------------------------
    **
    **  Parameters Passed:      <none>
    **  Parameters Returned:    <none>
    **  Notes:
    **          This requires a time-base isr, and other 'implied' functions
    **
    **----------------------------------------------------------------------
    */
    void main( void )
    {
        /*------------------------------------------------------------------.
        ;
        '------------------------------------------------------------------*/
        u16     raw_x;      // get the un-scaled ADC values
        u16     raw_y;
    
        s16     x;          // for the scaled values
        s16     y;
    
        s32     result_z;   // our result ... (2^12)x(2^12) = 16,777,216 < 2^32
    
        /*------------------------------------------------------------------.
        ;  Power-up                                                         ;
        '------------------------------------------------------------------*/
        Disable_Interrupts( );  // just in case
        Init_Port_IO( );        // 'safest' port levels
        Init_Debug( );          // initialize the error/debug stuff
    
        /*------------------------------------------------------------------.
        ;  Initialize the time-base                                         ;
        '------------------------------------------------------------------*/
        Init_Time_Base( );      // configure it
        Enable_Time_Base( );    // enable it
    
        /*------------------------------------------------------------------.
        ;  Clear any 'pending' interrupts and then enable the master.       ;
        '------------------------------------------------------------------*/
        Enable_All_Interrupts( );
    
        /*------------------------------------------------------------------.
        ;  Simple forever loop which reads, multiplies, and outputs         ;
        '------------------------------------------------------------------*/
        while( FOREVER )
        {
            /*--------------------------------------------------------------.
            ;  Read in the ADC values                                       ;
            '--------------------------------------------------------------*/
            raw_x = Get_ADC_Value( CHANNEL_0 );
            raw_y = Get_ADC_Value( CHANNEL_1 );
    
            /*--------------------------------------------------------------.
            ;  Scale the values per the system requirements                 ;
            '--------------------------------------------------------------*/
            x = Scale_ADC( raw_x );
            y = Scale_ADC( raw_y );
    
            /*--------------------------------------------------------------.
            ;  Multiply the two readings, and feed that into our output...  ;
            '--------------------------------------------------------------*/
            result_z = x * y;                   // the complex math
    
            /*--------------------------------------------------------------.
            ; The output is a signed 32-bit PWM channel operating with a    ;
            ; base frequency of 50kHz, and this is used to control the      ;
            ; french-fry heat lamps, and simultaneously killing the flies   ;
            ; buzzing about with the intense Infra-Red lamps.  Those little ;
            ; black dots in your fry container are not 'zesty' spices.      ;
            '--------------------------------------------------------------*/
            Update_PWM_Out( CHANNEL_A, result_z );
        }
    
    }
    
    
    
    /*===========================================================================
    *       END OF MODULE ( Keil_Forum_Example.C )
    ===========================================================================*/
    
    

    I did not include all of the functions, but you can figure it out from there.

    Also I have not compiled this code because it will only show a bunch of errors and complain how it should not work. I hate that. So I never actually compile or link programs. This way I also avoid that debugging thing too. It takes too much time anyway.

    --Cpt. Vince Foster
    2nd Cannon Place
    Fort Marcy Park, VA

  • now I am sure he will get an a on his test

    uh... thanks erik.

    After posting it, I quickly spotted an error. (not that there is only one).

    It turns out that I didn't allocate 'timed_out' and then I didn't initialize it prior to the while( time_out_timer > 0 ) loop. So if time_out_timer was 0, then timed_out is un-assigned, thus the if( timed_out != FALSE ) test becomes an invalid test. The system fails, millions are lost, and as a result of the failure, a Mr. Boro Berak (this OP) is hired to replace me while the crayon on his diploma is still drying.

    Mr. Berak will quickly hire erik malund and he shall ask some fairly simple questions...

    which '8051'
    which language (C, Pascal, assembler)
    which a/d (internal/external)
    what supply voltages do you have
    what precision do you need
    what resolution do you need
    what fluency do you have in programming
    what experience do you have in analog design

    --Cpt. Vince Foster
    2nd Cannon Place
    Fort Marcy Park, VA

  • Maybe not: that's a pretty distinctive style, and any decent teacher would instantly spot whether or not it is typical of the student's own work...