本帖最后由 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
根据程序画好电路图仿真通过!
除了要求用AVRASM还试了WINAVR和bascom avr编程都达到预期的效果。
兄弟们~~这这也太太简单了么!呵呵~~编程这玩意可以随便搞了。
|