Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*********************************************************
- 2313dmx_t0ovf_test_010 : DMX-Timer0 Overflow-ver1.0
- for ATtiny2313 (8MHz)
- at PCB :dmx-rec2313s ver2.0 late
- ただしダイオードをジャンパーに置き換え
- 入出力にプルダウン1kΩ追加必要
- main.c
- 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)
- DMX channel (base address + n)
- ch0: (PD5)ACPumpTriac
- ch1: (PWM1:PB3,PB4)25kHzPWMcontrolFAN
- ch0(ポンプ)は,ch1(ファン)が20%以上にならないと出力しない
- ch0は約1sec周期16段階の間欠出力
- ch1は山洋電気電気などPWM(5V)コントロール機能付きファン対応
- PD5:ACゼロクロスTriacへの出力
- PB3:二重反転ファン吸込側PWM(茶)25kHz:PB4と同期
- PB4:二重反転ファン吐出側PWM(白)25kHz:PB3と同期
- (PD1,PB2 reserve)
- 8MHz=0.000125ms=0.125µs
- #HighFuse 0xdf = 0b11011111
- #LowFuse 0xfc = 0b11111100
- Timer0のOVF割込みをカウントし周期を伸ばす
- 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が上限
- #define ON_TIME 8 //ポンプ間欠動作on_time
- volatile int j = 0;
- //volatileは常に更新される変数の場合
- //ループ内などで更新不要とコンパイラが判断すると最適化されたり
- //目的の挙動にならない可能性があるため最適化されないようにする
- /**TIMER0オーバーフロー割り込み**/
- //"dmx_recv.h"で"avr/interrupt.h"を読み込み済み
- //PD5のon,offTimeをメインループ外でカウントするための割込み
- ISR(TIMER0_OVF_vect){
- TCNT0 = 0; //Timerスタート位置変更によるカウント周期調整
- //on-offを1周期とする長さ
- //0:約1sec周期,128:約0.5sec周期,192:約0.25sec周期
- j++; //割り込みごとに1つカウントアップ
- }
- /**Timer0,1設定と初期化**/
- void init_timer (void) {
- /*8bitTimer0設定*/
- //通常動作によるTimer0オーバーフロー割り込み
- TCNT0 = 0;//カウンターリセット
- TCCR0B |= _BV(CS02) | _BV(CS00);//1024分周,カウンタースタート
- TIMSK |= _BV(TOIE0); //Timer/counter0溢れ割り込み許可(TOIE0)bit2
- /*16bitTimer1設定*/
- //高速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
- PORTB |= _BV(PB2);//reserve PullUp
- PORTD |= _BV(PD1);//reserve PullUp
- DDRB = 0x00; // 00000000 OutPutはmainでbit操作
- DDRD = 0x00; // 00000000 Outputはmainでbit操作
- DDRD |= _BV(PD5); //ポートを出力に
- }
- /*システムクロック変更初期化*/
- //出荷時のヒューズビットCKSEL=0100, SUT=10, CKDIV8=0
- void init_sysclk (void) {
- //標準でCKDIV8=0のため8分周(CLKPS3~0を0011に設定)してしまう
- //念のため分周なしに初期化
- CLKPR = _BV(CLKPCE);//クロック分周変更許可
- CLKPR = 0x00; //分周なしに変更
- }
- int main (void) {
- int i; //DMXスタートアドレス:9bit
- int a = 0;//PD5のon,ott_timeフラグ
- unsigned char on_time; //PD5先のトライアックon時間
- unsigned char off_time; //PD5先のトライアックoff時間
- unsigned char dmx_ch0 =0; //ch0のDMX値変化監視リセット
- unsigned char pwm1 = 0;
- volatile unsigned char *dmx_buf;
- /**デバイスを初期化**/
- init_sysclk();
- init_io();
- init_timer();
- /**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受信完了
- //PD5のon-off周期
- //Timer0割込みjカウントアップとの条件一致
- //dmx_buf[0]の8bit255段階では周期が長過ぎるため
- //上位5bitだけ使用することで16段階に粗くするため3bitシフト
- //最大値の0b11111111:255を3bitシフトすると,0b00011111:16となる
- on_time = ON_TIME; //ポンプオンタイム
- off_time = (255 - dmx_ch0) >> 3; //上位5bit
- //PB3,4の25kHzパルス制御
- pwm1 = dmx_buf[1];
- //ポンプACトライアック制御
- if(dmx_buf[1] < 0x33){ //ファンが20%(51:0x33)未満
- DDRD &= ~_BV(PD5); //ポートを出力にしない
- PORTD &= ~_BV(PD5); //ポートをLowに
- }else{
- if(dmx_ch0 == 0){
- DDRD &= ~_BV(PD5); //ポートを出力にしない
- PORTD &= ~_BV(PD5); //ポートをLowに
- dmx_ch0 = dmx_buf[0];//比較更新サンプリング
- j=0;
- a=0;
- }
- else if(dmx_ch0 == 255){
- DDRD |= _BV(PD5); //ポートを出力に
- PORTD |= _BV(PD5); //ポートをHighに
- dmx_ch0 = dmx_buf[0];//比較更新サンプリング
- j=0;
- a=0;
- }
- else if(dmx_ch0 < 255){
- if(!a){ //a==0
- DDRD |= _BV(PD5); //ポートを出力に
- PORTD |= _BV(PD5); //ポートをHighに
- if(j >= on_time){ //DMXで指定された
- dmx_ch0 = dmx_buf[0];//比較更新サンプリング
- j=0; //カウントリセット
- a=1; //フラグをoff_timeに
- }
- }
- if(a){ //a==1
- DDRD &= ~_BV(PD5); //ポートを出力にしない
- PORTD &= ~_BV(PD5); //ポートをLowに
- if(j >= off_time){
- dmx_ch0 = dmx_buf[0];//比較更新サンプリング
- j=0; //カウントリセット
- a=0; //フラグリセット
- }
- }
- }
- }
- //二重反転ファン25kHzパルス制御
- //PB3吸込み側
- if (pwm1) { //0じゃなければ
- OCR1A = (pwm1)*5/4; //255*5/4=318.75<319
- //最大値をICR1:319の近似値に調整
- DDRB |= _BV(PB3); //ポートを出力にする
- } else {
- DDRB &= ~_BV(PB3); //ポートを出力にしない
- }
- //PB4吐出側
- if (pwm1) { //0じゃなければ
- OCR1B = (pwm1)*5/4; //255*5/4=318.75<319
- //最大値をICR1:319の近似値に調整
- DDRB |= _BV(PB4); //ポートを出力にする
- } else {
- DDRB &= ~_BV(PB4); //ポートを出力にしない
- }
- }
- }
Add Comment
Please, Sign In to add comment