Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*********************************************************
- 2313dmx_hzsync_com_test_001: DMX HzSynchronize Common test ver0.2
- for ATtiny2313 (8MHz)
- at PCB :dmx-rec2313s ver2.0 late
- ただしダイオードをジャンパーに置き換え
- 入出力にプルダウン追加必要
- main.c
- DMX512 4ch DIMMER
- DMX channel (base address + n)
- 0ch: (PWM0:PD5)ACPumpTriac
- 1ch: (PWM1:PB3,PB4)25kHzPWMcontrolFAN
- DMX base address
- Address 256 128 64 32 16 8 4 2 1
- i-bit 8 7 6 5 4 3 2 1 0
- PORT PB7 PB6 PB5 PB1 PB0 PD6 PD4 PD3 PD2
- (address=0 =>512ch)
- 8MHz=0.000125ms=0.125µs
- PB2:ACゼロクロストリガー入力:0.5ms=500µs
- PD5:AC非ゼロクロストリガー出力
- PB3:二重反転ファン吸込側PWM(茶)25kHz:PB4と同期
- PB4:二重反転ファン吐出側PWM(白)25kHz:PB3と同期
- PD1:PD1PullUp(H:共通/L:50Hz限定)
- #HighFuse 0xdf = 0b11011111
- #LowFuse 0xfc = 0b11111100
- v0.1 20180721 "2313dmx_hzsync_test_001"より分岐
- PD1High(PullUp),スイッチを省いた時に周波数共通設定
- その場合,50Hz約40~75%,60Hz約10~50%の制御となる
- ただし液送りのため,双方Full動作追加
- 目的上,ポンプを7割以上稼働しない前提
- Created by Tsunehiro Oketani
- Copyright oketronics 2018 All rights reserved.
- *********************************************************/
- #include <avr/io.h>
- #include "dmx_recv.h"
- #define DMX_SIZE 2 //連続するDMX受信チャンネル数
- //"dmx_recv.h"のDMX_BUF_SIZEが上限
- static volatile int a; //a:ゼロクロス検出フラグ
- //staticは記述されたファイル内でのみ使用が制限される変数,0に初期化される
- //volatileは常に更新される変数,最適化による消失防止
- /**ゼロクロス検出**/
- //AC100Vのゼロクロスを検出しPB2にHigh入力
- //優先順位がUSARTRX割込みより低いピン変化割込み
- ISR(PCINT_vect){
- if(!a){ //a == 0,次のゼロクロス入力待機
- if(PINB & _BV(PINB2)){ //PB2にゼロクロスHigh入力があったら
- //TCNT0 = 0; //Timer0カウントをリセット
- a=1; //検出中
- }
- }
- if(a){ //a == 1,ゼロクロス検出中
- //Timer0スタート時(PD5出力時)に確実に0Vを超えているように
- //ゼロクロスをフォトトライアックが検出中はTimer0を停止しておく
- if(PINB & _BV(PINB2)){
- TCNT0 = 0; //Timer0カウントをリセット
- //a = 1;
- }
- //else {a = 0;}
- }
- if(!(PINB & _BV(PINB2))){
- a = 0;
- }
- }
- /**PWM出力のための設定と初期化**/
- void init_pwm (void) {
- /*8bit高速PWM(ACポンプ制御フォトトライアック)*/
- //Timer0カウンター、比較レジスタを初期化
- TCNT0 = 0;
- OCR0A = 0;
- OCR0B = 0;
- //高速PWM動作,TOP値COR0A
- TCCR0B |= _BV(WGM02);
- TCCR0A |= _BV(WGM01) | _BV(WGM00);
- //比較一致でHigh、BOTTOMでLowをOC0Bへ出力(反転動作)
- TCCR0A |= _BV(COM1B0) | _BV(COM1B1);
- ////Timer0:AC50Hzおよび60Hz同期////
- //クロック周波数/(タイマー分周*TOP値COR0A)=AC半波
- //PD1High(PullUp):50,60Hz共通設定
- //8,000,000 / (256 * COR0A) = (60 x 2)の近似値
- if(PIND & _BV(PIND1)){ //PD1がHighであれば
- TCCR0B |= _BV(CS02); //8MHz/256分周=31250Hz
- OCR0A = 0xf0; //240:0xf0:130.2Hz
- }
- //PD1Low:東日本50Hz限定最適化
- //8,000,000 / (1024 * COR0A) = (50 x 2)の近似値
- if(!(PIND & _BV(PIND1))){//PD1がLowであれば
- TCCR0B |= _BV(CS02) | _BV(CS00);//8MHz/1024分周=7812.5Hz
- OCR0A = 0x4d; //東日本50HzのOCR0A値(77=78-1:0x4d:100.17Hz)
- }
- /*16bit高速PWM(DCファン制御25kHzPWM)*/
- //Timer1カウンター、比較レジスタを初期化
- TCNT1 = 0;
- OCR1A = 0;
- OCR1B = 0;
- //高速PWM動作,Top値ICR1
- TCCR1B |= _BV(WGM12) | _BV(WGM13);
- TCCR1A |= _BV(WGM11);
- //比較一致でLow、BOTTOMでHighをOC1A,OC1Bへ出力(非反転動作)
- TCCR1A |= _BV(COM1A1) | _BV(COM1B1);
- //Top値
- ICR1 = 0x013f; //320=0x140,319=0x013f
- //(システムクロック8MHz分周なし)/(2*TCNT1分周*TOP値320)=12.5kHz
- //ノコギリ波割込み反転周期12.5kHz
- //OCR1A,OCR1B比較一致による周期25kHz
- //オシロ実測で25kHzに調整,ICR1=319=0x013f
- //TCNT1クロック分周なし
- TCCR1B |= _BV(CS10);
- }
- /*IOポート初期化*/
- void init_io (void) {
- PORTA = 0x03; // 00000011 PA0,PA1 PullUp
- PORTB = 0xe3; // 11100011 PB0,1,5,6,7 PullUp
- PORTD = 0x5c; // 01011100 PD2,3,4,6 PullUp
- PORTD|= _BV(PD1); //PD1 PullUp 50/60Hz切り替え
- DDRB = 0x00; // 00000000 PB3~4 はmainでbit操作
- DDRD = 0x00; // 00000000 PD1,5 はmainでbit操作
- }
- /*システムクロック変更初期化*/
- //出荷時のヒューズビットCKSEL=0100, SUT=10, CKDIV8=0
- void init_sysclk (void) {
- //標準でCKDIV8=0のため8分周(CLKPS3~0を0011に設定)してしまう
- //念のため分周なしに初期化
- CLKPR = _BV(CLKPCE);//クロック分周変更許可
- CLKPR = 0x00; //分周なしに変更
- }
- /*ピン変化割込み初期化*/
- //AC100Vのゼロクロス付近のHighトリガーをPB2に入力
- //PB2のピン変化0群について割込み許可設定
- void init_pin_int (void) {
- GIMSK |= _BV(PCIE); //一般割り込み許可レジスタ,ピン変化0群割り込み許可(PCIE)bit5
- PCMSK |= _BV(PCINT2); //ピン変化0群割り込み許可レジスタ,個別PB2を許可(PCINT2)bit2
- }
- int main (void) {
- int i; //i:アドレスに関連
- unsigned char pwm0 = 0;
- unsigned char pwm1 = 0;
- volatile unsigned char *dmx_buf;
- /**デバイスを初期化**/
- init_sysclk();
- init_io();
- init_pwm();
- init_pin_int();
- /**DMX base address**/
- //DipSWなどでIOポートのLowを数える
- //Address 256 128 64 32 16 8 4 2 1
- //i-bit 8 7 6 5 4 3 2 1 0
- //PORT PB7 PB6 PB5 PB1 PB0 PD6 PD4 PD3 PD2
- i = ((~PIND & 0x1c) >> 2); //0b00011100:PD4,3,2 :i-bit2,1,0
- i |= ((~PIND & 0x40) >> 3); //0b01000000:PD6 :i-bit3
- i |= ((~PINB & 0x03) << 4); //0b00000011:PB1,0 :i-bit5,4
- i |= ((~PINB & 0xe0) << 1); //0b11100000:PB7,6,5 :i-bit8,7,6
- //処理中"dmx_recv.c"のdmx_ch値は0~511
- //dmx_buf[i-1]
- if (i) { //IOポートを2進法で数える
- dmx_buf = init_dmx(i - 1, DMX_SIZE);
- //"dmx_recv.c"のUSART初期化へ
- //"i-1"はchに、"DMX_SIZE"はsizeに
- }
- else if (!i) { //IOポートに入力がない場合512ch
- dmx_buf = init_dmx(512 - 1, DMX_SIZE);
- }
- sei(); //デバイス初期化、ポート読み込み終わったので割り込みを許可
- /*メインループ*/
- while (1) {
- wait_dmx(); //DMX受信完了
- pwm0 = dmx_buf[0];
- pwm1 = dmx_buf[1];
- //PD1High(PullUp):50,60Hz共通設定
- if(PIND & _BV(PIND1)){ //PD1がHighであれば
- if(pwm0 >=25){//pwm0が25以上になったとき
- if(pwm0==255){//ポンプ液送りのためFull
- OCR0B = 25;//0にするとゼロクロス地点を超えてしまい波形が乱れる
- }
- else{//Top値と調整,ポンプを目的上7割以上で稼働しない前提
- //OCR0B = 280 - (pwm0);//60Hzフルスケール,50Hzでは使用不可
- //OCR0B = 250 - ((pwm0)*7/10);//両周波数の最大公約
- OCR0B = 230 - (pwm0>>1);//50Hz75%程度基準,60Hz50%程度
- //OCR0B = 230 - ((pwm0)/3);//50Hz50%程度基準,60Hz40%程度
- }
- }
- else{ //pwm0が25未満のとき
- OCR0B = 255;//
- //クロック分周の制約上120Hzのところ130Hzなので超過する値を調整
- //8bitのOCR0Bとpwm0の値を反転させているので、
- //pwm0=25のとき,280-25=255で下限
- //pwmが25未満のときは下限の255にしておく
- }
- }
- //PD1Low:東日本50Hz限定最適化
- if(!(PIND & _BV(PIND1))){//PD1がLowであれば
- if(pwm0==255){//ポンプ液送りのためFull
- OCR0B = 2;//0にするとゼロクロス地点を超えてしまい波形が乱れる
- }
- else{//Top値と調整,ポンプを目的上7割以上で稼働しない前提
- //OCR0B = 70-(pwm0>>2);//50Hzフルスケール
- OCR0B = 70-(pwm0>>3);//50Hz60%程度基準
- //OCR0B = 70-(pwm0>>4);//50Hz40%程度基準
- }
- }
- //ACポンプ制御
- if((pwm0)&&(dmx_buf[1] >0x33)){ //ファンが20%(51:0x33)以上
- DDRD |= _BV(PD5); //ポートを出力に
- } else {
- DDRD &= ~_BV(PD5); //ポートを出力にしない
- }
- //二重反転ファン25kHzパルス制御
- //PB3吸込み側,PB4吐出側
- if (pwm1) { //0じゃなければ
- OCR1A = (pwm1)*5/4; //255*5/4=318.75<319
- DDRB |= _BV(PB3); //ポートを出力にする
- } else {
- DDRB &= ~_BV(PB3); //ポートを出力にしない
- }
- if (pwm1) { //0じゃなければ
- OCR1B = (pwm1)*5/4; //255*5/4=318.75<319
- DDRB |= _BV(PB4); //ポートを出力にする
- } else {
- DDRB &= ~_BV(PB4); //ポートを出力にしない
- }
- }
- }
Add Comment
Please, Sign In to add comment