我们有蓝牙模块,当接收器数据被更改时,它会发送中断信号到picoblaze并通过中断确认降低该信号。 中断子程序工作成功但系统无法返回主程序。当我们运行系统主循环按要求流动但在中断信号之后它停留在中断子程序中。我们能够一遍又一遍地调用中断子程序但是不能回到主循环。
我们的汇编代码是:
CONSTANT SONAR, 81
CONSTANT REMOTE, 82
CONSTANT MOTOR_R, 83
CONSTANT MOTOR_L, 84
CONSTANT ILERI, 00
CONSTANT SAG, 01
CONSTANT SOL, 02
CONSTANT SAGX, 03
CONSTANT SOLX, 04
CONSTANT ILERI2, 08
CONSTANT SAG2, 09
CONSTANT SOL2, 0A
CONSTANT SAGX2, 0B
CONSTANT SOLX2, 0C
CONSTANT HIZLAN, 05
CONSTANT YAVASLA, 06
NAMEREG sD, SPEED
NAMEREG sC, ENGELLER
LOAD sE, 00
LOAD SPEED, 3F ; hiz degeri 0 ile 128 arasi degissin, main icinde degeri
degisebilsin
ENABLE INTERRUPT
LOOP:
INPUT ENGELLER, 81
COMPARE ENGELLER, 1
JUMP NZ SOLSERBEST
CALL RIGHT
CALL DELAY_QS
JUMP LOOP
SOLSERBEST:
COMPARE ENGELLER, 2
JUMP NZ SAGSERBEST
CALL LEFT
CALL DELAY_QS
JUMP LOOP
SAGSERBEST:
CALL FORWARD
CALL DELAY_QS
JUMP LOOP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ileri ve geri fonksiyonlari birlestirilebilir
ilk bitin degeri main icinde verilirse
FORWARD: ; her hamleden once pwm 0 ediliyor
LOAD sE, 00
OUTPUT sE, MOTOR_R ; MOTOR_R gelen port id'e gore degisecek
OUTPUT sE, MOTOR_L ; ikinci pwm modulune
TEST sE, 00 ; delay
ADD sE, SPEED
ADD sE, 80 ; simdiki sisteme gore ilk biti 1 yapilip ileri yon
veriliyor
OUTPUT sE, MOTOR_R
OUTPUT sE, MOTOR_L
LOAD sE, 00
RETURN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RIGHT:
LOAD sE, 00
OUTPUT sE, MOTOR_R
OUTPUT sE, MOTOR_L
TEST sE, 00
ADD sE, SPEED
ADD sE, 80 ; bu herhalde ileri olacak :D
OUTPUT sE, MOTOR_R ; sag motor MOTOR_R deymis gibi
LOAD sE, 00
RETURN
LEFT:
LOAD sE, 00
OUTPUT sE, MOTOR_R
OUTPUT sE, MOTOR_L
TEST sE, 00
ADD sE, SPEED
ADD sE, 80 ; bu herhalde ileri olacak :D
OUTPUT sE, MOTOR_L ; sol motor MOTOR_L deymis gibi
LOAD sE, 00
RETURN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FORW_R:
LOAD sE, 00
OUTPUT sE, MOTOR_R
OUTPUT sE, MOTOR_L
TEST sE, 00
ADD sE, SPEED
SR0 sE ; sol motora hizin yarisi gitsin
ADD sE, 80 ; ikisi de ileri
OUTPUT sE, MOTOR_L
TEST sE, 00 ; delay
ADD sE, SPEED ; sag motora hizin bir bucuk kati gitsin
OUTPUT sE, MOTOR_R
LOAD sE,00
RETURN
FORW_L:
LOAD sE, 00
OUTPUT sE, MOTOR_R
OUTPUT sE, MOTOR_L
TEST sE, 00
ADD sE, SPEED
SR0 sE ; sag motora hizin yarisi gitsin
ADD sE, 80
OUTPUT sE, MOTOR_R
TEST sE, 00 ; delay
ADD sE, SPEED ; sol motora hizin bir bucuk kati gitsin
OUTPUT sE, MOTOR_L
LOAD sE,00
RETURN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DELAY_1S:
LOAD s0, 80
LOAD s1, F0
LOAD s2, FA
LOAD s3, 02
DONGU1:
SUB s0, 01
JUMP NZ, DONGU1
DONGU2:
SUB s1, 01
JUMP Z, DONGU3
LOAD s0, FF
JUMP DONGU1
DONGU3:
SUB s2, 01
JUMP Z, DONGU4
LOAD s1, FF
JUMP DONGU2
DONGU4:
SUB s3, 01
RETURN Z
LOAD s2, FF
JUMP DONGU3
RETURN ; bu komut calisirsa fonksiyon yanlistir :D
ISR:
INPUT sC, REMOTE ; bluetoothtan veri okunsun
COMPARE sC, ILERI ; komutlari tek tek deniyo, ilerde TEST kullanan
guzel bu hale getirebilirim
JUMP NZ, SECIM2
CALL FORWARD ; bu 1 saniyelik ileri komutu
CALL DELAY_1S
RETURNI ENABLE
SECIM2:
COMPARE sC, SAG
JUMP NZ, SECIM3
CALL RIGHT ; 1 saniyelik sag
CALL DELAY_1S
RETURNI ENABLE
SECIM3:
COMPARE sC, SOL
JUMP NZ, SECIM4
CALL LEFT ; 1 saniyelik sol
CALL DELAY_1S
RETURNI ENABLE
SECIM4:
COMPARE sC, SAGX
JUMP NZ, SECIM5
CALL FORW_R ; 1 saniyelik ileri sag
CALL DELAY_1S
RETURNI ENABLE
SECIM5:
COMPARE sC, SOLX
JUMP NZ, SECIM6
CALL FORW_L ; 1 saniyelik ileri sol
CALL DELAY_1S
RETURNI ENABLE
SECIM6:
COMPARE sC, ILERI2
JUMP NZ, SECIM7
CALL FORWARD ; 3 saniyelik ileri
CALL DELAY_1S
CALL DELAY_1S
CALL DELAY_1S
RETURNI ENABLE
SECIM7:
COMPARE sC, SAG2
JUMP NZ, SECIM8
CALL RIGHT ; 3 saniyelik sag
CALL DELAY_1S
CALL DELAY_1S
CALL DELAY_1S
RETURNI ENABLE
SECIM8:
COMPARE sC, SOL2
JUMP NZ, SECIM9
CALL LEFT ; 3 saniyelik sol
CALL DELAY_1S
CALL DELAY_1S
CALL DELAY_1S
RETURNI ENABLE
SECIM9:
COMPARE sC, SAGX2
JUMP NZ, SECIM10
CALL FORW_R ; 3 saniyelik ileri sag
CALL DELAY_1S
CALL DELAY_1S
CALL DELAY_1S
RETURNI ENABLE
SECIM10:
COMPARE sC, SOLX2
JUMP NZ, SECIM11
CALL FORW_L ; 3 saniyelik ileri SOL
CALL DELAY_1S
CALL DELAY_1S
CALL DELAY_1S
RETURNI ENABLE
SECIM11:
COMPARE sC, HIZLAN
JUMP NZ, SECIM12
COMPARE SPEED, 78 ; hiz zaten max ise atla
JUMP C, GECERSIZ
ADD SPEED, 20 ; degilse 20 eklesin (hexa)
RETURNI ENABLE
SECIM12:
COMPARE sC, YAVASLA
JUMP NZ, GECERSIZ
COMPARE SPEED, 20 ; hiz zaten min ise atla
JUMP C, GECERSIZ
SUB SPEED, 20 ; degilse 20 azalt
RETURNI ENABLE
GECERSIZ:
RETURNI ENABLE ; komut bos ise direk cik
ADDRESS 3FF
JUMP ISR
子模块取自github。 我们的蓝牙verilog代码是:
module uart(
input wire [7:0] din,
input wire wr_en,
input wire clk_50m,
output wire tx,
output wire tx_busy,
input wire rx,
output wire rdy,
input wire rdy_clr,
output reg [7:0] dout,
output tx_,
// input wire select,
output reg interrupt,
input interrupt_ack
);
wire [7:0] rx_dout;
//reg [7:0] dout;
baud_rate_gen uart_baud(
.clk_50m(clk_50m),
.rxclk_en(rxclk_en),
.txclk_en(txclk_en)
);
transmitter uart_tx(
.din(din),
.wr_en(wr_en),
.clk_50m(clk_50m),
.clken(txclk_en),
.tx(tx),
.tx_busy(tx_busy)
);
receiver uart_rx(
.rx(rx),
.rdy(rdy),
.rdy_clr(rdy_clr),
.clk_50m(clk_50m),
.clken(rxclk_en),
.data(rx_dout)
);
assign tx_ = 1;
initial
begin
interrupt = 1'b0;
end
always @ (posedge clk_50m)
begin
if(dout != rx_dout)
begin
dout <= rx_dout;
case(dout)
8'b00000000 : interrupt = 1;
8'b00000001 : interrupt = 1;
8'b00000010 : interrupt = 1;
8'b00000011 : interrupt = 1;
8'b00000100 : interrupt = 1;
8'b00000101 : interrupt = 1;
8'b00000110 : interrupt = 1;
//8'b000000111 :
8'b00001000 : interrupt = 1;
8'b00001001 : interrupt = 1;
8'b00001010 : interrupt = 1;
8'b00001011 : interrupt = 1;
8'b00001100 : interrupt = 1;
default: interrupt = 0;
endcase
end
if(interrupt_ack)
interrupt = 0;
end
endmodule