We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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 (...). */
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