Advertisement
Guest User

Maple Frequency Measurement Example

a guest
Dec 14th, 2011
320
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.31 KB | None | 0 0
  1. /*
  2. * This paste provided by Chris Troutner from http://thesolarpowerexpert.com
  3. *
  4. * This code is based on publicly available code available at the following sources:
  5. * http://pastebin.com/NQtbVCFh
  6. * http://forums.leaflabs.com/topic.php?id=1038
  7. *
  8. * It's inteded for a Maple Rev 5 from leaflabs.com
  9. */
  10.  
  11. #include <timer.h>
  12.  
  13.  
  14.  
  15. int value = 0;
  16. int count = 0;
  17.  
  18. int overflow_flag = 0;
  19.  
  20. HardwareTimer timer4 = HardwareTimer(4);
  21.  
  22. //quick method to return if there's anyone on the other end of the serialusb link yet.
  23. boolean isConnected(){
  24.   return (SerialUSB.isConnected() && (SerialUSB.getDTR() || SerialUSB.getRTS()));
  25. }
  26.  
  27. void setup()
  28. {
  29.  
  30.   SerialUSB.begin();
  31.   while(!isConnected()); //wait till console attaches.
  32.   SerialUSB.println("Hello!");
  33.  
  34.   //Setup Timer4 Channel 1 (pin 5) as an input
  35.   pinMode(5, INPUT);
  36.  
  37.   //Configure pin 7 as an output
  38.   pinMode(7, OUTPUT);
  39.  
  40.   setup_timer();
  41.        
  42. }
  43.  
  44. void __measurePulse_irq()
  45. {
  46.  
  47.   //For some reason, the interrupt is triggred as soon as
  48.   //the device is turned on. This gets around that bug.
  49.   if( count == 0 )
  50.     return;
  51.   else {
  52.    
  53.     if(~overflow_flag)
  54.       value = TIMER4_BASE->CCR1;        //read the captured value
  55.     else {
  56.       value = 0;
  57.       overflow_flag = 0;
  58.     }
  59.      
  60.  
  61.     timer4.setCount(0);  //Zero timer
  62.   }
  63. }
  64.  
  65. void handle_overflow() {
  66.  
  67.   overflow_flag = 1;
  68. }
  69.  
  70. void loop() {
  71.  
  72.   //Display the value very 500 mS
  73.   if( count == 100 ) {
  74.     //delay(500);
  75.     SerialUSB.println(value);
  76.     //value = 0;
  77.     count = 0;
  78.   }
  79.  
  80.  
  81.   //Pulse pin 7 at a rate of 100 Hz @ 50% DC
  82.   digitalWrite(7, HIGH);
  83.   delay(5);
  84.   digitalWrite(7, LOW);
  85.   delay(5);
  86.  
  87.   count++;
  88.  
  89. }
  90.  
  91.  
  92. //Halt processor and flash LED - used for debugging
  93. void HaltAll(void) {
  94.  
  95.   //Timer4.pause();
  96.   timer4.pause();
  97.   pinMode(BOARD_LED_PIN, OUTPUT);
  98.  
  99.   while(1) {
  100.      
  101.      toggleLED();
  102.      delay(1000);
  103.    
  104.   }
  105.  
  106. }
  107.  
  108. /*
  109. This is a mis-mash of code from these two sources:
  110. http://pastebin.com/NQtbVCFh
  111. http://forums.leaflabs.com/topic.php?id=1038
  112. */
  113. void setup_timer(void) {
  114.  
  115.   //Create a pointer to the timer (why?)
  116.   timer_dev *t = TIMER4;
  117.      
  118.   //Initialize timer  
  119.   timer4.pause();
  120.  
  121.   /*
  122.   A prescaler of 288 means that at 72MHz, I get the following:
  123.   100 Hz = 2510
  124.   10 Hz = 25084
  125.   */
  126.   timer4.setPrescaleFactor(288);
  127.  
  128.   timer4.setOverflow(65535);
  129.   timer4.setCount(0);
  130.  
  131.   //New code to set overflow timer
  132.   timer4.setMode(2, TIMER_OUTPUT_COMPARE); //Set this channel to compare
  133.   timer4.setCompare(2, 65534); //Set the compare for the channel to the overflow vale
  134.   timer4.attachInterrupt(2, handle_overflow); //Assign the interrupt handler
  135.  
  136.   timer4.refresh();
  137.  
  138.   //Create a pointer to the timer registers (why?)
  139.   timer_reg_map r = t->regs;
  140.      
  141.      
  142.   //capture compare regs TIMx_CCRx used to hold val after a transition on corresponding ICx
  143.  
  144.   //when cap occurs, flag CCXIF (TIMx_SR register) is set,
  145.   //and interrupt, or dma req can be sent if they are enabled.
  146.  
  147.   //if cap occurs while flag is already high CCxOF (overcapture) flag is set..
  148.  
  149.   //CCIX can be cleared by writing 0, or by reading the capped data from TIMx_CCRx
  150.   //CCxOF is cleared by writing 0 to it.
  151.  
  152.   //Capture/Compare 1 Selection
  153.   //  set CC1S bits to 01 in the capture compare mode register.
  154.   //  01 selects TI1 as the input to use. (page 336 stm32 reference)
  155.   //  (assuming here that TI1 is D6, according to maple master pin map)
  156.   //CC1S bits are bits 0,1
  157.   bitSet(r.adv->CCMR1, 0);
  158.   bitClear(r.adv->CCMR1, 1);
  159.  
  160.  
  161.   //Input Capture 1 Filter.
  162.   //  need to set IC1F bits according to a table saying how long
  163.   //  we should wait for a signal to be 'stable' to validate a transition
  164.   //  on the input.
  165.   //  (page 336 stm32 reference)
  166.   //IC1F bits are bits 7,6,5,4    
  167.   bitClear(r.adv->CCMR1, 7);                        
  168.   bitClear(r.adv->CCMR1, 6);  
  169.   bitSet(r.adv->CCMR1, 5);  
  170.   bitSet(r.adv->CCMR1, 4);  
  171.  
  172.   //sort out the input capture prescaler..
  173.   //00 no prescaler.. capture is done as soon as edge is detected
  174.   bitClear(r.adv->CCMR1, 3);                        
  175.   bitClear(r.adv->CCMR1, 2);  
  176.  
  177.   //This command does everything above to the CCMR1 register.
  178.   //TIMER4_BASE->CCMR1 = 0x00F1;        //channel 1 configure as input, IC1 mapped on TI1
  179.  
  180.   //select the edge for the transition on TI1 channel using CC1P in CCER
  181.   //CC1P is bit 1 of CCER (page 339)
  182.   // 0 = rising
  183.   // 1 = falling
  184.   bitClear(r.adv->CCER,1);
  185.  
  186.   //set the CC1E bit to enable capture from the counter.
  187.   //CCE1 is bit 0 of CCER (page 339)
  188.   //Enable capture
  189.   bitSet(r.adv->CCER,0);
  190.  
  191.  
  192.   //TIMER4_BASE->CCMR2 = 0x0000;        //channels 3&4 disabled
  193.   //TIMER4_BASE->CCER = 0x0001;     //configure channel 1 as an input
  194.   //TIMER4_BASE->SMCR = 0x0000;     //all slave modes disabled, CC transitions on clock
  195.  //TIMER4_BASE->CR1 = 0x0001;       //enable the counter
  196.   //TIMER4_BASE->CR2 = 0x0000;      //connect TIM4_CH1 pin to TI1 input
  197.   //TIMER4_BASE->PSC = 0x00FF;      //set a random large prescalar just for testing
  198.  
  199.   //timer_attach_interrupt(TIMER4, TIMER_CC1_INTERRUPT, __measurePulse_irq);
  200.   timer4.attachInterrupt(1, __measurePulse_irq);
  201.  
  202.   //timer_resume(TIMER4);
  203.   timer4.resume();
  204.  
  205.   /*value = TIMER4_BASE->CCMR2;
  206.   SerialUSB.println("Value is: ");
  207.   SerialUSB.println(value);
  208.   HaltAll();
  209.   */
  210. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement