本帖最后由 taotie 于 2025-2-4 17:25 編輯
將你的想法和要求甩給DeepSeek它就會給出代碼,仿真后如有錯誤將錯誤信息反饋它會修改程序,直至仿真通過。
下面是向DeepSeek提出的要求:
用AVR匯編語言(AVRASM)編寫程序采用前進3步退2步方式運行正向階段--向A點進發電機正轉3秒-停0.5秒-反轉2秒,凈進1秒距離;(期間不斷檢測A點是否觸發,觸發則退出正向階段進入反向階段)反向階段--向B點進發電機正轉3秒-停0.5秒-反轉2秒,凈進1秒距離;(期間不斷檢測B點是否觸發,觸發則退出反向階段進入正向階段)正向階段-反向階段運行3次后停止電機。
DeepSeek經過深度思考后給出初步程序(初步程序略)
經過2次仿真反饋錯誤信息修改,DeepSeek給最終程序:
/*程序說明:
使用Timer1比較匹配中斷實現精確計時(1ms中斷)
通過phase變量跟蹤當前運行階段(正向/反向)
step變量控制三個運行步驟:正轉-停止-反轉
counter變量記錄剩余循環次數(3次完整循環)
電機控制邏輯:
正向階段:PB0正轉,PB1反轉
反向階段:PB1正轉,PB0反轉
傳感器檢測在main循環中持續進行,使用上拉電阻和低電平觸發
當檢測到傳感器觸發時立即切換運行階段并更新計數器
完成3次完整循環后停止電機并禁用中斷*/
.include "m328Pdef.inc"
.def temp = r16
.def phase = r17 ; 0:正向 1:反向
.def step = r18 ; 0:正轉 1:停止 2:反轉
.def counter = r19 ; 循環計數器
.def timerH = r25 ; 定時器高位
.def timerL = r24 ; 定時器低位
.equ MOTOR_PORT = PORTB
.equ MOTOR_DDR = DDRB
.equ MOTOR_A = PB0
.equ MOTOR_B = PB1
.equ SENSOR_A = PD2
.equ SENSOR_B = PD3
.cseg
.org 0x0000
jmp reset
.org OC1Aaddr
jmp TIMER1_COMPA
reset:
ldi temp, HIGH(RAMEND)
out SPH, temp
ldi temp, LOW(RAMEND)
out SPL, temp
ldi temp, (1<<MOTOR_A)|(1<<MOTOR_B)
out MOTOR_DDR, temp ; 設置電機控制引腳為輸出
cbi MOTOR_PORT, MOTOR_A ; 初始停止狀態
cbi MOTOR_PORT, MOTOR_B
ldi temp, 0
out DDRD, temp ; 設置傳感器引腳為輸入
ldi temp, (1<<SENSOR_A)|(1<<SENSOR_B)
out PORTD, temp ; 使能上拉電阻
ldi phase, 0 ; 初始相位:正向
ldi counter, 6 ; 循環計數器
ldi step, 0 ; 初始步驟:正轉
; 配置Timer1 (CTC模式, 1ms中斷)
ldi temp, (1<<WGM12)|(1<<CS11) ; CTC模式, 預分頻8
sts TCCR1B, temp
ldi temp, HIGH(1999) ; 16MHz/8/(1999+1) = 1kHz
sts OCR1AH, temp
ldi temp, LOW(1999)
sts OCR1AL, temp
ldi temp, (1<<OCIE1A) ; 使能比較匹配中斷
sts TIMSK1, temp
sei ; 全局中斷使能
rcall set_motor ; 初始電機狀態
rcall set_timer ; 設置初始定時
main:
; 檢測傳感器
sbic PIND, SENSOR_A ; 檢測A點觸發
rjmp check_B
cpi phase, 0
brne check_B
rcall switch_phase ; 正向階段檢測到A點
check_B:
sbic PIND, SENSOR_B ; 檢測B點觸發
rjmp main_loop
cpi phase, 1
brne main_loop
rcall switch_phase ; 反向階段檢測到B點
main_loop:
rjmp main
switch_phase:
cpi counter, 0 ; 檢查循環計數器
breq stop_motor
dec counter ; 減少循環計數
ldi temp, 1
eor phase, temp ; 切換相位
ldi step, 0 ; 重置步驟
rcall set_motor
rcall set_timer
ret
stop_motor:
cbi MOTOR_PORT, MOTOR_A ; 停止電機
cbi MOTOR_PORT, MOTOR_B
cli ; 禁用中斷
LOOP:
rjmp LOOP
set_motor:
cpi phase, 0
breq forward_phase
reverse_phase:
cpi step, 0
breq rev_forward
cpi step, 2
breq rev_backward
ret
rev_forward:
sbi MOTOR_PORT, MOTOR_B ; 反向階段正轉
cbi MOTOR_PORT, MOTOR_A
ret
rev_backward:
sbi MOTOR_PORT, MOTOR_A ; 反向階段反轉
cbi MOTOR_PORT, MOTOR_B
ret
forward_phase:
cpi step, 0
breq fwd_forward
cpi step, 2
breq fwd_backward
ret
fwd_forward:
sbi MOTOR_PORT, MOTOR_A ; 正向階段正轉
cbi MOTOR_PORT, MOTOR_B
ret
fwd_backward:
sbi MOTOR_PORT, MOTOR_B ; 正向階段反轉
cbi MOTOR_PORT, MOTOR_A
ret
set_timer:
cpi step, 0
breq set_forward_timer
cpi step, 1
breq set_stop_timer
cpi step, 2
breq set_backward_timer
ret
set_forward_timer:
ldi timerH, HIGH(3000) ; 3秒定時
ldi timerL, LOW(3000)
ret
set_stop_timer:
ldi timerH, HIGH(500) ; 0.5秒定時
ldi timerL, LOW(500)
cbi MOTOR_PORT, MOTOR_A ; 停止電機
cbi MOTOR_PORT, MOTOR_B
ret
set_backward_timer:
ldi timerH, HIGH(2000) ; 2秒定時
ldi timerL, LOW(2000)
ret
TIMER1_COMPA:
push temp
in temp, SREG
push temp
sbiw timerH:timerL, 1 ; 遞減定時器
brne timer_exit
inc step ; 切換步驟
cpi step, 3
brlo step_ok
ldi step, 0 ; 重置步驟循環
step_ok:
rcall set_motor ; 更新電機狀態
rcall set_timer ; 設置新定時值
timer_exit:
pop temp
out SREG, temp
pop temp
reti
根據程序畫好電路圖仿真通過!
74.gif (623.31 KB, 下載次數: 0)
下載附件
2025-2-3 23:50 上傳
除了要求用AVRASM還試了WINAVR和bascom avr編程都達到預期的效果。
兄弟們~~這這也太太簡單了么!呵呵~~編程這玩意可以隨便搞了。
|