【问题标题】:LTC Timecode Reader using Arduino使用 Arduino 的 LTC 时间码阅读器
【发布时间】:2014-02-16 17:14:42
【问题描述】:

我不久前在这里发帖,你真的很有帮助。而且我已经设法修改了一些代码以使其在液晶显示器上工作。

我想要一些额外的帮助首先是有一种方法可以根据引脚的高低状态定义 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(); } }

【问题讨论】:

标签: arduino


【解决方案1】:

从类型声明中删除的 if 不应该影响代码中显示的 «volatile» 关键字告诉你volatile是某种异国情调的东西,但在这里使用时远非如此

它应该是这里的样子~那不是商业机器

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多