Guest User

Untitled

a guest
Jul 22nd, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.41 KB | None | 0 0
  1. /*********************************************************
  2. 2313dmx_hzsync_test_001 : DMX HzSynchronize test ver0.1
  3.  
  4. for ATtiny2313 (8MHz)
  5. at PCB :dmx-rec2313s ver2.0 late
  6. ただしダイオードをジャンパーに置き換え
  7. 入出力にプルダウン追加必要
  8.  
  9. main.c
  10.  
  11. DMX512 4ch DIMMER
  12. DMX channel (base address + n)
  13. 0ch: (PWM0:PD5)ACPumpTriac
  14. 1ch: (PWM1:PB3,PB4)25kHzPWMcontrolFAN
  15.  
  16. DMX base address
  17. Address 256 128 64 32 16 8 4 2 1
  18. i-bit 8 7 6 5 4 3 2 1 0
  19. PORT PB7 PB6 PB5 PB1 PB0 PD6 PD4 PD3 PD2
  20. (address=0 =>512ch)
  21.  
  22. 8MHz=0.000125ms=0.125µs
  23.  
  24. PB2:ACゼロクロストリガー入力:0.5ms=500µs
  25. PD5:AC非ゼロクロストリガー出力
  26. PB3:二重反転ファン吸込側PWM(茶)25kHz:PB4と同期
  27. PB4:二重反転ファン吐出側PWM(白)25kHz:PB3と同期
  28.  
  29. PD1:PD1PullUp(H:60Hz/L:50Hz)
  30.  
  31. #HighFuse 0xdf = 0b11011111
  32. #LowFuse 0xfc = 0b11111100
  33.  
  34. v0.1 20180721
  35.  
  36. Created by Tsunehiro Oketani
  37. Copyright oketronics 2018 All rights reserved.
  38. *********************************************************/
  39.  
  40. #include <avr/io.h>
  41. #include "dmx_recv.h"
  42.  
  43. #define DMX_SIZE 2 //連続するDMX受信チャンネル数
  44. //"dmx_recv.h"のDMX_BUF_SIZEが上限
  45.  
  46. static volatile int a; //a:ゼロクロス検出フラグ
  47. //staticは記述されたファイル内でのみ使用が制限される変数,0に初期化される
  48. //volatileは常に更新される変数,最適化による消失防止
  49.  
  50. /**ゼロクロス検出**/
  51. //AC100Vのゼロクロスを検出しPB2にHigh入力
  52. //優先順位がUSARTRX割込みより低いピン変化割込み
  53. ISR(PCINT_vect){
  54. if(!a){ //a == 0,次のゼロクロス入力待機
  55. if(PINB & _BV(PINB2)){ //PB2にゼロクロスHigh入力があったら
  56. //TCNT0 = 0; //Timer0カウントをリセット
  57. a=1; //検出中
  58. }
  59. }
  60.  
  61. if(a){ //a == 1,ゼロクロス検出中
  62. //Timer0スタート時(PD5出力時)に確実に0Vを超えているように
  63. //ゼロクロスをフォトトライアックが検出中はTimer0を停止しておく
  64. if(PINB & _BV(PINB2)){
  65. TCNT0 = 0; //Timer0カウントをリセット
  66. //a = 1;
  67. }
  68. //else {a = 0;}
  69. }
  70.  
  71. if(!(PINB & _BV(PINB2))){
  72. a = 0;
  73. }
  74.  
  75. }
  76.  
  77.  
  78. /**PWM出力のための設定と初期化**/
  79. void init_pwm (void) {
  80.  
  81. /*8bit高速PWM(ACポンプ制御フォトトライアック)*/
  82. //Timer0カウンター、比較レジスタを初期化
  83. TCNT0 = 0;
  84. OCR0A = 0;
  85. OCR0B = 0;
  86.  
  87. //高速PWM動作,TOP値COR0A
  88. TCCR0B |= _BV(WGM02);
  89. TCCR0A |= _BV(WGM01) | _BV(WGM00);
  90.  
  91. //比較一致でHigh、BOTTOMでLowをOC0Bへ出力(反転動作)
  92. TCCR0A |= _BV(COM1B0) | _BV(COM1B1);
  93.  
  94. ////Timer0:AC50Hzおよび60Hz同期////
  95. //クロック周波数/(タイマー分周*TOP値COR0A)=AC半波
  96.  
  97. //PD1High(PullUp):西日本60Hz設定
  98. //8,000,000 / (256 * COR0A) = (60 x 2)の近似値
  99. if(PIND & _BV(PIND1)){ //PD1がHighであれば
  100. TCCR0B |= _BV(CS02); //8MHz/256分周=31250Hz
  101. OCR0A = 0xf0; //240:0xf0:130.2Hz
  102. }
  103.  
  104. //PD1Low:東日本50Hz設定
  105. //8,000,000 / (1024 * COR0A) = (50 x 2)の近似値
  106. if(!(PIND & _BV(PIND1))){//PD1がLowであれば
  107. TCCR0B |= _BV(CS02) | _BV(CS00);//8MHz/1024分周=7812.5Hz
  108. OCR0A = 0x4d; //東日本50HzのOCR0A値(77=78-1:0x4d:100.17Hz)
  109. }
  110.  
  111.  
  112.  
  113. /*16bit高速PWM(DCファン制御25kHzPWM)*/
  114. //Timer1カウンター、比較レジスタを初期化
  115. TCNT1 = 0;
  116. OCR1A = 0;
  117. OCR1B = 0;
  118.  
  119. //高速PWM動作,Top値ICR1
  120. TCCR1B |= _BV(WGM12) | _BV(WGM13);
  121. TCCR1A |= _BV(WGM11);
  122.  
  123. //比較一致でLow、BOTTOMでHighをOC1A,OC1Bへ出力(非反転動作)
  124. TCCR1A |= _BV(COM1A1) | _BV(COM1B1);
  125.  
  126. //Top値
  127. ICR1 = 0x013f; //320=0x140,319=0x013f
  128. //(システムクロック8MHz分周なし)/(2*TCNT1分周*TOP値320)=12.5kHz
  129. //ノコギリ波割込み反転周期12.5kHz
  130. //OCR1A,OCR1B比較一致による周期25kHz
  131. //オシロ実測で25kHzに調整,ICR1=319=0x013f
  132.  
  133. //TCNT1クロック分周なし
  134. TCCR1B |= _BV(CS10);
  135. }
  136.  
  137. /*IOポート初期化*/
  138. void init_io (void) {
  139. PORTA = 0x03; // 00000011 PA0,PA1 PullUp
  140. PORTB = 0xe3; // 11100011 PB0,1,5,6,7 PullUp
  141. PORTD = 0x5c; // 01011100 PD2,3,4,6 PullUp
  142. PORTD|= _BV(PD1); //PD1 PullUp 50/60Hz切り替え
  143. DDRB = 0x00; // 00000000 PB3~4 はmainでbit操作
  144. DDRD = 0x00; // 00000000 PD1,5 はmainでbit操作
  145. }
  146.  
  147. /*システムクロック変更初期化*/
  148. //出荷時のヒューズビットCKSEL=0100, SUT=10, CKDIV8=0
  149. void init_sysclk (void) {
  150. //標準でCKDIV8=0のため8分周(CLKPS3~0を0011に設定)してしまう
  151. //念のため分周なしに初期化
  152. CLKPR = _BV(CLKPCE);//クロック分周変更許可
  153. CLKPR = 0x00; //分周なしに変更
  154. }
  155.  
  156. /*ピン変化割込み初期化*/
  157. //AC100Vのゼロクロス付近のHighトリガーをPB2に入力
  158. //PB2のピン変化0群について割込み許可設定
  159. void init_pin_int (void) {
  160. GIMSK |= _BV(PCIE); //一般割り込み許可レジスタ,ピン変化0群割り込み許可(PCIE)bit5
  161. PCMSK |= _BV(PCINT2); //ピン変化0群割り込み許可レジスタ,個別PB2を許可(PCINT2)bit2
  162. }
  163.  
  164. int main (void) {
  165. int i; //i:アドレスに関連
  166.  
  167. unsigned char pwm0 = 0;
  168. unsigned char pwm1 = 0;
  169. volatile unsigned char *dmx_buf;
  170.  
  171. /**デバイスを初期化**/
  172. init_sysclk();
  173. init_io();
  174. init_pwm();
  175. init_pin_int();
  176.  
  177. /**DMX base address**/
  178. //DipSWなどでIOポートのLowを数える
  179. //Address 256 128 64 32 16 8 4 2 1
  180. //i-bit 8 7 6 5 4 3 2 1 0
  181. //PORT PB7 PB6 PB5 PB1 PB0 PD6 PD4 PD3 PD2
  182. i = ((~PIND & 0x1c) >> 2); //0b00011100:PD4,3,2 :i-bit2,1,0
  183. i |= ((~PIND & 0x40) >> 3); //0b01000000:PD6 :i-bit3
  184. i |= ((~PINB & 0x03) << 4); //0b00000011:PB1,0 :i-bit5,4
  185. i |= ((~PINB & 0xe0) << 1); //0b11100000:PB7,6,5 :i-bit8,7,6
  186.  
  187. //処理中"dmx_recv.c"のdmx_ch値は0~511
  188. //dmx_buf[i-1]
  189. if (i) { //IOポートを2進法で数える
  190. dmx_buf = init_dmx(i - 1, DMX_SIZE);
  191. //"dmx_recv.c"のUSART初期化へ
  192. //"i-1"はchに、"DMX_SIZE"はsizeに
  193. }
  194. else if (!i) { //IOポートに入力がない場合512ch
  195. dmx_buf = init_dmx(512 - 1, DMX_SIZE);
  196. }
  197.  
  198. sei(); //デバイス初期化、ポート読み込み終わったので割り込みを許可
  199.  
  200. /*メインループ*/
  201. while (1) {
  202. wait_dmx(); //DMX受信完了
  203.  
  204. pwm0 = dmx_buf[0];
  205. pwm1 = dmx_buf[1];
  206.  
  207. //PD1High(PullUp):西日本60Hz設定
  208. if(PIND & _BV(PIND1)){ //PD1がHighであれば
  209. if(pwm0 >=25){//pwm0が25以上になったとき
  210. OCR0B = 280 - (pwm0);//Top値と調整
  211. }
  212. else{ //pwm0が25未満のとき
  213. OCR0B = 255;//
  214. //クロック分周の制約上120Hzのところ130Hzなので超過する値を調整
  215. //8bitのOCR0Bとpwm0の値を反転させているので、
  216. //pwm0=25のとき,280-25=255で下限
  217. //pwmが25未満のときは下限の255にしておく
  218. }
  219. }
  220.  
  221. //PD1Low:東日本50Hz設定
  222. if(!(PIND & _BV(PIND1))){//PD1がLowであれば
  223. OCR0B = 70-(pwm0>>2);//Top値と調整
  224. }
  225.  
  226.  
  227. //ACポンプ制御
  228. if((pwm0)&&(dmx_buf[1] >0x33)){ //ファンが20%(51:0x33)以上
  229. DDRD |= _BV(PD5); //ポートを出力に
  230. } else {
  231. DDRD &= ~_BV(PD5); //ポートを出力にしない
  232. }
  233.  
  234. //二重反転ファン25kHzパルス制御
  235. //PB3吸込み側,PB4吐出側
  236. if (pwm1) { //0じゃなければ
  237. OCR1A = (pwm1)*5/4; //255*5/4=318.75<319
  238. DDRB |= _BV(PB3); //ポートを出力にする
  239. } else {
  240. DDRB &= ~_BV(PB3); //ポートを出力にしない
  241. }
  242. if (pwm1) { //0じゃなければ
  243. OCR1B = (pwm1)*5/4; //255*5/4=318.75<319
  244. DDRB |= _BV(PB4); //ポートを出力にする
  245. } else {
  246. DDRB &= ~_BV(PB4); //ポートを出力にしない
  247. }
  248. }
  249.  
  250. }
Add Comment
Please, Sign In to add comment