PSoCEval1でTV出力(NTSCのモノクロ出力)ができないか実験してみました。
http://nicotak.com/psoc/sample/
eval1_tvout.zip
回路図です。抵抗2本とビデオの端子をつないだだけで作れます。
P00はPWM16の出力をDigInvで論理を反転させてポートに出力してます。
ポートP00の出力設定はstrongです。
実行したみた結果ですが、、、
横に4ドット出したら終わってしまいました。
処理スピードが足りません。
このマイコンは24MHzなんですが、どういうわけかAVRの8MHzよりも遅いみたいです。
これは最適化とかアセンブラとかでどうにか速くなるんでしょうか。
というわけで、まだまだ実験中です。
プログラムです。
簡単に説明すると次のとおりです。
・15750Hz周期で割り込みをかける。
・ライン数を1からカウントする。
・ライン数が262になったら1画面終了、1に戻す。
・ライン数が22以上だと描画。それ未満は同期信号です。
・60画面ぶんで1秒が経過。
//---------------------------------------------------------------------------- // C main line //---------------------------------------------------------------------------- #include <m8c.h> // part specific constants and macros #include "PSoCAPI.h" // PSoC API definitions for all User Modules int linenum = 0; int tick=0; unsigned int vram[]={ 0b0100010001000100, 0b1010101010101010, 0b1110111011101110, 0b1010101010101010, 0b0000000000000000, 0b1100110011001100, 0b1010101010101010, 0b1100110011001100, 0b1010101010101010, 0b1100110011001100, 0b0000000000000000, 0b0110011001100110, 0b1000100010001000, 0b1000100010001000, 0b1000100010001000, 0b0110011001100110, }; #define WIDTHSYNC (12000000/1000000) #define WIDTHSYNC2 (12000000/160000) #define PWMPERIOD (12000000/15750) char video_row=0; char video_row0=0; char dotcnt=0; unsigned int video_dotdat=0x0000; unsigned int video_dotmsk; #define VIDEO_ROWMAX 16 #define VIDEO_DOTH 10 #define VIDEO_SYSCLINE 22 #pragma interrupt_handler pwmISR void pwmISR(void){ linenum++; if(linenum < VIDEO_SYSCLINE){ if(linenum == 7){ //7-21 PWM16_WritePulseWidth(WIDTHSYNC2); video_row=0; video_row0=0; } if(linenum == 1){ //1-6 PWM16_WritePulseWidth(PWMPERIOD-WIDTHSYNC); } return; } if(linenum >= ((VIDEO_ROWMAX*VIDEO_DOTH)+VIDEO_SYSCLINE)){ if(linenum==262){ linenum=0; tick++; } return; } video_dotdat = vram[video_row]; dotcnt=4; while(dotcnt--){ if(video_dotdat & 0x8000){ PRT1DR |= (1<<0);// Port 1 Data Register }else{ PRT1DR &= ~(1<<0);// Port 1 Data Register } video_dotdat <<=1; } PRT1DR &= ~(1<<0);// Port 1 Data Register video_row0++; if(video_row0 >= VIDEO_DOTH){ video_row0=0; video_row++; } } void main() { int tickbak=0; char f=0; int sec=0; /* set period to eight clocks */ PWM16_WritePeriod(PWMPERIOD-1); /* set pulse width to generate a duty cycle */ PWM16_WritePulseWidth(WIDTHSYNC2); LCD_Start(); PRT1DM0 |= (1<<0); // Port 1 Drive Mode PRT1DM1 &= ~(1<<0); // Port 1 Drive Mode PRT1DM2 &= ~(1<<0); // Port 1 Drive Mode M8C_EnableGInt;//Enable Global Interrupt PWM16_Start(); /* start the PWM8! */ PWM16_EnableInt(); DigInv_Start(); while(1){ while(tickbak==tick); tickbak=tick; f++; if(f>=60){ //60f = 1sec f=0; LCD_Position(0,0); LCD_PrHexInt(sec); sec++; } } }