5iMX宗旨:分享遥控模型兴趣爱好

5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年)
查看: 17992|回复: 26
打印 上一主题 下一主题

做了个无刷电调(附原理图和程序)

[复制链接]
跳转到指定楼层
楼主
发表于 2008-12-22 19:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ttt.rar (127.33 KB, 下载次数: 1110) 控制用一片Amega8l控制,电流输出用IRF640和IRF9640,用电位器控制转速,图为控制硬盘电机.
纯属好玩.










[ 本帖最后由 zhxzsh 于 2008-12-23 20:32 编辑 ]

评分

参与人数 1威望 +2 收起 理由
论坛老模友 + 2 精品文章,感谢分享!

查看全部评分

欢迎继续阅读楼主其他信息

沙发
发表于 2008-12-22 19:47 | 只看该作者
还你厉害
3
发表于 2008-12-22 20:32 | 只看该作者
可否上电路来让后辈学习学习。
4
发表于 2008-12-22 21:28 | 只看该作者
可否上电路学习学习。
5
发表于 2008-12-22 21:55 | 只看该作者
可否上电路学习学习    支持楼主
6
发表于 2008-12-22 22:11 | 只看该作者
关注学习贴!~    支持LZ上电路图   家里的废弃硬盘很多
7
发表于 2008-12-23 00:38 | 只看该作者
强人 羡慕啊 给我电路图我也搞不定
8
发表于 2008-12-24 19:43 | 只看该作者
不错,支持!楼主勤俭持家啊,电阻的脚留的挺长,剪下来还可以用。:loveliness:
你用什么软件啊,有几个文件打不开?

[ 本帖最后由 驼铃 于 2008-12-24 19:46 编辑 ]
9
发表于 2008-12-25 12:34 | 只看该作者
牛 ....
10
发表于 2008-12-25 14:04 | 只看该作者
改自德国人的设计,由PPM 控制转速改为电位器控制。
11
发表于 2008-12-25 14:06 | 只看该作者
原电路图

fblmc01_sch.jpg (80.33 KB, 下载次数: 144)

fblmc01_sch.jpg
12
发表于 2008-12-25 14:11 | 只看该作者

