ATtiny412でNTSCビデオ信号 [Arduino]
NTSCでのビデオ出力。
いろいろ調べてみたけど、結構たいへん。
1.情報収集
小さなカラーLCDなども安価になってきていて、いまどきマイコンでNTSCでのビデオ出力する人が少なくなっている。記事をさぐると10年くらい前のものが多く、リンク切れも多数。
カラー、ノンインターレスの説明は見つかるものの、基本のモノクロとノンインターレスの情報が少なめ。PICでの情報が多めな感じ。
2.ソフトウェア
全部あるいは部分的にアセンブラを使わないといけなかったり、SPIを出力につかったり。
とくにカラーは超高難度のよう。
別ICと組み合わせが必要なものも。
3.ハードウェア
簡単なものだと同期信号と画像信号と2本の抵抗を介して出力。
外部クロックを使用しないと画像が揺らぐらしい。
そこで、C言語だけで、tinyAVR 1シリーズのDAC機能を使って、コネクタ以外の外付けパーツなしでビデオ出力できるかやってみました。
とりあえずできたけど、ウェイトなしで横16ドットしか表示できていない。
もうちょっとなんとかなりそうな気もする。
[2023/11/02]
その後、ちょっと改善
・割り算をなくした
・16ビットでなくてもいい変数は8ビットに
・データを1ドットあたり1byte → 1bitとした
・for文を使わず、配列の添え字を変数にせず、すべて展開
(横1ドットにつきプログラム1行)
などで、横128ドットまでは行きついた。
同期をなんとかせねば。
[2023/11/03]
ジッター(揺らぎ)の原因がプログラムの問題なのか、クリスタルの有無の問題なのか、SYNCとVIDEOと2本の抵抗を使ってATmega328のArduinoに移植してみた。
1ドット毎の幅が違うから右端がそろわないけど、くっきりになった。
やっぱりクリスタルがないとダメってことか。
[2023/11/03]
いろいろ修正しながらATtint202でやってみた。
ジッター(揺らぎ)はあるものの、くっきりはした。エッジがぼやけるのはDACのせいだったらしい。
もうちょっと形になったらブログに上げたい。
いろいろ調べてみたけど、結構たいへん。
1.情報収集
小さなカラーLCDなども安価になってきていて、いまどきマイコンでNTSCでのビデオ出力する人が少なくなっている。記事をさぐると10年くらい前のものが多く、リンク切れも多数。
カラー、ノンインターレスの説明は見つかるものの、基本のモノクロとノンインターレスの情報が少なめ。PICでの情報が多めな感じ。
2.ソフトウェア
全部あるいは部分的にアセンブラを使わないといけなかったり、SPIを出力につかったり。
とくにカラーは超高難度のよう。
別ICと組み合わせが必要なものも。
3.ハードウェア
簡単なものだと同期信号と画像信号と2本の抵抗を介して出力。
外部クロックを使用しないと画像が揺らぐらしい。
そこで、C言語だけで、tinyAVR 1シリーズのDAC機能を使って、コネクタ以外の外付けパーツなしでビデオ出力できるかやってみました。
とりあえずできたけど、ウェイトなしで横16ドットしか表示できていない。
もうちょっとなんとかなりそうな気もする。
// ATtiny412 NTSC test (20MHz)
#define IRE_p100 (59) // = 255 * 1.0V/4.34V * (40+100)/140
#define IRE_p50 (38) // = 255 * 1.0V/4.34V * (40+ 50)/140
#define IRE_0 (17) // = 255 * 1.0V/4.34V * 40 /140
#define IRE_m40 (0)
uint8_t const img_i[] = {
0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,
0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,
0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,
0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,
0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,
0,0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,
0,0,0,0,1,1,1,0,0,1,1,0,0,0,0,0,
0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,
0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,
0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,
0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
void setup(){ // Register Settings
// VIDEO OUTPUT
VREF.CTRLA |= VREF_DAC0REFSEL_4V34_gc; // Voltage reference at 4.34V
VREF.CTRLB |= VREF_DAC0REFEN_bm; // DAC0/AC0 reference enable: enabled
delayMicroseconds(25); // Wait VREF start-up time
PORTA.PIN6CTRL &= ~PORT_ISC_gm; // Disable digital input buffer
PORTA.PIN6CTRL |= PORT_ISC_INPUT_DISABLE_gc;
PORTA.PIN6CTRL &= ~PORT_PULLUPEN_bm; // Disable pull-up resistor
DAC0.CTRLA = DAC_ENABLE_bm | DAC_OUTEN_bm; // Enable DAC, Output Buffer
// H-SYNC
TCB0.CTRLA = TCB_CLKSEL_CLKDIV1_gc | TCB_ENABLE_bm;// 20MHz / 1 / 1270 -> 15,750Hz
TCB0.CTRLB = TCB_CNTMODE_INT_gc; // periodic Interrupt mode
TCB0_CCMP = 1269; // top value
TCB0.INTCTRL= TCB_CAPT_bm; // Capture Interrupt Enable
}
void loop() {
}
ISR(TCB0_INT_vect) {
static uint16_t scan, x, y, offset;
DAC0.DATA = IRE_0; // start from -3.2usec
scan++;
while(TCB0_CNT < 94); // front porch (20MHz*(3.2+1.5 )usec=94)
DAC0.DATA = IRE_m40;
if(scan > 3 && scan < 7) goto END;
while(TCB0_CNT < 188); // back porch (20MHz*(3.2+1.5+4.7)usec=188)
DAC0.DATA = IRE_0;
if(scan < 48 || scan > 239) goto END; // 192 lines
y = (scan - 48) / 12; // y = 0..15
offset= y<<4;
while(TCB0_CNT < 282); // H-blanking (20MHz*(3.2+10.9 )usec=282)
MAIN:
for(x=0; x<16; x++) {
DAC0.DATA = (img_i[x + offset]) ? IRE_p100 : IRE_0;
}
DAC0.DATA = IRE_0;
END:
if(scan == 262) scan = 0;
TCB0.INTFLAGS= TCB_CAPT_bm; // Clear Capture Interrupt Flag
}
[2023/11/02]
その後、ちょっと改善
・割り算をなくした
・16ビットでなくてもいい変数は8ビットに
・データを1ドットあたり1byte → 1bitとした
・for文を使わず、配列の添え字を変数にせず、すべて展開
(横1ドットにつきプログラム1行)
などで、横128ドットまでは行きついた。
同期をなんとかせねば。
[2023/11/03]
ジッター(揺らぎ)の原因がプログラムの問題なのか、クリスタルの有無の問題なのか、SYNCとVIDEOと2本の抵抗を使ってATmega328のArduinoに移植してみた。
1ドット毎の幅が違うから右端がそろわないけど、くっきりになった。
やっぱりクリスタルがないとダメってことか。
[2023/11/03]
いろいろ修正しながらATtint202でやってみた。
ジッター(揺らぎ)はあるものの、くっきりはした。エッジがぼやけるのはDACのせいだったらしい。
もうちょっと形になったらブログに上げたい。
2023-10-29 01:13
nice!(0)
コメント(0)
コメント 0