使用Arduino的LTC时间码阅读器

时间:2014-02-16 17:14:42

标签: arduino

我刚刚在这里发帖,你真的很有帮助。我已经设法调整了一些代码,使其能够在液晶显示器上工作。

我想要一些额外的帮助首先是有一种方法可以根据引脚的高低状态定义one_time_max等。这样我可以使用开关来改变时间,以便它可以在NTSC和PAL之间切换。

其次,任何人都应该善意地解释这段代码中间发生的事情。我知道有一个挥发性的布尔值,它可以是假的。但是稍后在代码中你会对它做一个IF语句,我不完全理解它是如何工作的。任何帮助将不胜感激。

这是一张到目前为止的情况。随着项目的继续,我会让你们保持最新状态:)

// Code from forum post Dec 12, 2007
//
//

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);


#define one_time_max          600 // these values are setup for PA video
#define one_time_min          400 // It's the durstion of a one and zero with a little bit of room for error. 
#define zero_time_max          1050 // 
#define zero_time_min          950 // 


#define icpPin 8      // ICP input pin on arduino
//#define one_time_max      475 // these values are setup for NTSC video
//#define one_time_min      300 // PAL would be around 1000 for 0 and 500 for 1
//#define zero_time_max    875 // 80bits times 29.97 frames per sec
//#define zero_time_min    700 // equals 833 (divide by 8 clock pulses)

#define end_data_position   63
#define end_sync_position   77
#define end_smpte_position     80

volatile unsigned int pin = 13;
volatile unsigned int bit_time;   // volatile instructs the variable to be stored in RAM
volatile boolean valid_tc_word;   // booleon can be either of two values true or false
volatile boolean ones_bit_count;  // booleon can be either of two values true or false
volatile boolean tc_sync;         // booleon can be either of two values true or false
volatile boolean write_tc_out;    // booleon can be either of two values true or false
volatile boolean drop_frame_flag; // booleon can be either of two values true or false

volatile byte total_bits;   //this stores a an 8-bit unsigned number
volatile byte current_bit;  //this stores a an 8-bit unsigned number
volatile byte sync_count;   //this stores a an 8-bit unsigned number

volatile byte tc[8];         //this stores a an 8-bit unsigned number
volatile char timeCode[11];  //this stores a an 8-bit unsigned number


/* ICR interrupt vector */
ISR(TIMER1_CAPT_vect)   //ISR=Interrupt Service Routine, and timer1 capture event
{
  //toggleCaptureEdge
  TCCR1B ^= _BV(ICES1); //toggles the edge that triggers the handler so that the duration of both high and low pulses is measured.

  bit_time = ICR1; //this is the value the timer generates 

  //resetTimer1
  TCNT1 = 0;

  if ((bit_time < one_time_min) || (bit_time > zero_time_max)) // this gets rid of anything that's not what we're looking for
  {
    total_bits = 0;
  }
  else
  {
    if (ones_bit_count == true) // only count the second ones pluse
    ones_bit_count = false;
    else
    {
    if (bit_time > zero_time_min)
    {
      current_bit = 0;
      sync_count = 0;
    }
    else //if (bit_time < one_time_max)
    {
      ones_bit_count = true;
      current_bit = 1;
      sync_count++;
      if (sync_count == 12) // part of the last two bytes of a timecode word
      {
        sync_count = 0;
        tc_sync = true;
        total_bits = end_sync_position;
      }
    }

    if (total_bits <= end_data_position) // timecode runs least to most so we need
    {                       // to shift things around
      tc[0] = tc[0] >> 1;

      for(int n=1;n<8;n++) //creates tc[1-8]
      {
        if(tc[n] & 1)
        tc[n-1] |= 0x80;

        tc[n] = tc[n] >> 1;
      }

      if(current_bit == 1)
        tc[7] |= 0x80;
    }
    total_bits++;
    }

    if (total_bits == end_smpte_position) // we have the 80th bit
    {
    total_bits = 0;
    if (tc_sync)
    {
      tc_sync = false;
      valid_tc_word = true;
    }
    }

    if (valid_tc_word)
    {
    valid_tc_word = false;

    timeCode[10] = (tc[0]&0x0F)+0x30;   // frames  this converst from binary to decimal giving us the last digit
    timeCode[9] = (tc[1]&0x03)+0x30;    // 10's of frames this converst from binary to decimal giving us the first digit
    timeCode[8] =  ':';
    timeCode[7] = (tc[2]&0x0F)+0x30;    // seconds
    timeCode[6] = (tc[3]&0x07)+0x30;    // 10's of seconds
    timeCode[5] =  ':';
    timeCode[4] = (tc[4]&0x0F)+0x30;    // minutes
    timeCode[3] = (tc[5]&0x07)+0x30;    // 10's of minutes
    timeCode[2] = ':';
    timeCode[1] = (tc[6]&0x0F)+0x30;    // hours
    timeCode[0] = (tc[7]&0x03)+0x30;    // 10's of hours

    drop_frame_flag = bit_is_set(tc[1], 2); //detects whether theree is the drop frame bit.

    write_tc_out = true;
    }
  }
}


void setup()
{
  lcd.begin (16, 2);
  pinMode(icpPin, INPUT);           // ICP pin (digital pin 8 on arduino) as input

  bit_time = 0;
  valid_tc_word = false;
  ones_bit_count = false;
  tc_sync = false;
  write_tc_out = false;
  drop_frame_flag = false;
  total_bits =  0;
  current_bit =  0;
  sync_count =  0;

lcd.print("Finished setup");
delay (1000);

  TCCR1A = B00000000; // clear all
  TCCR1B = B11000010; // ICNC1 noise reduction + ICES1 start on rising edge + CS11 divide by 8
  TCCR1C = B00000000; // clear all
  TIMSK1 = B00100000; // ICIE1 enable the icp

  TCNT1 = 0; // clear timer1
}

void loop()
{
    if (write_tc_out)
    {
    write_tc_out = false;
    if (drop_frame_flag)
      lcd.print("TC-[df] ");
    else
      lcd.print("TC-NO DROP FRAME");
lcd.setCursor(0, 1);
    lcd.print((char*)timeCode);
    lcd.print("\r");
lcd.setCursor(11, 1);
lcd.print("......");
delay (40);
lcd.clear(); } }

1 个答案:

答案 0 :(得分:0)

如果从类型声明中删除不应该影响«volatile»关键字,如代码所示▬编译器 - 编写者需要权衡人们想要做系统(这里的东西)并且它会阻塞机器以便它们告诉你volatile是某种奇特的东西,但在这里使用时远非如此

这是应该在这里的方式〜这不是商业机器