Demo.c
上传用户:sourcesun
上传日期:2013-09-23
资源大小:362k
文件大小:10k
源码类别:

DNA

开发平台:

Asm

  1. /******************************************************************************
  2. Example program to show how to trigger external interrupts by pressing buttons
  3. 1 and 1 on the IAR LPC2148 evaluation board.
  4. See schematic for button connections:
  5. BTN1 is hooked up to EINT2 on Port Pin P0.15
  6. BTN2 is hooked up to EINT0 on Port Pin P0.16
  7. This example does not use the PLL to mulitply the main clock frequency, so the
  8. main bus is running at 12MHz and the peripheral clock at 3MHz.
  9. The foreground task just resets timers and button states which are altered in
  10. interrupt service routines. The user can use these to signal tasks to be
  11. done in the foreground.
  12. There are three software timer, which expire every 100 milliseconds, every
  13. second, and every five seconds. Button presses are counted and data stored in
  14. the pressCount field of struct buttonData.
  15. Usage Notes:
  16. Option run to main is disabled to save watchpoint.
  17. ProjectLinker option box "With runtime control modules" unchecked to save
  18. watchpoint
  19. - During debug:
  20. - Click J-LinkWatchpoints
  21. - Check box for Watchpoint 0
  22. - Enter "VICVectAddr" (case sensitive) int Address
  23. - Enter 0xFFFFFFFF into Address mask
  24. - Select radio buttons R/W and Word in Access Type and Data respecively
  25. - In Data value enter 0x40000591 (ISR address of External Int 2)
  26. Similarly for Watchpoint 1, all same settings except enter 0x400005C1 for Data
  27. value
  28. Click Run
  29. - when you press button 1, you will break in function
  30. __irq __arm void IRQ_ISR_Handler (void) and trace into void Btn1DownISR(void)
  31. - similarly, when you press button 2 you will break at the same place and
  32. trace into void Btn2DownISR(void)
  33. ******************************************************************************/
  34. #include "demo.h"
  35. void main(void)
  36. {
  37.   SoftwareTimer_t *ptr2Timer = &softTimer[0];
  38.   unsigned int i;
  39.   initializeInterruptDataStructs();
  40.   installTimer(ptr2Timer,FIVE_SEC_TIMER,TICKS_PER_5_SECONDS,
  41.                FIVE_SEC_TIMER_INSTALLED);
  42.   installTimer(ptr2Timer,ONE_SEC_TIMER,TICKS_PER_SECOND,
  43.                ONE_SEC_TIMER_INSTALLED);
  44.   installTimer(ptr2Timer,ONE_HUNDRED_mSEC_TIMER,TICKS_PER_100mSEC,
  45.                ONE_HUNDRED_mSEC_TIMER_INSTALLED);
  46.   /* This if-else statement detects if interrupt vectors located by the linker
  47.   command file are at memory location 0 or not. If so, MEMMAP is set to 1 to run
  48.   program out of flash
  49.   */
  50.   #pragma segment = "INTVEC"
  51.   if (( void * )0x00000000UL == __segment_begin( "INTVEC" ))
  52.   {
  53.     MEMMAP = 1;  // normal flash mode
  54.   }
  55.   else
  56.   {
  57.     MEMMAP = 2 ; // user ram mode - Map lowest 64 bytes of the address space to
  58.                  //bottom of internal RAM, moving exception vectors into place
  59.   }
  60.   /* Init MCU Clock */
  61.   /* Fosc = 12MHz, Fpckl = 12MHz */
  62.   PLLCON_bit.PLLC = PLLCON_bit.PLLE = 0; // Disable and disconnect PLL
  63.   feed();                                // PLL feed sequence
  64.   /* Init Peripherial divider Pckl = Clk/4 */
  65.   VPBDIV_bit.VPBDIV = 0;
  66.   /* This section of code configures Timer 0, match channel 0 to interrupt on
  67.   matching the value stored in MR0 */
  68.   T0IR=0xFF;           // reset match and capture event interrupts
  69.   T0TCR=0;             // Disable counting
  70.   T0TC=0;              // Clear timer counter
  71.   T0PR= 0;             // No Prescalar
  72.   T0PC=0;              // Clear prescaler timer counter
  73.   T0MR0=PCLKFREQ/100;  // Count up to 36,864 for 100Hz interrupt, period = 10ms
  74.   T0MCR |= (RESET | INT_ON_MATCH);  // Reset Timer Counter & Interrupt on match
  75.   T0TCR &= ~2;         // Clear reset flag
  76.   T0TCR = 1;           // Counting enable
  77.   /* Preliminary setup of the VIC. Assign all interrupt chanels to IRQ */
  78.   VICIntSelect  =  0;             // Set all VIC interrupts to IRQ for now
  79.   VICIntEnClear = 0xFFFFFFFF;     // Diasable all interrupts
  80.   VICSoftIntClear = 0xFFFFFFFF;   // Clear all software interrutps
  81.   VICProtection = 0;              // VIC registers can be accessed in User or
  82.                                   // privileged mode
  83.   VICVectAddr = 0;                // Clear interrupt
  84.   VICDefVectAddr = 0;             // Clear address of the default ISR
  85.   /*Configure the pins that the buttons are hooked up to to be external
  86.   interrupts */
  87.   PINSEL0_bit.P0_15=0x2;          // Set Port pin P0.15 function to EINT2
  88.   PINSEL1_bit.P0_16=0x1;          // Set Port pin P0.16 function to EINT0
  89.   /* Clear the VICVectAddress slots 0-15 and VICVectCtrl slots 0-15 */
  90.   VICVectAddr0  = 
  91.   VICVectAddr1  = 
  92.   VICVectAddr2  = 
  93.   VICVectAddr3  = 
  94.   VICVectAddr4  = 
  95.   VICVectAddr5  = 
  96.   VICVectAddr6  = 
  97.   VICVectAddr7  = 
  98.   VICVectAddr8  = 
  99.   VICVectAddr9  = 
  100.   VICVectAddr10 = 
  101.   VICVectAddr11 = 
  102.   VICVectAddr12 = 
  103.   VICVectAddr13 = 
  104.   VICVectAddr14 = 
  105.   VICVectAddr15 = 0;
  106.                                   // Disable all vectored IRQ slots
  107.   VICVectCntl0  = 
  108.   VICVectCntl1  = 
  109.   VICVectCntl2  = 
  110.   VICVectCntl3  = 
  111.   VICVectCntl4  = 
  112.   VICVectCntl5  = 
  113.   VICVectCntl6  = 
  114.   VICVectCntl7  = 
  115.   VICVectCntl8  = 
  116.   VICVectCntl9  = 
  117.   VICVectCntl10 = 
  118.   VICVectCntl11 = 
  119.   VICVectCntl12 = 
  120.   VICVectCntl13 = 
  121.   VICVectCntl14 = 
  122.   VICVectCntl15 = 0;
  123.   /* This section installs the specific interrupts and configure the VIC
  124.   control registers and sets them as IRQs */
  125.   VICProtection = 0;                           // Accesss VIC in USR | PROTECT
  126.   VICDefVectAddr = (unsigned int)&NonVectISR;  // Install default ISR addr
  127.   /* Setup the Timer0 interrupt on match interrupt */
  128.   VICIntSelect &= ~(1<<VIC_TIMER0);            // Timer 0 intrpt is an IRQ
  129.   VICVectAddr0 = (unsigned int)&MM_TIMER0_ISR; // Install ISR in VIC addr slot
  130.   VICVectCntl0 = 0x20 | VIC_TIMER0;            // IRQ type, TIMER 0 int enabled
  131.   VICIntEnable |= (1<<VIC_TIMER0);             // Turn on Timer0 Interrupt
  132.   /* Set up the button 1 pressed interrupt on EINT0 */
  133.   VICIntSelect &= ~(1<<VIC_EINT0);              // IRQ on external int 0.
  134.   VICVectAddr1 = (unsigned int)&Btn2DownISR;    // Install ISR in VIC addr slot
  135.   VICVectCntl1 = 0x20 | VIC_EINT0;              // Enable vec int for EINT 0.
  136.   VICIntEnable |= (1<<VIC_EINT0);               // Enable EINT0 interrupt.
  137.   /* Set up the button 2 pressed interrupt on EINT2 */
  138.   VICIntSelect &= ~(1<<VIC_EINT2);              // IRQ on external int 2.
  139.   VICVectAddr2 = (unsigned int)&Btn1DownISR;    // Install EINT2 in VIC addr slot
  140.   VICVectCntl2 = 0x20 | VIC_EINT2;              // Enable vect int for EINT2.
  141.   VICIntEnable |= (1<<VIC_EINT2);               // Enable EINT 2 interrupt.
  142.   __enable_interrupt();                         // Global interrupt enable
  143.   /*This is the foreground loop, which looks at data coming from the background
  144.   loop. The user can insert own code to react to timer and button driven
  145.   events */
  146.   while(TRUE)                                      // Foreground Loop
  147.   {
  148.     for(i = 1; i<MAX_BUTTONS; i++)
  149.     {
  150.       if(buttonData[i].us_buttonState == DOWN)
  151.       {
  152.         buttonData[i].us_buttonState = UP;
  153.         buttonData[i].us_pressCount = 0;
  154.       }
  155.     }
  156.     if(softTimer[FIVE_SEC_TIMER].us_Event == TIMER_EXPIRED)
  157.         installTimer(ptr2Timer,FIVE_SEC_TIMER,TICKS_PER_5_SECONDS,
  158.                FIVE_SEC_TIMER_INSTALLED);
  159.     if(softTimer[ONE_SEC_TIMER].us_Event == TIMER_EXPIRED)
  160.       installTimer(ptr2Timer,ONE_SEC_TIMER,TICKS_PER_SECOND,
  161.                ONE_SEC_TIMER_INSTALLED);
  162.     if(softTimer[ONE_HUNDRED_mSEC_TIMER].us_Event == TIMER_EXPIRED)
  163.       installTimer(ptr2Timer,ONE_HUNDRED_mSEC_TIMER,TICKS_PER_100mSEC,
  164.                ONE_HUNDRED_mSEC_TIMER_INSTALLED);
  165.   } // end foreground loop
  166. }   // end main()
  167. void installTimer
  168. (
  169.   SoftwareTimer_t *ptr2Timer,
  170.   unsigned int us_offset,
  171.   unsigned int us_ticks,
  172.   unsigned int us_event
  173. )
  174. {
  175.   (ptr2Timer+us_offset)->us_Ticks = us_ticks;
  176.   (ptr2Timer+us_offset)->us_Event = us_event;
  177. }
  178. void initializeInterruptDataStructs(void)
  179. {
  180.   unsigned int i;
  181.   for(i=0;i<MAX_BUTTONS;i++)
  182.   {
  183.     buttonData[i].us_buttonState = UP;
  184.     buttonData[i].us_pressCount = 0;
  185.   }
  186.   for(i=0;i<MAX_SOFTWARE_TIMERS;i++)
  187.   {
  188.     softTimer[i].us_Ticks = 0;
  189.     softTimer[i].us_Event = EVENT_UNDEFINED;
  190.   }
  191. }
  192. /*************************************************************************
  193.  * Function Name: IRQ_ISR_Handler
  194.  * Parameters: void
  195.  * Return: void
  196.  *
  197.  * Description: IRQ subroutine
  198. * Note: This is ARM mode code - full 32 bit code
  199.  *************************************************************************/
  200. #pragma vector=0x18
  201. __irq __arm void IRQ_ISR_Handler (void)
  202. {
  203.   void (*interrupt_function)();
  204.   unsigned int vector;
  205.   vector = VICVectAddr;     // Get interrupt vector.
  206.   interrupt_function = (void(*)())vector;
  207.   (*interrupt_function)();  // Call vectored interrupt function
  208.   VICVectAddr = 0;          // Clear interrupt in VIC
  209. }
  210. /*************************************************************************
  211.  * Function Name: MM_TIMER0_ISR
  212.  * Parameters: void
  213.  * Return: void
  214.  *
  215.  * Description: TIMER0 interrupt subroutine
  216.  *
  217.  *************************************************************************/
  218. void MM_TIMER0_ISR()
  219. {
  220.   unsigned int IntType;
  221.   unsigned int i;
  222.   for(i=0; i<MAX_SOFTWARE_TIMERS; i++)
  223.     if(softTimer[i].us_Ticks > 1)
  224.       softTimer[i].us_Ticks--;
  225.     else
  226.       softTimer[i].us_Event = TIMER_EXPIRED;
  227.   IntType = (T0IR & 0xFF); // confirm interrupt type
  228.   T0IR = (IntType & 0xFF); // Clear timer interrupt
  229. }
  230. void Btn1DownISR(void)
  231. {
  232.   EXTINT_bit.EINT2 = 1;   // Try to reset external interrupt flag.
  233.   if(!EXTINT_bit.EINT2)   // Check if flag was reset (button not pressed).
  234.   {
  235.     buttonData[1].us_buttonState = DOWN;
  236.     buttonData[1].us_pressCount++;
  237.   }
  238. }
  239. void Btn2DownISR(void)
  240. {
  241.   EXTINT_bit.EINT0 = 1;   // Try to reset external interrupt flag.
  242.   if(!EXTINT_bit.EINT0)   // Check if flag was reset (button not pressed).
  243.   {
  244.     buttonData[2].us_buttonState = DOWN;
  245.     buttonData[2].us_pressCount++;
  246.   }
  247. }
  248. void NonVectISR(void)
  249. {
  250.   while(TRUE);           // You should never get here, so spin in tight loop
  251.                          // to signal something is amiss
  252. }
  253. // Feed sequence for the PLL
  254. void feed (void)
  255. {
  256.   PLLFEED=0xAA;
  257.   PLLFEED=0x55;
  258. }