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

Interrupt Sample code for C167CS

Hi all,

I am learning microprocessor programming.
I need some sample code for interrupt routine for C167CS.
It should be as simple as e.g. every second print time on display.

Thanks for help
regards
/M

  • I hope there is no mistakes here:

    #include <reg167.h>  // definitions of SFRs
    #include <intrins.h> // declarations of intrinsic routines like _bfld_()
    
    unsigned long seconds = 0;
    
    void OnTimer0(void) interrupt 0x20 using TIMER0_RB
    {
      static char buffer[32];
      seconds++;
      sprintf(buffer, "Seconds running: #lu", seconds);
      MyWriteToDisplayRoutine(buffer); // this function should display strings
        // write it yourself
    }
    
    void main(void)
    {
      T0REL = 0xA0A2;                 // configure Timer0 to trigger
      _bfld_(T01CON, 0x00FF, 0x0047); // interrupt every second at 25MHz CPU clock
      T0IC = 0x0044; // the Timer0 iterrupt will have level 1, group level 0
      IEN = 1; // enable interrupts
      for (;;) _idle_(); // IDLE in the endless loop to save some power :-)
    }
    

  • Hi Mike,

    Thanks a lot for your help.
    I will try to run the code soon and may come back if something is not clear.

    thanks again for your help.

    regards
    /M

  • Hi Mike again,

    I just looked at the code and wonder the followings:


    _bfld_(T01CON, 0x00FF, 0x0047); // interrupt every second at 25MHz CPU clock


    what does the "_bfld_" function do;

    can I replace the code

    for (;;) _idle_();


    with while(1){};
    i.e. I don't use _idle_(); functions

    regards
    /M

  • what does the "_bfld_" function do

    Take a look in the manuals to find out about blfd and idle.

    Jon

  • I agree with Jon totally.
    The manuals you need are:
    C166 library functions reference, C166 Instruction Set Manual ( _bfld_(), _idle_() )
    C167 Microcontroller Manual ( registers T0REL, T01CON etc.)

  • Hi all,

    Thanks, I have found the answers to my questions in the corresponding manuals.

    regards
    /M

  • Hi all again,

    I run the following code on my board and it works.

    #include <reg167.h> // definitions of SFRs
    #include <intrins.h> // declarations of intrinsic routines like _bfld_()

    unsigned long seconds = 0;

    void OnTimer0(void) interrupt 0x20 using TIMER0_RB
    {
    static char buffer[32];
    seconds++;
    sprintf(buffer, "Seconds running: #lu", seconds);
    printf("Buffer %s", buffer);
    }

    void main(void)
    {
    T0REL = 0xA0A2; // configure Timer0 to trigger
    _bfld_(T01CON, 0x00FF, 0x0047); // interrupt every second at 25MHz CPU clock
    T0IC = 0x0044; // the Timer0 iterrupt will have level 1, group level 0
    IEN = 1; // enable interrupts
    for (;;) _idle_(); // IDLE in the endless loop to save some power :-)
    }



    Then I tried to run it using uVision2. Compilation and linking goes fine without any error or warning.
    But I don't get any text in serial window #1.
    Am I missing something?
    regards
    /M

  • I don't see any code to initialize ASC0.

    Jon

  • hi Jon,

    Thanks for reply.

    I don't see any code to initialize ASC0.

    OK!
    But I didn't need such a initialization of ASCO when I run the code on real target. It worked as expected i.e. every second interrupt was executed and

    sprintf(buffer, "Seconds Val: %lu", seconds);
    appeared on the display.
    Now why I need such initialization in the case of simulator uVision.
    Is it something we need when using simulator's serial interface?

    Further I have one more question regarding setting time for a timer.


    T01CON = 0x0047; // interrupt every second at 25MHz CPU clock
    Here time is set one second and works fine but what if I want to set the time other than one sec like one min or one hour.
    I know that it is T01CON register where this
    information is given but how.
    I tried to understand TxI with the help of Timer/counter x Input selection table but couldn't understand well.
    Can someone give me some more example to explain it.
    I will realy appreciate this affort.

    thanks all
    regards
    /M

  • But I didn't need such a initialization of ASCO when I run the code on real target.

    Well. ASC0 is NOT initialized to work when the C16x resets, so something initialized it. Are you using MON166 or another target monitor to download and run your code? If so, the monitor already initialized the serial port.

    Jon

  • There is an example called hello in the \keil\c166\examples\hello folder. This example appears as follows:

    #include <stdio.h>                /* standard I/O .h-file              */
    #include <reg167.h>               /* special function register 80C167  */
    
    /****************/
    /* main program */
    /****************/
    void main (void)  {               /* execution starts here               */
                                      /* initialize the serial interface     */
    #ifndef MCB167          /* do not initialize if you use Monitor-166      */  
      P3  |= 0x0400;        /* SET PORT 3.10 OUTPUT LATCH (TXD)              */
      DP3 |= 0x0400;        /* SET PORT 3.10 DIRECTION CONTROL (TXD OUTPUT)  */
      DP3 &= 0xF7FF;        /* RESET PORT 3.11 DIRECTION CONTROL (RXD INPUT) */
      S0TIC = 0x80;         /* SET TRANSMIT INTERRUPT FLAG                   */
      S0RIC = 0x00;         /* DELETE RECEIVE INTERRUPT FLAG                 */
      S0BG  = 0x40;         /* SET BAUDRATE TO 9600 BAUD                     */
      S0CON = 0x8011;       /* SET SERIAL MODE                               */
    #endif
    
      printf ("Hello World\n");  /* the 'printf' function call               */
      while (1) {                /* An embedded program does not stop and    */
        ;  /* ... */             /* never returns.  We've used an endless    */
      }                          /* loop.  You may wish to put in your own   */
    }                            /* code were we've printed the dots (...).  */

    Note that the initialization for the serial port is required when MON166 is not used.

    Jon

  • I tried to understand TxI with the help of Timer/counter x Input selection table but couldn't understand well.

    Actually the time between two interrupts is set by T01CON and T0REL - read the whole section on CAPCOM timers in the microcontroller manual. With such simple approach and using timer 0 that time can be increased to about 2 seconds (at 25MHz CPU clock). To get 1 minute or 1 hour you will have to count the number of interrupts and react accordingly every 60 or 3600 (or whatever) interrupts.

  • Hi all,

    Jon wrote:

    Well. ASC0 is NOT initialized to work when the C16x resets, so something initialized it. Are you using MON166 or another target monitor to download and run your code? If so, the monitor already initialized the serial port.

    I am using C167CS and there was a miss in my previous mail that I mentioned I use the same code for simulated and target environment which is not true.
    I noticed in my code later that I use one additinal "init_display()"statement in my code in the very beginning and it is where ASC0 is initialized (sorry for that miss),though it deals with P2 and not with P3(as in Hello world application).
    Now my simulated application work after I have added the code from Hello world application( thanks Jon for tips).

    Thanks to Mike for my next question regarding timing for interrupt routine.
    Thanks all of you for being so helpful.

    regards
    /M