原始代码 -第1部分

  1. ;**** **** **** **** ****
  2. ;
  3. ;Die Benutzung der Software ist mit folgenden Bedin×gen verbunden:
  4. ;
  5. ;1. Da ich alles kostenlos zur Verfü×g stelle, gebe ich keinerlei Garantie
  6. ;   und übernehme auch keinerlei Haftung für die Folgen der Benutzung.
  7. ;
  8. ;2. Die Software ist ausschließlich zur privaten Nutzung bestimmt. Ich
  9. ;   habe nicht geprüft, ob bei gewerblicher Nutzung irgendwelche Patentrechte
  10. ;   verletzt werden oder sonstige rechtliche Einschränkungen vorliegen.
  11. ;
  12. ;3. Jeder darf Änderungen vornehmen, z.B. um die Funktion seinen Bedürfnissen
  13. ;   anzupassen oder zu erweitern. Ich würde mich freuen, wenn ich weiterhin als
  14. ;   Co-Autor in den Unterlagen erscheine und mir ein Link zur entprechenden Seite
  15. ;   (falls vorhanden) mitgeteilt wird.
  16. ;
  17. ;4. Auch nach den Änderungen sollen die Software weiterhin frei sein, d.h. kostenlos bleiben.
  18. ;
  19. ;!! Wer mit den Nutzungbedin×gen nicht einverstanden ist, darf die Software nicht nutzen !!
  20. ;
  21. ; October 2004
  22. ; autor: Bernhard Konze
  23. ; email: bernhard.konze(at)versanet.de
  24. ;
  25. ;**** **** **** **** ****
  26. ; Device
  27. ;
  28. ;**** **** **** **** ****
  29. .include "m8def.inc"
  30. ;
  31. ;**** **** **** **** ****
  32. ;**** **** **** **** ****
  33. ; fuses must be set to internal calibrated oscillator = 8 mhz
  34. ;**** **** **** **** ****
  35. ;**** **** **** **** ****

  36. .equ UART_CONTROL = 1
  37. .equ UART_FULL          = 1
  38. .equ RC_PULS           = 0

  39. .include "flea.inc"

  40. .equ        CHANGE_TIMEOUT        = 0x32
  41. .equ        CHANGE_TOT_LOW        = 0x28

  42. .equ        POWER_RANGE        = 100                        ; full range of tcnt0 setting
  43. .equ        MIN_DUTY        = 10                        ; no power
  44. .equ        NO_POWER        = 256-MIN_DUTY                ; (POWER_OFF)
  45. .equ        MAX_POWER        = 256-POWER_RANGE        ; (FULL_POWER)

  46. .equ        defaultTIMEOUT        = 32000
  47. .equ        compScanTIMEOUT        = 48000

  48. .equ        T1STOP        = 0x00
  49. .equ        T1CK8        = 0x02

  50. .equ        EXT0_DIS        = 0x00        ; disable ext0int
  51. .if RC_PULS == 1
  52. .equ        EXT0_EN                = 0x40        ; enable ext0int
  53. .else
  54. .equ        EXT0_EN                = 0x00        ; disable ext0int
  55. .endif

  56. .equ        MIN_RC_PULS        = 1100                        ; µs (or lower) = NO_POWER


  57. ;**** **** **** **** ****
  58. ; Register Definitions
  59. .def        i_sreg                 = r1        ; status register save in interrupts
  60. .def        tcnt0_power_on         = r2        ; timer0 counts nFETs are switched on
  61. .def        tcnt0_change_tot = r3        ; when zero, tcnt0_power_on is changed by one (inc or dec)
  62. .def        TCNT1X                  = r4        ; upper 8bit timer1 (software-) register
  63. .def        uart_cnt         = r5
  64. .def        tcnt0_pwron_next = r6

  65. .def        start_rcpuls_l         = r7
  66. .def        start_rcpuls_h         = r8
  67. .def        new_rcpuls_l         = r9
  68. .def        new_rcpuls_h         = r10
  69. .def        rcpuls_timeout         = r11
  70. .equ        RCP_TOT                 = 100

  71. .def        current_err         = r12        ; counts consecutive current errors
  72. .equ        CURRENT_ERR_MAX  = 3        ; performs a reset after MAX errors

  73. .def        sys_control         = r13


  74. .def        temp1        = r16                        ; main temporary
  75. .def        temp2        = r17                        ; main temporary
  76. .def        temp3        = r18                        ; main temporary
  77. .def        temp4        = r19                        ; main temporary

  78. .def        i_temp1        = r20                        ; interrupt temporary
  79. .def        i_temp2        = r21                        ; interrupt temporary
  80. .def        i_temp3        = r22                        ; interrupt temporary

  81. .def        state0        = r23        ; state flags
  82.         .equ        OCT1_PENDING        = 0        ; if set, output compare interrunpt is pending
  83.         .equ        UB_LOW                 = 1        ; set if accu voltage low
  84.         .equ        I_pFET_HIGH        = 2        ; set if over-current detect
  85.         .equ        GET_STATE        = 3        ; set if state is to be send
  86.         .equ        C_FET                = 4        ; if set, C-FET state is to be changed
  87.         .equ        A_FET                = 5        ; if set, A-FET state is to be changed
  88.              ; if neither 1 nor 2 is set, B-FET state is to be changed
  89.         .equ        I_OFF_CYCLE        = 6        ; if set, current off cycle is active
  90.         .equ        EVAL_UB                = 7        ; if set, next PWM on should look for power

  91. .def        state1        = r24        ; state flags
  92.         .equ        POWER_OFF        = 0        ; switch fets on disabled
  93.         .equ        FULL_POWER        = 1        ; 100% on - don't switch off, but do OFF_CYCLE working
  94.         .equ        CALC_NEXT_OCT1        = 2        ; calculate OCT1 offset, when wait_OCT1_before_switch is called
  95.         .equ        RC_PULS_UPDATED        = 3        ; new rc-puls value available
  96.         .equ        EVAL_RC_PULS        = 4        ; if set, new rc puls is evaluated, while waiting for OCT1
  97.         .equ        EVAL_SYS_STATE        = 5        ; if set, overcurrent and undervoltage are checked
  98.         .equ        EVAL_I_pFET        = 6        ; if set, next PWM on should look for current
  99.         .equ        T1OVFL_FLAG        = 7        ; each timer1 overflow sets this flag - used for voltage + current watch

  100. ;rfu        .def        yyy        r25


  101. ; here the XYZ registers are placed ( r26-r31)

  102. ; ZH = new_duty                ; PWM destination


  103. ;**** **** **** **** ****
  104. ; RAM Definitions

  105. .equ        tcnt1_sav_l        = 0x0060        ; actual 24-bit timer1 value
  106. .equ        tcnt1_sav_h        = 0x0061
  107. .equ        tcnt1_sav_x        = 0x0062
  108. .equ        last_tcnt1_l        = 0x0063        ; last 24-bit timer1 value
  109. .equ        last_tcnt1_h        = 0x0064
  110. .equ        last_tcnt1_x        = 0x0065

  111. .equ        wt_comp_scan_l        = 0x0066        ; time from switch to comparator scan
  112. .equ        wt_comp_scan_h        = 0x0067
  113. .equ        wt_FET_switch_l        = 0x0068        ; time from zero-crossing to switch of the appropriate FET
  114. .equ        wt_FET_switch_h        = 0x0069

  115. .equ        OCT1_high        = 0x006a

  116. .equ        uart_data        = 0x0070        ; only for debug requirements


  117. ;**** **** **** **** ****
  118. ; ATmega8 interrupts

  119. ;.equ        INT0addr=$001        ; External Interrupt0 Vector Address
  120. ;.equ        INT1addr=$002        ; External Interrupt1 Vector Address
  121. ;.equ        OC2addr =$003        ; Output Compare2 Interrupt Vector Address
  122. ;.equ        OVF2addr=$004        ; Overflow2 Interrupt Vector Address
  123. ;.equ        ICP1addr=$005        ; Input Capture1 Interrupt Vector Address
  124. ;.equ        OC1Aaddr=$006        ; Output Compare1A Interrupt Vector Address
  125. ;.equ        OC1Baddr=$007        ; Output Compare1B Interrupt Vector Address
  126. ;.equ        OVF1addr=$008        ; Overflow1 Interrupt Vector Address
  127. ;.equ        OVF0addr=$009        ; Overflow0 Interrupt Vector Address
  128. ;.equ        SPIaddr =$00a        ; SPI Interrupt Vector Address
  129. ;.equ        URXCaddr=$00b        ; USART Receive Complete Interrupt Vector Address
  130. ;.equ        UDREaddr=$00c        ; USART Data Register Empty Interrupt Vector Address
  131. ;.equ        UTXCaddr=$00d        ; USART Transmit Complete Interrupt Vector Address
  132. ;.equ        ADCCaddr=$00e        ; ADC Interrupt Vector Address
  133. ;.equ        ERDYaddr=$00f        ; EEPROM Interrupt Vector Address
  134. ;.equ        ACIaddr =$010        ; Analog Comparator Interrupt Vector Address
  135. ;.equ        TWIaddr =$011        ; Irq. vector address for Two-Wire Interface
  136. ;.equ        SPMaddr =$012        ; SPM complete Interrupt Vector Address
  137. ;.equ        SPMRaddr =$012        ; SPM complete Interrupt Vector Address
  138. ;-----bko-----------------------------------------------------------------

  139. ;**** **** **** **** ****
  140. .cseg
  141. .org 0
  142. ;**** **** **** **** ****

  143. ;-----bko-----------------------------------------------------------------
  144. ; reset and interrupt jump table
  145.                 rjmp        reset
  146. .if RC_PULS == 1
  147.                 rjmp        ext_int0
  148. .else
  149.                 nop        ; int0
  150. .endif
  151.                 nop        ; ext_int1
  152.                 nop        ; t2oc_int
  153.                 nop        ; t2ovfl_int
  154.                 nop        ; icp1
  155.                 rjmp        t1oca_int
  156.                 nop        ; t1ocb_int
  157.                 rjmp        t1ovfl_int
  158.                 rjmp        t0ovfl_int
  159.                 nop        ; spi_int
  160.                 nop        ; urxc
  161.                 nop        ; udre
  162. .if UART_CONTROL == 1
  163.   .if UART_FULL == 1
  164.                 rjmp        utxc
  165.   .else
  166.                 nop        ; utxc
  167.   .endif
  168. .else
  169.                 nop        ; utxc
  170. .endif
  171. ; not used        nop        ; adc_int
  172. ; not used        nop        ; eep_int
  173. ; not used        nop        ; aci_int
  174. ; not used        nop        ; wire2_int
  175. ; not used        nop        ; spmc_int


  176. version:        .db        "bkf101"


  177. ;-----bko-----------------------------------------------------------------
  178. ; init after reset

  179. reset:                ldi        temp1, high(RAMEND)        ; stack = RAMEND
  180.                 out        SPH, temp1
  181.                 ldi        temp1, low(RAMEND)
  182.                 out         SPL, temp1

  183.         ; portB - all FETs off
  184.                 ldi        temp1, INIT_PB                ; PORTB initially holds 0x00
  185.                 out        PORTB, temp1
  186.                 ldi        temp1, DIR_PB
  187.                 out        DDRB, temp1

  188.         ; portC reads comparator inputs
  189.                 ldi        temp1, INIT_PC
  190.                 out        PORTD, temp1
  191.                 ldi        temp1, DIR_PC
  192.                 out        DDRD, temp1

  193.         ; portD reads rc-puls + AIN0 ( + RxD, TxD for debug )
  194.                 ldi        temp1, INIT_PD
  195.                 out        PORTD, temp1
  196.                 ldi        temp1, DIR_PD
  197.                 out        DDRD, temp1

  198.         ; timer0: PWM + beep control = 0x02         ; start timer0 with CK/8 (1µs/count)
  199.                 ldi        temp1, 0x02
  200.                 out        TCCR0, temp1

  201.         ; timer1: commutation control = 0x02        ; start timer1 with CK/8 (1µs/count)
  202.                 ldi        temp1, T1CK8
  203.                 out        TCCR1B, temp1

  204.         ; reset state flags
  205.                 clr        state0
  206.                 clr        state1

  207.         ; power off
  208.                 rcall        switch_power_off

  209.         ; reset rc puls timeout
  210.                 ldi        temp1, RCP_TOT
  211.                 mov        rcpuls_timeout, temp1
  212.                
  213. .if UART_CONTROL == 1

  214.                 ldi        ZH,high(version*2)
  215.                 ldi        ZL,low(version*2)

  216.         ;**** UART Initialization ****
  217.                 ldi        temp1, 0        ; set to 38400baud (8MHz)
  218.                 out        UBRRH, temp1
  219.                 ldi        temp1, 12
  220.                 out        UBRRL, temp1
  221.                 ldi        temp1, 0x18
  222.                 out        UCSRB, temp1        ; enable rx+tx - no interrupts !
  223.                 in         temp1, UDR        ; clear possibly pending rxc

  224.                 lpm
  225.                 adiw        ZL,1                ;increment Z-pointer
  226.                 mov        temp1, r0        ; b
  227.                 rcall        send_byte
  228. .endif
  229.                 rcall        wait260ms        ; wait a while
  230.                 rcall        wait260ms

  231. .if UART_CONTROL == 1
  232.                 lpm
  233.                 adiw        ZL,1                ;increment Z-pointer
  234.                 mov        temp1, r0        ; k
  235.                 rcall        send_byte
  236. .endif
