Guest User

Untitled

a guest
Jul 19th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.62 KB | None | 0 0
  1. /*********************************************************
  2. 2313dmx_t0ovf_test_010 : DMX-Timer0 Overflow-ver1.0
  3.  
  4. for ATtiny2313 (8MHz)
  5. at PCB :dmx-rec2313s ver2.0 late
  6. ただしダイオードをジャンパーに置き換え
  7. 入出力にプルダウン1kΩ追加必要
  8.  
  9. main.c
  10.  
  11. DMX base address
  12. Address 256 128 64 32 16 8 4 2 1
  13. i-bit 8 7 6 5 4 3 2 1 0
  14. PORT PB7 PB6 PB5 PB1 PB0 PD6 PD4 PD3 PD2
  15. (address=0 ==512ch)
  16.  
  17. DMX channel (base address + n)
  18. ch0: (PD5)ACPumpTriac
  19. ch1: (PWM1:PB3,PB4)25kHzPWMcontrolFAN
  20.  
  21. ch0(ポンプ)は,ch1(ファン)が20%以上にならないと出力しない
  22. ch0は約1sec周期16段階の間欠出力
  23. ch1は山洋電気電気などPWM(5V)コントロール機能付きファン対応
  24.  
  25. PD5:ACゼロクロスTriacへの出力
  26. PB3:二重反転ファン吸込側PWM(茶)25kHz:PB4と同期
  27. PB4:二重反転ファン吐出側PWM(白)25kHz:PB3と同期
  28.  
  29. (PD1,PB2 reserve)
  30.  
  31. 8MHz=0.000125ms=0.125µs
  32. #HighFuse 0xdf = 0b11011111
  33. #LowFuse 0xfc = 0b11111100
  34.  
  35.  Timer0のOVF割込みをカウントし周期を伸ばす
  36.  
  37. Created by Tsunehiro Oketani
  38. Copyright oketronics 2018 All rights reserved.
  39. *********************************************************/
  40.  
  41. #include <avr/io.h>
  42. #include "dmx_recv.h"
  43.  
  44. #define DMX_SIZE 2 //連続するDMX受信チャンネル数
  45. //"dmx_recv.h"のDMX_BUF_SIZEが上限
  46.  
  47. #define ON_TIME 8 //ポンプ間欠動作on_time
  48.  
  49. volatile int j = 0;
  50. //volatileは常に更新される変数の場合
  51. //ループ内などで更新不要とコンパイラが判断すると最適化されたり
  52. //目的の挙動にならない可能性があるため最適化されないようにする
  53.  
  54. /**TIMER0オーバーフロー割り込み**/
  55. //"dmx_recv.h"で"avr/interrupt.h"を読み込み済み
  56. //PD5のon,offTimeをメインループ外でカウントするための割込み
  57. ISR(TIMER0_OVF_vect){
  58. TCNT0 = 0; //Timerスタート位置変更によるカウント周期調整
  59. //on-offを1周期とする長さ
  60. //0:約1sec周期,128:約0.5sec周期,192:約0.25sec周期
  61. j++; //割り込みごとに1つカウントアップ
  62. }
  63.  
  64. /**Timer0,1設定と初期化**/
  65. void init_timer (void) {
  66.  
  67. /*8bitTimer0設定*/
  68. //通常動作によるTimer0オーバーフロー割り込み
  69. TCNT0 = 0;//カウンターリセット
  70. TCCR0B |= _BV(CS02) | _BV(CS00);//1024分周,カウンタースタート
  71. TIMSK |= _BV(TOIE0); //Timer/counter0溢れ割り込み許可(TOIE0)bit2
  72.  
  73. /*16bitTimer1設定*/
  74. //高速PWM(DCファン制御25kHzPWM)
  75. //Timer1カウンター,比較レジスタをリセット
  76. TCNT1 = 0;
  77. OCR1A = 0;
  78. OCR1B = 0;
  79.  
  80. //高速PWM動作,Top値ICR1
  81. TCCR1B |= _BV(WGM12) | _BV(WGM13);
  82. TCCR1A |= _BV(WGM11);
  83.  
  84. //比較一致でLow、BOTTOMでHighをOC1A,OC1Bへ出力(非反転動作)
  85. TCCR1A |= _BV(COM1A1) | _BV(COM1B1);
  86.  
  87. //Top値
  88. ICR1 = 0x013f; //320=0x140,319=0x013f
  89. //(システムクロック8MHz分周なし)/(2*TCNT1分周*TOP値320)=12.5kHz
  90. //ノコギリ波割込み反転周期12.5kHz
  91. //OCR1A,OCR1B比較一致による周期25kHz
  92. //オシロ実測で25kHzに調整,ICR1=319=0x013f
  93.  
  94. //TCNT1クロック分周
  95. TCCR1B |= _BV(CS10);//分周なし,カウンタースタート
  96. }
  97.  
  98. /*IOポート初期化*/
  99. void init_io (void) {
  100. PORTA = 0x03; // 00000011 PA0,PA1 PullUp
  101. PORTB = 0xe3; // 11100011 PB0,1,5,6,7 PullUp
  102. PORTD = 0x5c; // 01011100 PD2,3,4,6 PullUp
  103. PORTB |= _BV(PB2);//reserve PullUp
  104. PORTD |= _BV(PD1);//reserve PullUp
  105. DDRB = 0x00; // 00000000 OutPutはmainでbit操作
  106. DDRD = 0x00; // 00000000 Outputはmainでbit操作
  107. DDRD |= _BV(PD5); //ポートを出力に
  108. }
  109.  
  110. /*システムクロック変更初期化*/
  111. //出荷時のヒューズビットCKSEL=0100, SUT=10, CKDIV8=0
  112. void init_sysclk (void) {
  113. //標準でCKDIV8=0のため8分周(CLKPS3~0を0011に設定)してしまう
  114. //念のため分周なしに初期化
  115. CLKPR = _BV(CLKPCE);//クロック分周変更許可
  116. CLKPR = 0x00; //分周なしに変更
  117. }
  118.  
  119. int main (void) {
  120. int i; //DMXスタートアドレス:9bit
  121. int a = 0;//PD5のon,ott_timeフラグ
  122.  
  123. unsigned char on_time; //PD5先のトライアックon時間
  124. unsigned char off_time; //PD5先のトライアックoff時間
  125. unsigned char dmx_ch0 =0; //ch0のDMX値変化監視リセット
  126. unsigned char pwm1 = 0;
  127. volatile unsigned char *dmx_buf;
  128.  
  129. /**デバイスを初期化**/
  130. init_sysclk();
  131. init_io();
  132. init_timer();
  133.  
  134. /**DMX base address**/
  135. //DipSWなどでIOポートのLowを数える
  136. //Address 256 128 64 32 16 8 4 2 1
  137. //i-bit 8 7 6 5 4 3 2 1 0
  138. //PORT PB7 PB6 PB5 PB1 PB0 PD6 PD4 PD3 PD2
  139. i = ((~PIND & 0x1c) >> 2); //0b00011100:PD4,3,2 :i-bit2,1,0
  140. i |= ((~PIND & 0x40) >> 3); //0b01000000:PD6 :i-bit3
  141. i |= ((~PINB & 0x03) << 4); //0b00000011:PB1,0 :i-bit5,4
  142. i |= ((~PINB & 0xe0) << 1); //0b11100000:PB7,6,5 :i-bit8,7,6
  143.  
  144. //処理中"dmx_recv.c"のdmx_ch値は0~511
  145. //dmx_buf[i-1]
  146. if (i) { //IOポートを2進法で数える
  147. dmx_buf = init_dmx(i - 1, DMX_SIZE);
  148. //"dmx_recv.c"のUSART初期化へ
  149. //"i-1"はchに、"DMX_SIZE"はsizeに
  150. }
  151. else if (!i) { //IOポートに入力がない場合512ch
  152. dmx_buf = init_dmx(512 - 1, DMX_SIZE);
  153. }
  154.  
  155. sei(); //デバイス初期化、ポート読み込み終わったので割り込みを許可
  156.  
  157. /*メインループ*/
  158. while (1) {
  159. wait_dmx(); //DMX受信完了
  160.  
  161. //PD5のon-off周期
  162. //Timer0割込みjカウントアップとの条件一致
  163. //dmx_buf[0]の8bit255段階では周期が長過ぎるため
  164. //上位5bitだけ使用することで16段階に粗くするため3bitシフト
  165. //最大値の0b11111111:255を3bitシフトすると,0b00011111:16となる
  166. on_time = ON_TIME; //ポンプオンタイム
  167. off_time = (255 - dmx_ch0) >> 3; //上位5bit
  168.  
  169. //PB3,4の25kHzパルス制御
  170. pwm1 = dmx_buf[1];
  171.  
  172. //ポンプACトライアック制御
  173.  
  174. if(dmx_buf[1] < 0x33){ //ファンが20%(51:0x33)未満
  175. DDRD &= ~_BV(PD5); //ポートを出力にしない
  176. PORTD &= ~_BV(PD5); //ポートをLowに
  177. }else{
  178. if(dmx_ch0 == 0){
  179. DDRD &= ~_BV(PD5); //ポートを出力にしない
  180. PORTD &= ~_BV(PD5); //ポートをLowに
  181. dmx_ch0 = dmx_buf[0];//比較更新サンプリング
  182. j=0;
  183. a=0;
  184. }
  185. else if(dmx_ch0 == 255){
  186. DDRD |= _BV(PD5); //ポートを出力に
  187. PORTD |= _BV(PD5); //ポートをHighに
  188. dmx_ch0 = dmx_buf[0];//比較更新サンプリング
  189. j=0;
  190. a=0;
  191. }
  192.  
  193. else if(dmx_ch0 < 255){
  194. if(!a){ //a==0
  195. DDRD |= _BV(PD5); //ポートを出力に
  196. PORTD |= _BV(PD5); //ポートをHighに
  197. if(j >= on_time){ //DMXで指定された
  198. dmx_ch0 = dmx_buf[0];//比較更新サンプリング
  199. j=0; //カウントリセット
  200. a=1; //フラグをoff_timeに
  201. }
  202. }
  203. if(a){ //a==1
  204. DDRD &= ~_BV(PD5); //ポートを出力にしない
  205. PORTD &= ~_BV(PD5); //ポートをLowに
  206. if(j >= off_time){
  207. dmx_ch0 = dmx_buf[0];//比較更新サンプリング
  208. j=0; //カウントリセット
  209. a=0; //フラグリセット
  210. }
  211. }
  212. }
  213. }
  214.  
  215. //二重反転ファン25kHzパルス制御
  216. //PB3吸込み側
  217. if (pwm1) { //0じゃなければ
  218. OCR1A = (pwm1)*5/4; //255*5/4=318.75<319
  219. //最大値をICR1:319の近似値に調整
  220. DDRB |= _BV(PB3); //ポートを出力にする
  221. } else {
  222. DDRB &= ~_BV(PB3); //ポートを出力にしない
  223. }
  224. //PB4吐出側
  225. if (pwm1) { //0じゃなければ
  226. OCR1B = (pwm1)*5/4; //255*5/4=318.75<319
  227. //最大値をICR1:319の近似値に調整
  228. DDRB |= _BV(PB4); //ポートを出力にする
  229. } else {
  230. DDRB &= ~_BV(PB4); //ポートを出力にしない
  231. }
  232. }
  233. }
Add Comment
Please, Sign In to add comment