复制代码
13
发表于 2008-12-25 14:12 | 只看该作者

第2部分

  1.                 rcall        beep328ms        ; signal ready

  2. .if UART_CONTROL == 1
  3.                 lpm
  4.                 adiw        ZL,1                ;increment Z-pointer
  5.                 mov        temp1, r0        ; o
  6.                 rcall        send_byte
  7.                 lpm
  8.                 adiw        ZL,1                ;increment Z-pointer
  9.                 mov        temp1, r0        ; (1st number)
  10.                 rcall        send_byte
  11. .endif

  12. control_start:        ; init variables
  13.                 ldi        temp1, CHANGE_TIMEOUT
  14.                 mov        tcnt0_change_tot, temp1
  15.                 ldi        temp1, NO_POWER
  16.                 mov        tcnt0_power_on, temp1

  17.                 ldi        temp1, 0                ; reset error counters
  18.                 mov        current_err,temp1
  19.                 mov        sys_control, temp1

  20.         ; init registers and interrupts
  21.                 ldi        temp1, (1<<<
  22.                 out        TIFR, temp1                ; clear TOIE1,OCIE1A & TOIE0
  23.                 out        TIMSK, temp1                ; enable TOIE1,OCIE1A & TOIE0 interrupts

  24. .if UART_CONTROL == 1
  25.                 lpm
  26.                 adiw        ZL,1                ;increment Z-pointer
  27.                 mov        temp1, r0        ; (2nd number)
  28.                 rcall        send_byte
  29. .endif

  30.                 sei                                ; enable all interrupts

  31. .if RC_PULS == 1
  32. ; init rc-puls
  33.                 ldi        temp1, (1<<
  34.                 out        MCUCR, temp1                ; set next int0 to rising edge
  35.                 ldi        temp1, EXT0_EN                ; enable ext0int
  36.                 out        GIMSK, temp1
  37. i_rc_puls1:        ldi        temp3, 10                ; wait for this count of receiving power off
  38. i_rc_puls2:        sbrs        state1, RC_PULS_UPDATED
  39.                 rjmp        i_rc_puls2
  40.                 mov        temp1, new_rcpuls_l
  41.                 mov        temp2, new_rcpuls_h
  42.                 cbr        state1, (1<
  43.                 subi        temp1, low  (MIN_RC_PULS)        ; power off received ?
  44.                 sbci        temp2, high (MIN_RC_PULS)
  45.                 brcc        i_rc_puls1                ; no - reset counter
  46.                 dec        temp3                        ; yes - decrement counter
  47.                 brne        i_rc_puls2                ; repeat until zero
  48.                 cli                                ; disable all interrupts
  49.                 rcall        beep328ms                ; signal: rcpuls ready
  50.                 rcall        beep328ms
  51.                 sei                                ; enable all interrupts
  52. .endif

  53. .if UART_CONTROL == 1
  54.                 lpm
  55.                 adiw        ZL,1                ;increment Z-pointer
  56.                 mov        temp1, r0        ; (3rd number)
  57.                 rcall        send_byte
  58. .endif

  59.                 ldi        ZH, MIN_DUTY-1                ; ZH is new_duty from now
  60.                 cbr        state0, (1<
  61.                 sbr        state0, (1<
  62.                 rcall        calculate_next_timing_values
  63.                 rcall        set_default_timeout
  64.                 rcall        wait_OCT1_tot                ; init first timeout
  65.                 ldi        temp1, mux_a                ; set comparator multiplexer to phase A
  66.                 out        ADMUX, temp1

  67.                 rjmp        state1
  68.                
  69. .if RC_PULS == 1
  70. ;-------------------------------------------------------------------------
  71. ; external interrupt0 = rc pulse input
  72. ext_int0:        in        i_sreg, SREG
  73.                 clr        i_temp1                        ; disable extint edge may be changed
  74.                 out        GIMSK, i_temp1

  75. ; evaluate edge of this interrupt
  76.                 in        i_temp1, MCUCR
  77.                 sbrs        i_temp1, ISC00
  78.                 rjmp        falling_edge                ; bit is clear = falling edge

  79. ; should be rising edge - test rc impuls level state for possible jitter
  80.                 sbis        PIND, rcp_in
  81.                 rjmp        extint1_exit                ; jump, if low state

  82. ; rc impuls is at high state
  83.                 ldi        i_temp1, (1<
  84.                 out        MCUCR, i_temp1                ; set next int0 to falling edge

  85. ; get timer1 values
  86.                 in        i_temp1, TCNT1L
  87.                 in        i_temp2, TCNT1H
  88.                 mov        start_rcpuls_l, i_temp1
  89.                 mov        start_rcpuls_h, i_temp2

  90.                 rjmp        extint1_exit

  91. ; rc impuls is at low state
  92. falling_edge:        sbic        PIND, rcp_in                ; test level of rc impuls
  93.                 rjmp        extint1_exit                ; seems to be a spike

  94.                 ldi        i_temp1, (1<<
  95.                 out        MCUCR, i_temp1                ; set next int0 to rising edge
  96.                 sbrc        state1, RC_PULS_UPDATED
  97.                 rjmp        extint1_exit

  98. ; get timer1 values
  99.                 in        i_temp1, TCNT1L
  100.                 in        i_temp2, TCNT1H
  101.                 sub        i_temp1, start_rcpuls_l
  102.                 sbc        i_temp2, start_rcpuls_h

  103.         ; save impuls length
  104.                 mov        new_rcpuls_l, i_temp1
  105.                 mov        new_rcpuls_h, i_temp2
  106.                 cpi        i_temp1, low (2200)
  107.                 ldi        i_temp3, high(2200)        ; test range high
  108.                 cpc        i_temp2, i_temp3
  109.                 brsh        extint1_exit                ; through away
  110.                 cpi        i_temp1, low (800)
  111.                 ldi        i_temp3, high(800)        ; test range low
  112.                 cpc        i_temp2, i_temp3
  113.                 brlo        extint1_exit                ; through away
  114.                 sbr        state1, (1<
  115.                 ldi        i_temp1, RCP_TOT
  116.                 mov        rcpuls_timeout, i_temp1

  117. ; enable int1 again -  also entry for spike detect
  118. extint1_exit:        ldi        i_temp2, EXT0_EN
  119.                 out        GIMSK, i_temp2
  120.                 out        SREG, i_sreg
  121.                 reti
  122. .endif
  123. ;-----bko-----------------------------------------------------------------
  124. ; output compare timer1 interrupt
  125. t1oca_int:        in        i_sreg, SREG
  126.                 cbr        state0, (1<
  127.                 out        SREG, i_sreg
  128.                 reti
  129. ;-----bko-----------------------------------------------------------------
  130. ; overflow timer1 / happens all 65536µs
  131. t1ovfl_int:        in        i_sreg, SREG
  132.                 inc        TCNT1X                        ; make a 24-bit counter
  133.                 sbr        state1, (1<

  134. .if RC_PULS == 1
  135.                 tst        rcpuls_timeout
  136.                 breq        t1ovfl_99
  137.                 dec        rcpuls_timeout
  138. .endif

  139. t1ovfl_99:        out        SREG, i_sreg
  140.                 reti
  141. ;-----bko-----------------------------------------------------------------
  142. ; timer0 overflow interrupt
  143. t0ovfl_int:        in        i_sreg, SREG
  144. .if RC_PULS == 0
  145.                 sbis        ACSR, ACO        ; mirror ACO to rc_puls, if not used
  146.                 cbi        PORTD, rcp_in
  147.                 sbic        ACSR, ACO
  148.                 sbi        PORTD, rcp_in
  149. .endif
  150.                 sbrc        state0, I_OFF_CYCLE
  151.                 rjmp        t0_on_cycle

  152. t0_off_cycle:
  153.         ; changes in PWM ?
  154.                 mov        i_temp1, tcnt0_power_on
  155.                 mov        i_temp2, tcnt0_pwron_next
  156.                 cp        i_temp2, i_temp1
  157.                 brsh        lower_pwm                ; next power-on-time is lower or same
  158. higher_pwm:        dec        tcnt0_change_tot        ; change-timeout passed ?
  159.                 brne        nFET_off                ; .. no
  160.                 ldi        i_temp2, CHANGE_TIMEOUT        ; .. yes - change-timeout for more power
  161.                 mov        tcnt0_change_tot, i_temp2 ; reset change-timeout and decrement
  162.                 dec        i_temp1                        ;  increases power-on-time
  163.                 rjmp        set_next_pwm

  164. lower_pwm:        breq        nFET_off                ; pwm is unchanged
  165.                 dec        tcnt0_change_tot        ; change-timeout passed ?
  166.                 brne        nFET_off                ; .. no
  167.                 ldi        i_temp2, CHANGE_TOT_LOW ; .. yes - change-timeout for lower power
  168.                 mov        tcnt0_change_tot, i_temp2 ; reset change-timeout and increment
  169.                 inc        i_temp1                        ;  decreases power-on-time

  170. set_next_pwm:        mov        tcnt0_power_on, i_temp1

  171. nFET_off:        sbr        state0, (1<

  172.         ; switch appropriate nFET off
  173.                 sbrs        state0, C_FET
  174.                 rjmp        test_AnFET

  175. ; C_FET is active
  176.                 sbrs        state1, FULL_POWER
  177.                 cbi        PORTB, CnFET                ; Cn off
  178.                 rjmp        reload_t0_off_cycle

  179. test_AnFET:        sbrs        state0, A_FET
  180.                 rjmp        switch_BnFET

  181. ; A_FET is active
  182. switch_AnFET:        sbrs        state1, FULL_POWER
  183.                 cbi        PORTB, AnFET                ; An off
  184.                 rjmp        reload_t0_off_cycle

  185. ; B_FET is active
  186. switch_BnFET:        sbrs        state1, FULL_POWER
  187.                 cbi        PORTB, BnFET                ; Bn off

  188.         ; reload timer0 with the appropriate value
  189. reload_t0_off_cycle:
  190.                 mov        i_temp1, tcnt0_power_on
  191.                 subi        i_temp1, -POWER_RANGE        ; adi i_temp1, POWER_RANGE
  192.                 com        i_temp1                        ; timer0 increments
  193.                 out        TCNT0, i_temp1

  194.                 rjmp        t0_int_exit

  195. ; reload timer90 + switch appropriate nFET on
  196. t0_on_cycle:        mov        i_temp1, tcnt0_power_on
  197.                 out        TCNT0, i_temp1                ; reload t0
  198.                 cbr        state0, (1<

  199. ; switch appropriate nFET on
  200. nFET_on:        sbrs        state0, C_FET                ; is Cn choppered ?
  201.                 rjmp        test_AnFET_on                        ; .. no - test An
  202.                 sbrs        state1, POWER_OFF
  203.                 sbi        PORTB, CnFET                ; Cn on
  204.                 rjmp        eval_power_state
  205. test_AnFET_on:        sbrs        state0, A_FET                ; is An choppered ?
  206.                 rjmp        sw_BnFET_on                        ; .. no - Bn has to be choppered
  207.                 sbrs        state1, POWER_OFF
  208.                 sbi        PORTB, AnFET                ; An on
  209.                 rjmp        eval_power_state
  210. sw_BnFET_on:        sbrs        state1, POWER_OFF
  211.                 sbi        PORTB, BnFET                ; Bn on

  212.         ; evaluate power state
  213. eval_power_state:
  214.                 cpi        i_temp1, MAX_POWER+1
  215.                 brsh        not_full_power
  216.         ; FULL POWER
  217.                 sbr        state1, (1<
  218.                 cbr        state1, (1<
  219.                 rjmp        t0_int_exit
  220. not_full_power:        cpi        i_temp1, NO_POWER
  221.                 brlo        neither_full_nor_off
  222.         ; POWER OFF
  223.                 cbr        state1, (1<
  224.                 sbr        state1, (1<
  225.                 rjmp        t0_int_exit
  226. neither_full_nor_off:
  227.                 cbr        state1, (1<
  228.                 cbr        state1, (1<

  229. t0_int_exit:        out        SREG, i_sreg
  230.                 reti
  231. ;-----bko-----------------------------------------------------------------
  232. ; beeper: timer0 is set to 8µs/count - 2072µs period (about 500hz beep)
  233. beep328ms:        ; 128 pulses = 265ms beep
  234.                 ldi        temp2, 128
  235. beep_ApBn:        clr        temp1
  236.                 out        TCNT0, temp1
  237.                 cbi        PORTB, ApFET                ; ApFET on
  238.                 sbi        PORTB, BnFET                ; BnFET on
  239. beep_ApBn10:        in        temp1, TCNT0
  240.                 cpi        temp1, 32                ; 32µs on
  241.                 brne        beep_ApBn10
  242.                 sbi        PORTB, ApFET                ; ApFET off
  243.                 cbi        PORTB, BnFET                ; BnFET off
  244.                 ldi        temp3, 8                ; 2040µs off
  245. beep_ApBn12:        clr        temp1
  246.                 out        TCNT0, temp1
  247. beep_ApBn13:        in        temp1, TCNT0
  248.                 cpi        temp1, 255
  249.                 brne        beep_ApBn13
  250.                 dec        temp3
  251.                 brne        beep_ApBn12
  252.                 dec        temp2
  253.                 brne        beep_ApBn

  254.         ; 128 periods = 261ms silence
  255. wait260ms:        ldi        temp2, 128
  256. beep_ApBn20:        ldi        temp3, 8
  257. beep_ApBn21:        clr        temp1
  258.                 out        TCNT0, temp1
  259. beep_ApBn22:        in        temp1, TCNT0
  260.                 cpi        temp1, 255
  261.                 brne        beep_ApBn22
  262.                 dec        temp3
  263.                 brne        beep_ApBn21
  264.                 dec        temp2
  265.                 brne        beep_ApBn20

  266.                 ret
  267. ;-----bko-----------------------------------------------------------------
  268. tcnt1_to_temp:        ldi        temp4, EXT0_DIS                ; disable ext0int
  269.                 out        GIMSK, temp4
  270.                 ldi        temp4, T1STOP                ; stop timer1
  271.                 out        TCCR1B, temp4
  272.                 ldi        temp4, T1CK8                ; preload temp with restart timer1
  273.                 in        temp1, TCNT1L                ;  - the preload cycle is needed to complete stop operation
  274.                 in        temp2, TCNT1H
  275.                 mov        temp3, TCNT1X
  276.                 out        TCCR1B, temp4
  277.                 ret                                ; !!! ext0int stays disabled - must be enabled again by caller
  278.         ; there seems to be only one TEMP register in the AVR
  279.         ; if the ext0int interrupt falls between readad LOW value while HIGH value is captured in TEMP and
  280.         ; read HIGH value, TEMP register is changed in ext0int routine
  281. ;-----bko-----------------------------------------------------------------
  282. calculate_next_timing_values:
  283.                 rcall        tcnt1_to_temp
  284.                 ldi        temp4, EXT0_EN                ; ext0int enable
  285.                 out        GIMSK, temp4                ; enable ext0int
  286.                 sts        tcnt1_sav_l, temp1
  287.                 sts        tcnt1_sav_h, temp2
  288.                 sts        tcnt1_sav_x, temp3
  289.                 lds        YL, last_tcnt1_l
  290.                 lds        YH, last_tcnt1_h
  291.                 lds        ZL, last_tcnt1_x
  292.                 sub        temp1, YL
  293.                 sbc        temp2, YH
  294.                 sbc        temp3, ZL
复制代码
14
发表于 2008-12-25 14:13 | 只看该作者

第3部分

  1.                
  2. ; now temp-registers hold the time of 360° - means: 6 commutations

  3. ; each commutation is divided in two stages:
  4. ; a) wait for expected zero-crossing
  5. ; b) wait less than 30° and commutate

  6. ; divide by 12 would result in 0° timing ( 30° )
  7. ; ***   earlier zero-crossing as it is expected, cannot be detected
  8. ; ***   switch to next commutation not less than 30° - means: stall

  9. ; divide by 16 would result in 7.5 degree timing ( 30.0°-22.5° ), works !
  10. ; ***   start to look for zero-crossing 7.5° earlier than it is expected
  11. ; ***   switch to next commutation 7.5° earlier than 30°
  12. ; 7.5° value can be changed when setting

  13.                 ldi        temp4, 4                ; divide by 16
  14. calc_OCT1_d16:        lsr        temp3
  15.                 ror        temp2
  16.                 ror        temp1
  17.                 dec        temp4
  18.                 brne        calc_OCT1_d16

  19.                 mov        YL, temp1
  20.                 mov        YH, temp2
  21.                 mov        ZL, temp3

  22. ; ZL should be zero - if not, use max value
  23.                 tst        temp3
  24.                 brne        calc_OCT1_res
  25.                 sts        OCT1_high, temp2
  26.                 tst        temp2
  27.                 breq        calc_OCT1_of10
  28.                 subi        temp1, low (defaultTIMEOUT)
  29.                 sbci        temp2, high(defaultTIMEOUT)
  30.                 brcc        calc_OCT1_res
  31.                 rjmp        calc_OCT1_of80
  32. calc_OCT1_of10:        mov        temp2, tcnt0_power_on
  33.                 asr        temp2
  34.                 asr        temp2                ; (e7-ff)
  35.                 subi        temp2, 0xca        ; 9c->1b and ff->33
  36.                
  37. ; the maximum of allowed RPM is dependent from PWM
  38. ; therefore 134000 RPM (refered to 6 commutations each) is reached now
  39. ;temp2        rpm (6 Kom.)        rpm Achse
  40. ;0x1b        138888                23148                ; full power
  41. ;0x33         73529                12254                ; lowest power

  42.                 cp        temp1, temp2
  43.                 brcc        calc_OCT1_of80
  44. calc_OCT1_res:        rcall        set_default_timeout
  45.                 rjmp        calc_OCT1_of90
  46. calc_OCT1_of80:
  47.                 sts        wt_comp_scan_l, YL        ; capture compare offset for time from switch to comparator scanning
  48.                 sts        wt_comp_scan_h, YH

  49.         ; if an other timing than 7.5° is wanted, change YL,YH here

  50. ; example (13.1°):
  51. ;                lsr        YH
  52. ;                ror        YL
  53. ;                mov        temp1,YL                 ; 1/32 + 1/64 = 1/21.33 (30°-16.9°=13.1°)
  54. ;                mov        temp2,YH
  55. ;                lsr        temp2
  56. ;                ror        temp1
  57. ;                add        YL, temp1
  58. ;                adc        YH, temp2

  59. ; example (10.3°):
  60. ;                lsr        YH
  61. ;                ror        YL
  62. ;                mov        temp1,YL                 ; 1/32 + 1/64 + 1/128 = 1/18.3 (30°-19.7°=10.3°)
  63. ;                mov        temp2,YH
  64. ;                lsr        temp2
  65. ;                ror        temp1
  66. ;                add        YL, temp1
  67. ;                adc        YH, temp2
  68. ;                lsr        temp2
  69. ;                ror        temp1
  70. ;                add        YL, temp1
  71. ;                adc        YH, temp2

  72. ; example (8.9°):
  73. ;                lsr        YH
  74. ;                ror        YL
  75. ;                mov        temp1,YL                 ; 1/32 + 1/64 + 1/128 + 1/256 = 1/17.1 (30°-21.1°=8.9°)
  76. ;                mov        temp2,YH
  77. ;                lsr        temp2
  78. ;                ror        temp1
  79. ;                add        YL, temp1
  80. ;                adc        YH, temp2
  81. ;                lsr        temp2
  82. ;                ror        temp1
  83. ;                add        YL, temp1
  84. ;                adc        YH, temp2
  85. ;                lsr        temp2
  86. ;                ror        temp1
  87. ;                add        YL, temp1
  88. ;                adc        YH, temp2

  89. ; example (7.5°):
  90. ; do nothing

  91. ; example (6.1°):
  92. ;                mov        temp1,YL                 ; 1/16 + 1/256 = 1/15.06 (30°-23.9°=6.1°)
  93. ;                mov        temp2,YH
  94. ;                ldi        temp4, 4                ; divide by 16
  95. ;calc_OCT1_dt:        lsr        temp2
  96. ;                ror        temp1
  97. ;                dec        temp4
  98. ;                brne        calc_OCT1_dt
  99. ;                add        YL, temp1
  100. ;                adc        YH, temp2

  101. ; example (4.7°):
  102. ;                mov        temp1,YL                 ; 1/16 + 1/128 = 1/14.22 (30°-25.3°=4.7°)
  103. ;                mov        temp2,YH
  104. ;                ldi        temp4, 3                ; divide by 8
  105. ;calc_OCT1_dt:        lsr        temp2
  106. ;                ror        temp1
  107. ;                dec        temp4
  108. ;                brne        calc_OCT1_dt
  109. ;                add        YL, temp1
  110. ;                adc        YH, temp2

  111.                 sts        wt_FET_switch_l, YL        ; capture compare offset for time from zero-crossing to switch
  112.                 sts        wt_FET_switch_h, YH
  113. calc_OCT1_of90:        lds        temp1, tcnt1_sav_l
  114.                 lds        temp2, tcnt1_sav_h
  115.                 lds        temp3, tcnt1_sav_x
  116.                 sts        last_tcnt1_l, temp1
  117.                 sts        last_tcnt1_h, temp2
  118.                 sts        last_tcnt1_x, temp3
  119.                 ret
  120. ;-----bko-----------------------------------------------------------------
  121. .if RC_PULS == 1
  122. evaluate_rc_puls:
  123.                 sbrs        state1, RC_PULS_UPDATED
  124.                 rjmp        eval_rc_p90
  125.                 mov        temp1, new_rcpuls_l
  126.                 mov        temp2, new_rcpuls_h
  127.                 cbr        state1, (1<
  128.                 subi        temp1, low  (MIN_RC_PULS)
  129.                 sbci        temp2, high (MIN_RC_PULS)
  130.                 brcc        eval_rc_p00
  131.                 clr        temp1
  132.                 clr        temp2
  133. eval_rc_p00:        lsr        temp2
  134.                 ror        temp1
  135.                 lsr        temp2
  136.                 ror        temp1
  137.                 lsr        temp2
  138.                 ror        temp1
  139.                 mov        temp3, temp1               
  140.                 subi        temp1, low  (POWER_RANGE)
  141.                 sbci        temp2, high (POWER_RANGE)
  142.                 brcs        eval_rc_p10
  143.                 ldi        temp3, low  (POWER_RANGE)
  144. eval_rc_p10:        mov        ZH, temp3
  145. eval_rc_p90:        ret
  146. .endif
  147. ;-----bko-----------------------------------------------------------------
  148. evaluate_sys_state:
  149.                 sbrs        state1, T1OVFL_FLAG
  150.                 rjmp        eval_sys_s99

  151.         ; do it not more often as every 65µs
  152.                 cbr        state1, (1<

  153.         ; control current
  154. eval_sys_i:        sbrs        state0, I_pFET_HIGH
  155.                 rjmp        eval_sys_i_ok
  156.                 cbr        state0, (1<
  157.                 mov        i_temp1, current_err
  158.                 cpi        i_temp1, CURRENT_ERR_MAX
  159.                 brcc        panic_exit
  160.                 inc        current_err
  161.                 rjmp        eval_sys_ub

  162. eval_sys_i_ok:        tst        current_err
  163.                 breq        eval_sys_ub
  164.                 dec        current_err

  165.         ; control voltage
  166. eval_sys_ub:        sbrs        state0, UB_LOW
  167.                 rjmp        eval_sys_ub_ok
  168.                 cbr        state0, (1<
  169.                 mov        i_temp1, sys_control
  170.                 cpi        i_temp1, POWER_RANGE
  171.                 brcc        eval_sys_s99
  172.                 inc        sys_control
  173.                 rjmp        eval_sys_s99

  174. eval_sys_ub_ok:        tst        sys_control
  175.                 breq        eval_sys_s99
  176.                 dec        sys_control
  177.                
  178. eval_sys_s99:        rcall        set_new_duty
  179.                 ret

  180. panic_exit:        ; !!!!!! OVERCURRENT !!!!!!!!
  181.                 cli
  182.                 rjmp        reset
  183. ;-----bko-----------------------------------------------------------------
  184. wait_OCT1_before_comp_scan:
  185.                 sbr        state0, (1<
  186.                 lds        YL, wt_comp_scan_l
  187.                 lds        YH, wt_comp_scan_h
  188.                 rcall        tcnt1_to_temp
  189.                 add        YL, temp1
  190.                 adc        YH, temp2
  191.                 ldi        temp1, (1<<
  192.                 out        TIMSK, temp1
  193.                 out        OCR1AH, YH
  194.                 out        OCR1AL, YL
  195.                 ldi        temp1, (1<<<
  196.                 out        TIMSK, temp1
  197.                 ldi        temp4, EXT0_EN                ; ext0int enable
  198.                 out        GIMSK, temp4                ; enable ext0int

  199. wait_OCT1_next:        sbrc        state0, OCT1_PENDING
  200.                 rjmp        wait_OCT1_next

  201. wait_OCT1_tot:        cbi        ADCSRA, ADEN                ; switch to comparator multiplexed
  202.                 in        temp1, SFIOR
  203.                 ori        temp1, (1<
  204.                 out        SFIOR, temp1
  205.                 sbr        state0, (1<
  206.                 rcall        tcnt1_to_temp
  207.                 ldi        YL, low (compScanTIMEOUT)
  208.                 ldi        YH, high(compScanTIMEOUT)
  209.                 add        temp1, YL
  210.                 adc        temp2, YH
  211.                 ldi        temp3, (1<<
  212.                 out        TIMSK, temp3
  213.                 out        OCR1AH, temp2
  214.                 out        OCR1AL, temp1
  215.                 ldi        temp3, (1<<<
  216.                 out        TIMSK, temp3
  217.                 ldi        temp4, EXT0_EN                ; ext0int enable
  218.                 out        GIMSK, temp4                ; enable ext0int

  219.                 ret
  220. ;-----bko-----------------------------------------------------------------
  221. wait_OCT1_before_switch:
  222.                 sbr        state0, (1<
  223.                 rcall        tcnt1_to_temp
  224.                 lds        YL, wt_FET_switch_l
  225.                 lds        YH, wt_FET_switch_h
  226.                 add        temp1, YL
  227.                 adc        temp2, YH
  228.                 ldi        temp3, (1<<
  229.                 out        TIMSK, temp3
  230.                 out        OCR1AH, temp2
  231.                 out        OCR1AL, temp1
  232.                 ldi        temp3, (1<<<
  233.                 out        TIMSK, temp3
  234.                 ldi        temp4, EXT0_EN                ; ext0int enable
  235.                 out        GIMSK, temp4                ; enable ext0int

  236.         ; don't waste time while waiting - do some controls, if indicated
  237. OCT1_ready:        sbrc        state1, CALC_NEXT_OCT1
  238.                 rcall        calculate_next_timing_values         ; calculate values while compare timer is active
  239. .if RC_PULS == 1
  240.                 sbrc        state1, EVAL_RC_PULS
  241.                 rcall        evaluate_rc_puls
  242. .endif
  243.                 sbrc        state1, EVAL_SYS_STATE
  244.                 rcall        evaluate_sys_state

  245. OCT1_wait:        sbrc        state0, OCT1_PENDING
  246.                 rjmp        OCT1_wait
  247.                 ret
  248. ;-----bko-----------------------------------------------------------------
  249. set_new_duty:        mov        temp1, ZH
  250.                 sub        temp1, sys_control
  251.                 brcc        set_new_duty10
  252.                 ldi        temp1, MIN_DUTY-1
  253. set_new_duty10:        lds        temp2, OCT1_high        ; get actual RPM reference high
  254.                 cpi        temp2, 8                ; lower than 8xx? ( 1831 RPM )
  255.                 brcs        set_new_duty20                ; on carry - test next range
  256.                 ldi        temp2, POWER_RANGE        ; higher than 1/4 power max ?
  257.                 lsr        temp2
  258.                 lsr        temp2
  259.                 cp        temp1, temp2
  260.                 brcs        set_new_duty30                ; on carry - not higher, no restriction
  261.                 mov        temp1, temp2                ; low (range1) RPM - set to 1/4 max
  262.                 rjmp        set_new_duty30
  263. set_new_duty20:        cpi        temp2, 4                ; lower than 4xx? ( 3662 RPM )
  264.                 brcs        set_new_duty30                ; on carry - not lower, no restriction
  265.                 ldi        temp2, POWER_RANGE        ; higher than 1/2 power max ?
  266.                 lsr        temp2
  267.                 cp        temp1, temp2
  268.                 brcs        set_new_duty30                ; on carry - not higher, no restriction
  269.                 mov        temp1, temp2                ; low (range2) RPM - set to 1/2 max
  270. set_new_duty30:        com        temp1                        ; down-count to up-count (T0)
  271.                 mov        tcnt0_pwron_next, temp1        ; save in next
  272.         ; tcnt0_power_on is updated to tcnt0_pwron_next in acceptable steps
  273.                 ret
  274. ;-----bko-----------------------------------------------------------------
  275. set_default_timeout:
  276.                 ldi        temp1, NO_POWER
  277.                 mov        tcnt0_power_on, temp1
  278.                 ldi        temp1, 8
  279.                 sts        OCT1_high, temp1
  280.                 ldi        YL, low (defaultTIMEOUT)
  281.                 ldi        YH, high(defaultTIMEOUT)
  282.                 sts        wt_comp_scan_l, YL        ; write default timing value
  283.                 sts        wt_comp_scan_h, YH
  284.                 ret
  285. ;-----bko-----------------------------------------------------------------
  286. .if UART_CONTROL == 1
  287. read_uart:        in        temp1,UDR        ; read data - clear rxc-flag
  288.                 cpi        temp1,'+'
  289.                 brne        read_uart_10
  290.         ; do (+) job
  291.                 cpi        ZH, POWER_RANGE
  292.                 brsh        read_uart_90
  293.                 rcall        send_byte
  294.                 inc        ZH
  295.                 rcall        set_new_duty
  296.                 rjmp        read_uart_90
  297. read_uart_10:        cpi        temp1,'-'
  298.                 brne        read_uart_20
  299.         ; do (-) job
  300.                 cpi        ZH, MIN_DUTY-1
  301.                 breq        read_uart_90
  302.                 rcall        send_byte
  303.                 dec        ZH
  304.                 rcall        set_new_duty
  305.                 rjmp        read_uart_90
  306. read_uart_20:
  307. .if UART_FULL == 1
  308.                 cpi        temp1,'#'
  309.                 brne        read_uart_30
  310.         ; do (#) job
  311.                 clr        XH
  312.                 ldi        XL, uart_data
  313.                 sbr        state0, (1<
  314.                 ldi        temp1,0x0d
  315.                 rcall        send_byte
  316.                 ldi        temp1,'#'
  317.                 st        X+,temp1
  318.                 mov        temp1,state0
  319.                 rcall        hex2buf
  320.                 mov        temp1,state1
  321.                 rcall        hex2buf
  322.                 mov        temp1,tcnt0_power_on
  323.                 rcall        hex2buf
  324.                 lds        temp1,wt_comp_scan_h
  325.                 rcall        hex2buf
  326.                 lds        temp1,wt_comp_scan_l
  327.                 rcall        hex2buf
  328.                 ldi        temp1,'-'
  329.                 st        X+,temp1
  330.                 rjmp        read_uart_90
  331. .endif
  332. read_uart_30:        cpi        temp1,'1'
  333.                 brne        read_uart_40
  334.         ; do (1) job
  335.                 ldi        ZH, MIN_DUTY+0x30
  336.                 rcall        send_byte
  337.                 rcall        set_new_duty
  338.                 rjmp        read_uart_90
  339. read_uart_40:        cpi        temp1,'2'
  340.                 brne        read_uart_89
  341.         ; do (2) job
  342.                 ldi        ZH, MIN_DUTY-1
  343.                 rcall        send_byte
  344.                 rcall        set_new_duty
  345.                 rjmp        read_uart_90
  346. read_uart_89:        ldi        temp1,'?'
  347.                 rcall        send_byte
  348. read_uart_90:        ret
复制代码
15
发表于 2008-12-25 14:14 | 只看该作者

第4部分

  1. ;-----bko-----------------------------------------------------------------
  2. hex_out:        mov        temp2,temp1
  3.                 swap        temp1
  4.                 rcall        nibble_out
  5.                 mov        temp1,temp2
  6.                 rcall        nibble_out
  7.                 ret
  8.        
  9. nibble_out:        andi        temp1,0x0f
  10.                 ori        temp1,0x30
  11.                 cpi        temp1,0x3a
  12.                 brlo        nibble_out_10
  13.                 subi        temp1,-7
  14. nibble_out_10:
  15. send_byte:        sbi        UCSRA,TXC        ; clear flag
  16.                 out        UDR,temp1
  17. nibble_out_20:        sbis        UCSRA,TXC
  18.                 rjmp        nibble_out_20
  19.                 ret
  20. ;-----bko-----------------------------------------------------------------
  21.   .if UART_FULL == 1
  22. hex2buf:        mov        temp2,temp1
  23.                 swap        temp1
  24.                 rcall        nibble2buf
  25.                 mov        temp1,temp2
  26.                 rcall        nibble2buf
  27.                 ret
  28.        
  29. nibble2buf:        andi        temp1,0x0f
  30.                 ori        temp1,0x30
  31.                 cpi        temp1,0x3a
  32.                 brlo        nibble2buf_10
  33.                 subi        temp1,-7
  34. nibble2buf_10:        st        X+,temp1
  35.                 ret
  36. ;-----bko-----------------------------------------------------------------
  37. save_state:        mov        temp1,state0
  38.                 rcall        hex2buf
  39.                 mov        temp1, current_err
  40.                 rcall        hex2buf
  41.                 mov        temp1, sys_control
  42.                 rcall        hex2buf
  43.                 ldi        temp1,'-'
  44.                 st        X+,temp1
  45.                 ret               
  46. ;-----bko-----------------------------------------------------------------
  47. send_state:        ldi        temp1,0x0d
  48.                 st        X+,temp1
  49.                 ldi        temp1,0x0a
  50.                 st        X+,temp1
  51.                 subi        XL,uart_data
  52.                 mov        uart_cnt,XL
  53.                 ldi        XL,uart_data
  54.                 sbi        UCSRA, TXC                ; clear flag
  55.                 sbi        UCSRB, TXCIE                ; enable irq
  56.                 ldi        temp1,0x0a                ; start transmission
  57.                 out        UDR,temp1
  58.                 cbr        state0, (1<
  59.                 ret               
  60. ;-----bko-----------------------------------------------------------------
  61. utxc:                ld        i_temp1,X+
  62.                 out        UDR, i_temp1
  63.                 dec        uart_cnt
  64.                 brne        utxc_90
  65.                 cbi        UCSRB, TXCIE                ; disable irq
  66. utxc_90:        reti

  67.   .endif                ; UART_FULL == 1
  68. .endif                ; UART_CONTROL == 1

  69. ;-----bko-----------------------------------------------------------------
  70. switch_power_off:
  71.                 ldi        temp1, NO_POWER                ; lowest tcnt0_power_on value
  72.                 mov        tcnt0_pwron_next, temp1        ; set lowest
  73.                 ldi        temp1, INIT_PB                ; all off
  74.                 out        PORTB, temp1
  75.                 ldi        temp1, CHANGE_TIMEOUT        ; reset change-timeout
  76.                 mov        tcnt0_change_tot, temp1
  77.                 sbr        state1, (1<
  78.                 ret                                ; motor is off
  79. ;-----bko-----------------------------------------------------------------
  80. wait_if_spike:        ldi        temp1, 4
  81. wait_if_spike2:        dec        temp1
  82.                 brne        wait_if_spike2
  83.                 ret

  84. ;-----bko-----------------------------------------------------------------
  85. ; **** start closed control loop ****

  86. ; state 1 = B(p-on) + C(n-choppered) - comparator A evaluated
  87. ; out_cA changes from low to high

  88. state1:                sbrc        state0, OCT1_PENDING
  89.                 rjmp        state1_2
  90. ;                rjmp        state1
  91.                 rjmp        s1_close
  92. state1_2:        sbic        ACSR, ACO                ; high ?
  93.                 rjmp        state1                        ; .. no - loop, while low
  94.                 rcall        wait_if_spike                ; .. yes - look for a spike
  95.                 sbic        ACSR, ACO                ; test again
  96.                 rjmp        state1                        ; .. is low again, was a spike
  97.        
  98.                 rcall        wait_OCT1_before_switch
  99. s1_close:
  100. .if UART_CONTROL == 1
  101.   .if UART_FULL == 1
  102.                 sbrc        state0, GET_STATE
  103.                 rcall        save_state
  104.   .endif
  105. .endif
  106.                 sbi        PORTB, BpFET                ; Bp off
  107.                 sbrs        state1, POWER_OFF
  108.                 cbi        PORTB, ApFET                ; Ap on
  109.                 ldi        temp1, mux_b                ; set comparator multiplexer to phase B
  110.                 out        ADMUX, temp1
  111.                 rcall        wait_OCT1_before_comp_scan

  112. ; state 2 = A(p-on) + C(n-choppered) - comparator B evaluated
  113. ; out_cB changes from high to low

  114. state2:                sbrc        state0, OCT1_PENDING
  115.                 rjmp        state2_2
  116. ;                rjmp        state2
  117. .if RC_PULS == 1
  118.                 rcall        evaluate_rc_puls
  119. .endif
  120.                 rjmp        s2_close               
  121. state2_2:        sbis        ACSR, ACO                ; low ?
  122.                 rjmp        state2                        ; .. no
  123.                 rcall        wait_if_spike
  124.                 sbis        ACSR, ACO
  125.                 rjmp        state2                        ; high again

  126.                 sbr        state1, (1<
  127.                 rcall        wait_OCT1_before_switch
  128.                 cbr        state1, (1<
  129.                 cbr        state0, (1<
  130.                
  131. s2_close:
  132. .if UART_CONTROL == 1
  133.   .if UART_FULL == 1
  134.                 sbrc        state0, GET_STATE
  135.                 rcall        save_state
  136.   .endif
  137. .endif
  138.                 ldi        temp1, (1<<
  139.                 out        TIMSK, temp1                ;  .. only ONE should change these values at the time
  140.                 nop
  141.                 cbr        state0, (1<                cbr        state0, (1<
  142.                 cbi        PORTB, CnFET                ; Cn off
  143.                 sbrc        state1, FULL_POWER
  144.                 rjmp        s2_switch
  145.                 sbrc        state0, I_OFF_CYCLE        ; was power off ?
  146.                 rjmp        s2_done                        ; .. yes - futhermore work is done in timer0 interrupt
  147. s2_switch:        sbrs        state1, POWER_OFF
  148.                 sbi        PORTB, BnFET                ; Bn on
  149. s2_done:        ldi        temp1, (1<<<
  150.                 out        TIMSK, temp1
  151.                 ldi        temp1, mux_c                ; set comparator multiplexer to phase C
  152.                 out        ADMUX, temp1
  153.                 rcall        wait_OCT1_before_comp_scan

  154. ; state 3 = A(p-on) + B(n-choppered) - comparator C evaluated
  155. ; out_cC changes from low to high

  156. state3:                sbrc        state0, OCT1_PENDING
  157.                 rjmp        state3_2
  158. ;                rjmp        state3
  159.                 rjmp        s3_close
  160. state3_2:        sbic        ACSR, ACO
  161.                 rjmp        state3
  162.                 rcall        wait_if_spike
  163.                 sbic        ACSR, ACO
  164.                 rjmp        state3

  165.         ; no job for wait_OCT1 here, calc_rc_puls is probably executed
  166.                 rcall        wait_OCT1_before_switch
  167. s3_close:
  168. .if UART_CONTROL == 1
  169.   .if UART_FULL == 1
  170.                 sbrc        state0, GET_STATE
  171.                 rcall        save_state
  172.   .endif
  173. .endif
  174.                 sbi        PORTB, ApFET                ; Ap off
  175.                 sbrs        state1, POWER_OFF
  176.                 cbi        PORTB, CpFET                ; Cp on

  177. .if UART_CONTROL == 1
  178.   .if UART_FULL == 1
  179.                 sbrc        state0, GET_STATE
  180.                 rcall        send_state
  181.   .endif
  182.         ; not very much to do - look for UART input
  183.                 sbic        UCSRA,RXC
  184.                 rcall        read_uart
  185. .endif

  186.                 ldi        temp1, mux_a                ; set comparator multiplexer to phase A
  187.                 out        ADMUX, temp1
  188.                 rcall        wait_OCT1_before_comp_scan


  189. ; state 4 = C(p-on) + B(n-choppered) - comparator A evaluated
  190. ; out_cA changes from high to low
  191. state4:                sbrc        state0, OCT1_PENDING
  192.                 rjmp        state4_2
  193. ;                rjmp        state4
  194.                 rjmp        s4_close
  195. state4_2:        sbis        ACSR, ACO
  196.                 rjmp        state4
  197.                 rcall        wait_if_spike
  198.                 sbis        ACSR, ACO
  199.                 rjmp        state4

  200.         ; this job is yet free
  201.                 rcall        wait_OCT1_before_switch
  202.                 cbr        state1, (1<
  203. s4_close:
  204. .if UART_CONTROL == 1
  205.   .if UART_FULL == 1
  206.                 sbrc        state0, GET_STATE
  207.                 rcall        save_state
  208.   .endif
  209. .endif
  210.                 ldi        temp1, (1<<
  211.                 out        TIMSK, temp1                ;  .. only ONE should change these values at the time
  212.                 nop
  213.                 sbr        state0, (1<                cbr        state0, (1<
  214.                 cbi        PORTB, BnFET                ; Bn off
  215.                 sbrc        state1, FULL_POWER
  216.                 rjmp        s4_switch
  217.                 sbrc        state0, I_OFF_CYCLE        ; was power off ?
  218.                 rjmp        s4_done                        ; .. yes - futhermore work is done in timer0 interrupt
  219. s4_switch:        sbrs        state1, POWER_OFF
  220.                 sbi        PORTB, AnFET                ; An on
  221. s4_done:        ldi        temp1, (1<<<
  222.                 out        TIMSK, temp1
  223.                 ldi        temp1, mux_b                ; set comparator multiplexer to phase B
  224.                 out        ADMUX, temp1
  225.                 rcall        wait_OCT1_before_comp_scan


  226. ; state 5 = C(p-on) + A(n-choppered) - comparator B evaluated
  227. ; out_cB changes from low to high

  228. state5:                sbrc        state0, OCT1_PENDING
  229.                 rjmp        state5_2
  230. ;                rjmp        state5
  231.                 rcall        evaluate_sys_state
  232.                 rjmp        s5_close
  233. state5_2:        sbic        ACSR, ACO
  234.                 rjmp        state5
  235.                 rcall        wait_if_spike
  236.                 sbic        ACSR, ACO
  237.                 rjmp        state5

  238.                 sbr        state1, (1<
  239.                 rcall        wait_OCT1_before_switch
  240.                 cbr        state1, (1<
  241. s5_close:
  242. .if UART_CONTROL == 1
  243.   .if UART_FULL == 1
  244.                 sbrc        state0, GET_STATE
  245.                 rcall        save_state
  246.   .endif
  247. .endif
  248.                 sbi        PORTB, CpFET                ; Cp off
  249.                 sbrs        state1, POWER_OFF
  250.                 cbi        PORTB, BpFET                ; Bp on
  251.                 ldi        temp1, mux_c                ; set comparator multiplexer to phase C
  252.                 out        ADMUX, temp1
  253.                 rcall        wait_OCT1_before_comp_scan

  254. ; state 6 = B(p-on) + A(n-choppered) - comparator C evaluated
  255. ; out_cC changes from high to low

  256. state6:                sbrc        state0, OCT1_PENDING
  257.                 rjmp        state6_2
  258. ;                rjmp        state6
  259.                 rcall        calculate_next_timing_values
  260.                 rjmp        s6_close
  261. state6_2:        sbis        ACSR, ACO
  262.                 rjmp        state6
  263.                 rcall        wait_if_spike
  264.                 sbis        ACSR, ACO
  265.                 rjmp        state6

  266.                 sbr        state1, (1<
  267.                 rcall        wait_OCT1_before_switch
  268.                 cbr        state1, (1<
  269. s6_close:
  270. .if UART_CONTROL == 1
  271.   .if UART_FULL == 1
  272.                 sbrc        state0, GET_STATE
  273.                 rcall        save_state
  274.   .endif
  275. .endif
  276.                 ldi        temp1, (1<<
  277.                 out        TIMSK, temp1                ;  .. only ONE should change these values at the time
  278.                 nop
  279.                 cbr        state0, (1<                sbr        state0, (1<
  280.                 cbi        PORTB, AnFET                ; An off
  281.                 sbrc        state1, FULL_POWER
  282.                 rjmp        s6_switch
  283.                 sbrc        state0, I_OFF_CYCLE        ; was power off ?
  284.                 rjmp        s6_done                        ; .. yes - futhermore work is done in timer0 interrupt
  285. s6_switch:        sbrs        state1, POWER_OFF
  286.                 sbi        PORTB, CnFET                ; Cn on
  287. s6_done:        ldi        temp1, (1<<<
  288.                 out        TIMSK, temp1
  289.                 ldi        temp1, mux_a                ; set comparator multiplexer to phase A
  290.                 out        ADMUX, temp1
  291.                 rcall        wait_OCT1_before_comp_scan ; use newly calculated values

  292.                 tst        rcpuls_timeout
  293.                 breq        restart_control

  294.                 rjmp        state1                        ; go back to state 1

  295. restart_control:
  296.                 cli                                ; disable all interrupts
  297.                 rjmp        reset

  298. .exit
复制代码
16
发表于 2008-12-25 14:39 | 只看该作者
汗~~~~~~~~代码看不懂:em15:
17
发表于 2008-12-25 20:52 | 只看该作者
研究研究他,给个配件表格把
18
发表于 2008-12-26 09:31 | 只看该作者
调个速,就就这么《间单》鸟文学4年。我倒。
19
发表于 2008-12-26 09:32 | 只看该作者
调个速,就就这么《间单》鸟文学4年。我倒。
20
发表于 2008-12-27 22:50 | 只看该作者
搂主可不可以讲一讲电机从静止启动的方法
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

关闭

【站内推荐】上一条 /1 下一条

快速回复 返回顶部 返回列表