module servo_pwm_top(
input clk, reset_p,
input [3:0] btn,
output reg [2:0] led,
output motor_pwm,
output [3:0] com,
output [7:0] seg_7);
reg [31:0] clk_div;
always @(posedge clk or posedge reset_p)begin
if(reset_p) clk_div = 0;
else clk_div = clk_div + 1;
end
// wire clk_div_26_nedge;
// edge_detector_n ed(
// .clk(clk), .reset_p(reset_p), .cp(clk_div[25]),
// .n_edge(clk_div_26_nedge));
wire btn_ctr0, btn_ctr1, btn_ctr2, btn_ctr3;
button_cntr btn0(.clk(clk), .reset_p(reset_p), .btn(btn[0]), .btn_pedge(btn_ctr0)); //버튼 채터링 방지
button_cntr btn1(.clk(clk), .reset_p(reset_p), .btn(btn[1]), .btn_pedge(btn_ctr1)); //버튼 채터링 방지
button_cntr btn2(.clk(clk), .reset_p(reset_p), .btn(btn[2]), .btn_pedge(btn_ctr2)); //버튼 채터링 방지
button_cntr btn3(.clk(clk), .reset_p(reset_p), .btn(btn[3]), .btn_pedge(btn_ctr3)); //버튼 채터링 방지
// wire btn_nedge0, btn_nedge1, btn_nedge2, btn_nedge3;
// edge_detector_n ed0(
// .clk(clk), .reset_p(reset_p), .cp(btn_ctr0),
// .n_edge(btn_nedge0));
// edge_detector_n ed1(
// .clk(clk), .reset_p(reset_p), .cp(btn_ctr1),
// .n_edge(btn_nedge1));
// edge_detector_n ed2(
// .clk(clk), .reset_p(reset_p), .cp(btn_ctr2),
// .n_edge(btn_nedge2));
// edge_detector_n ed3(
// .clk(clk), .reset_p(reset_p), .cp(btn_ctr3),
// .n_edge(btn_nedge3));
reg [1:0] cnt_btn;
always @(negedge clk or posedge reset_p)begin
if(reset_p)begin
cnt_btn = 1;
end
else if(btn_ctr0)begin
if(cnt_btn>=3)begin
cnt_btn = 0;
end
cnt_btn = cnt_btn + 1;
end
else if(btn_ctr1)cnt_btn = 1;
else if(btn_ctr2)cnt_btn = 2;
else if(btn_ctr3)cnt_btn = 3;
end
always @(negedge clk or posedge reset_p)begin
if(reset_p)begin
led = 3'b000;
end
else if(cnt_btn == 1)begin
led = 3'b001;
end
else if(cnt_btn == 2)begin
led = 3'b010;
end
else if(cnt_btn == 3)begin
led = 3'b100;
end
end
reg [6:0] duty;
always @(negedge clk or posedge reset_p)begin
if(reset_p) duty = 5;
else if(cnt_btn == 1)begin
duty = 5;
end
else if(cnt_btn == 2)begin
duty = 14;
end
else if(cnt_btn == 3)begin
duty = 24;
end
end
pwm_Nstep_freq #( //pwm컨트롤 모듈
.duty_step(200), //듀티폭을 100단계로 나눔
.pwm_freq(50)) //연결한 센서에 따라다름, 데이터시트에 필요한 주파수 있음
pwm_b(
.clk(clk),
.reset_p(reset_p),
.duty(duty),
.pwm(motor_pwm));
wire [15:0] duty_bcd;
bin_to_dec bcd_humi(.bin({6'b0, duty}), .bcd(duty_bcd));
fnd_cntr fnd (.clk(clk), .reset_p(reset_p), .value(duty_bcd), .com(com), .seg_7(seg_7));
endmodule
module servo_pwm_top(
input clk, reset_p,
input [3:0] btn,
output reg [2:0] led,
output motor_pwm,
output [3:0] com,
output [7:0] seg_7);
reg [31:0] clk_div;
always @(posedge clk or posedge reset_p)begin
if(reset_p) clk_div = 0;
else clk_div = clk_div + 1;
end
// wire clk_div_26_nedge;
// edge_detector_n ed(
// .clk(clk), .reset_p(reset_p), .cp(clk_div[25]),
// .n_edge(clk_div_26_nedge));
wire btn_ctr0, btn_ctr1, btn_ctr2, btn_ctr3;
button_cntr btn0(.clk(clk), .reset_p(reset_p), .btn(btn[0]), .btn_pedge(btn_ctr0)); //버튼 채터링 방지
button_cntr btn1(.clk(clk), .reset_p(reset_p), .btn(btn[1]), .btn_pedge(btn_ctr1)); //버튼 채터링 방지
button_cntr btn2(.clk(clk), .reset_p(reset_p), .btn(btn[2]), .btn_pedge(btn_ctr2)); //버튼 채터링 방지
button_cntr btn3(.clk(clk), .reset_p(reset_p), .btn(btn[3]), .btn_pedge(btn_ctr3)); //버튼 채터링 방지
// wire btn_nedge0, btn_nedge1, btn_nedge2, btn_nedge3;
// edge_detector_n ed0(
// .clk(clk), .reset_p(reset_p), .cp(btn_ctr0),
// .n_edge(btn_nedge0));
// edge_detector_n ed1(
// .clk(clk), .reset_p(reset_p), .cp(btn_ctr1),
// .n_edge(btn_nedge1));
// edge_detector_n ed2(
// .clk(clk), .reset_p(reset_p), .cp(btn_ctr2),
// .n_edge(btn_nedge2));
// edge_detector_n ed3(
// .clk(clk), .reset_p(reset_p), .cp(btn_ctr3),
// .n_edge(btn_nedge3));
reg [1:0] cnt_btn;
always @(negedge clk or posedge reset_p)begin
if(reset_p)begin
cnt_btn = 1;
end
else if(btn_ctr0)begin
if(cnt_btn>=3)begin
cnt_btn = 0;
end
cnt_btn = cnt_btn + 1;
end
end
always @(negedge clk or posedge reset_p)begin
if(reset_p)begin
led = 3'b000;
end
else if(cnt_btn == 1)begin
led = 3'b001;
end
else if(cnt_btn == 2)begin
led = 3'b010;
end
else if(cnt_btn == 3)begin
led = 3'b100;
end
end
reg [6:0] duty;
always @(negedge clk or posedge reset_p)begin
if(reset_p) duty = 5;
else if(btn_ctr1 || cnt_btn == 1)begin
duty = 5;
end
else if(btn_ctr2 || cnt_btn == 2)begin
duty = 14;
end
else if(btn_ctr1 || cnt_btn == 3)begin
duty = 24;
end
end
pwm_Nstep_freq #(
.duty_step(200), //듀티폭을 100단계로 나눔
.pwm_freq(50)) //연결한 센서에 따라다름, 데이터시트에 필요한 주파수 있음
pwm_b(
.clk(clk),
.reset_p(reset_p),
.duty(duty),
.pwm(motor_pwm));
wire [15:0] duty_bcd;
bin_to_dec bcd_humi(.bin({6'b0, duty}), .bcd(duty_bcd));
fnd_cntr fnd (.clk(clk), .reset_p(reset_p), .value(duty_bcd), .com(com), .seg_7(seg_7));
endmodule
동작하는 부분에서 btn_ctr을 눌러 or연산으로 같이 동작하게 만드려했지만, 짧게 나온 btn_ctr의 엣지가 지나면 저장된 cnt_btn의 값으로 다시 되돌아가서 결국 btn_ctr는 반응하지 않는것처럼 된다
클락에 의한 동작, 방향 왕복
module surbo_motor(
input clk, reset_p,
output [3:0] com,
output [7:0] seg_7,
output surbo_pwm
);
reg [31:0] clk_div;
always @(posedge clk or posedge reset_p) begin
if (reset_p)
clk_div = 0;
else
clk_div = clk_div + 1;
end
wire clk_div_24_nedge;
edge_detector_n ed(
.clk(clk),
.reset_p(reset_p),
.cp(clk_div[24]),
.n_edge(clk_div_24_nedge)
);
reg [6:0] duty; // duty 레지스터의 크기를 8비트로 설정
reg direction; // 방향 제어를 위한 플래그
always @(posedge clk or posedge reset_p) begin
if (reset_p) begin
duty = 5 ; // 초기화 1ms (5% 듀티 사이클)
direction = 0; // 초기 방향 설정 (0: 증가, 1: 감소)
end
else if (clk_div_24_nedge) begin // 20ms 주기
if (!direction) begin
if (duty < 24) // 2ms (10%)에 도달하지 않았다면 증가
duty = duty + 1;
else
direction = 1; // 2ms에 도달하면 방향을 감소로 변경
end
else begin
if (duty > 4) // 1ms (5%)에 도달하지 않았다면 감소
duty = duty - 1;
else
direction = 0; // 1ms에 도달하면 방향을 증가로 변경
end
end
end
pwm_Nstep_freq #(
.duty_step(200), // 100단계로 나눔
.pwm_freq(50) // PWM 주파수 50Hz
) pwm_motor(
.clk(clk),
.reset_p(reset_p),
.duty(duty),
.pwm(surbo_pwm)
);
wire [15:0] duty_bcd;
bin_to_dec bcd_surbo(
.bin({8'b0, duty}),
.bcd(duty_bcd)
);
// fnd_cntr 모듈 인스턴스
fnd_cntr fnd_cntr_inst(
.clk(clk),
.reset_p(reset_p),
.value(duty_bcd),
.com(com),
.seg_7(seg_7)
);
endmodule
module surbo_motor(
input clk, reset_p,
input [3:0] btn,
output [3:0] com,
output [7:0] seg_7,
output surbo_pwm
);
wire btn_ctr0, btn_ctr1, btn_ctr2, btn_ctr3;
button_cntr btn0(.clk(clk), .reset_p(reset_p), .btn(btn[0]), .btn_pedge(btn_ctr0)); //버튼 채터링 방지
button_cntr btn1(.clk(clk), .reset_p(reset_p), .btn(btn[1]), .btn_pedge(btn_ctr1)); //버튼 채터링 방지
button_cntr btn2(.clk(clk), .reset_p(reset_p), .btn(btn[2]), .btn_pedge(btn_ctr2)); //버튼 채터링 방지
button_cntr btn3(.clk(clk), .reset_p(reset_p), .btn(btn[3]), .btn_pedge(btn_ctr3)); //버튼 채터링 방지
reg [31:0] clk_div;
always @(posedge clk or posedge reset_p) begin
if (reset_p)
clk_div = 0;
else
clk_div = clk_div + 1;
end
wire clk_div_24_nedge;
edge_detector_n ed(
.clk(clk),
.reset_p(reset_p),
.cp(clk_div[24]),
.n_edge(clk_div_24_nedge)
);
reg [6:0] duty; // duty 레지스터의 크기를 8비트로 설정
reg direction; // 방향 제어를 위한 플래그
reg [6:0] duty_min, duty_max;
always @(posedge clk or posedge reset_p) begin
if (reset_p) begin
duty = 12 ; // 초기화 1ms (5% 듀티 사이클)
direction = 0; // 초기 방향 설정 (0: 증가, 1: 감소)
duty_min = 12;
duty_max = 50;
end
else if (clk_div_24_nedge) begin // 20ms 주기
if (!direction) begin
if (duty < duty_max) // 2ms (10%)에 도달하지 않았다면 증가
duty = duty + 1;
else
direction = 1; // 2ms에 도달하면 방향을 감소로 변경
end
else begin
if (duty > duty_min) // 1ms (5%)에 도달하지 않았다면 감소
duty = duty - 1;
else
direction = 0; // 1ms에 도달하면 방향을 증가로 변경
end
end
else if(btn_ctr0)direction = ~direction;
else if(btn_ctr1)duty_min = 30;
else if(btn_ctr2)duty_max = 40;
end
pwm_Nstep_freq #(
.duty_step(400), // 100단계로 나눔
.pwm_freq(50) // PWM 주파수 50Hz
) pwm_motor(
.clk(clk),
.reset_p(reset_p),
.duty(duty),
.pwm(surbo_pwm)
);
wire [15:0] duty_bcd;
bin_to_dec bcd_surbo(
.bin({8'b0, duty}),
.bcd(duty_bcd)
);
// fnd_cntr 모듈 인스턴스
fnd_cntr fnd_cntr_inst(
.clk(clk),
.reset_p(reset_p),
.value(duty_bcd),
.com(com),
.seg_7(seg_7)
);
endmodule
module surbo_motor(
input clk, reset_p,
input [3:0] btn,
output [3:0] com,
output [7:0] seg_7,
output surbo_pwm
);
wire btn_ctr0, btn_ctr1, btn_ctr2, btn_ctr3;
button_cntr btn0(.clk(clk), .reset_p(reset_p), .btn(btn[0]), .btn_pedge(btn_ctr0)); //버튼 채터링 방지
button_cntr btn1(.clk(clk), .reset_p(reset_p), .btn(btn[1]), .btn_pedge(btn_ctr1)); //버튼 채터링 방지
button_cntr btn2(.clk(clk), .reset_p(reset_p), .btn(btn[2]), .btn_pedge(btn_ctr2)); //버튼 채터링 방지
button_cntr btn3(.clk(clk), .reset_p(reset_p), .btn(btn[3]), .btn_pedge(btn_ctr3)); //버튼 채터링 방지
reg [31:0] clk_div;
always @(posedge clk or posedge reset_p) begin
if (reset_p)
clk_div = 0;
else
clk_div = clk_div + 1;
end
wire clk_div_24_nedge;
edge_detector_n ed(
.clk(clk),
.reset_p(reset_p),
.cp(clk_div[24]),
.n_edge(clk_div_24_nedge)
);
reg [6:0] duty; // duty 레지스터의 크기를 8비트로 설정
reg direction; // 방향 제어를 위한 플래그
reg [6:0] duty_min, duty_max;
always @(posedge clk or posedge reset_p) begin
if (reset_p) begin
duty = 12 ; // 초기화 1ms (5% 듀티 사이클)
direction = 0; // 초기 방향 설정 (0: 증가, 1: 감소)
duty_min = 12;
duty_max = 50;
end
else if (clk_div_24_nedge) begin // 20ms 주기
if (!direction) begin
if (duty < duty_max) // 2ms (10%)에 도달하지 않았다면 증가
duty = duty + 1;
else
direction = 1; // 2ms에 도달하면 방향을 감소로 변경
end
else begin
if (duty > duty_min) // 1ms (5%)에 도달하지 않았다면 감소
duty = duty - 1;
else
direction = 0; // 1ms에 도달하면 방향을 증가로 변경
end
end
else if(btn_ctr0)direction = ~direction;
else if(btn_ctr1)duty_min = duty; //수정한곳
else if(btn_ctr2)duty_max = duty; //수정한곳
end
pwm_Nstep_freq #(
.duty_step(400), // 100단계로 나눔
.pwm_freq(50) // PWM 주파수 50Hz
) pwm_motor(
.clk(clk),
.reset_p(reset_p),
.duty(duty),
.pwm(surbo_pwm)
);
wire [15:0] duty_bcd;
bin_to_dec bcd_surbo(
.bin({8'b0, duty}),
.bcd(duty_bcd)
);
// fnd_cntr 모듈 인스턴스
fnd_cntr fnd_cntr_inst(
.clk(clk),
.reset_p(reset_p),
.value(duty_bcd),
.com(com),
.seg_7(seg_7)
);
endmodule
가변저항

빨주노초파보 사용 남색은 파랑과 비슷해서 안씀
검 갈 빨주노초파보 회 백
0 1 2 3 4 5 6 7 8 9
금색 또는 은색이 맨 오른쪽 끝에있고 오차를 나타냄 왼쪽 부터 읽음

끝에 숫자는 0의 갯수, 사진의 331은 330옴
module adc_ch6_top(
input clk, reset_p,
input vauxp6, vauxn6,
output [3:0] com,
output [7:0] seg_7);
wire [4:0] channel_out;
wire [15:0] do_out;
wire eoc_out;
xadc_wiz_0 adc_6
(
.daddr_in({2'b0, channel_out}), // 채널 주소 넘겨받음 //주소 버스 //addr은 7비트 channel_out은 5비트 // Address bus for the dynamic reconfiguration port
.dclk_in(clk), //클럭 입력 // Clock input for the dynamic reconfiguration port
.den_in(eoc_out), //활성화 신호 // Enable Signal for the dynamic reconfiguration port
// di_in, //입력 데이터 버스// Input data bus for the dynamic reconfiguration port
// dwe_in, //쓰기 활성화 // Write Enable for the dynamic reconfiguration port
.reset_in(reset_p), //리셋 신호// Reset signal for the System Monitor control logic
.vauxp6(vauxp6), //JXADC포트로 아날로그 신호 입력받음, XDC 변경 필요 //채널6 양극// Auxiliary channel 6
.vauxn6(vauxn6), //JXADC포트로 아날로그 신호 입력받음, XDC 변경 필요 //채널6 음극
// busy_out, //adc작동 중 신호 // ADC Busy signal
// drdy_out, //데이터 준비 신호 // Data ready signal for the dynamic reconfiguration port
.channel_out(channel_out), //채널6, 현재 단일 채널로서 하나만 있음 //채널 선택 출력 // Channel Selection Outputs
.do_out(do_out), //아날로그가 디지털로 변환된 값을 출력 //출력 데이터 버스 //adc값 들어있음 // Output data bus for dynamic reconfiguration port
.eoc_out(eoc_out) //변환 완료 신호 //adc변환이 끝나면 1나옴 // End of Conversion Signal
// eos_out, //시퀀스 완료 신호 // End of Sequence Signal
// alarm_out, //모든 알람의 출력// OR'ed output of all the Alarms
);
wire [15:0] adc_value;
bin_to_dec bcd_adc(
.bin(do_out[15:4]),
.bcd(adc_value)
);
fnd_cntr fnd_cntr_inst(
.clk(clk),
.reset_p(reset_p),
.value(adc_value),
.com(com),
.seg_7(seg_7)
);
endmodule
비트수를 줄여 정밀도를 낮춘대신 잡음을 제거
module adc_ch6_top(
input clk, reset_p,
input vauxp6, vauxn6,
output [3:0] com,
output [7:0] seg_7);
wire [4:0] channel_out;
wire [15:0] do_out;
wire eoc_out;
xadc_wiz_0 adc_6
(
.daddr_in({2'b0, channel_out}), // 채널 주소 넘겨받음 //주소 버스 //addr은 7비트 channel_out은 5비트 // Address bus for the dynamic reconfiguration port
.dclk_in(clk), //클럭 입력 // Clock input for the dynamic reconfiguration port
.den_in(eoc_out), //활성화 신호 // Enable Signal for the dynamic reconfiguration port
// di_in, //입력 데이터 버스// Input data bus for the dynamic reconfiguration port
// dwe_in, //쓰기 활성화 // Write Enable for the dynamic reconfiguration port
.reset_in(reset_p), //리셋 신호// Reset signal for the System Monitor control logic
.vauxp6(vauxp6), //JXADC포트로 아날로그 신호 입력받음, XDC 변경 필요 //채널6 양극// Auxiliary channel 6
.vauxn6(vauxn6), //JXADC포트로 아날로그 신호 입력받음, XDC 변경 필요 //채널6 음극
// busy_out, //adc작동 중 신호 // ADC Busy signal
// drdy_out, //데이터 준비 신호 // Data ready signal for the dynamic reconfiguration port
.channel_out(channel_out), //채널6, 현재 단일 채널로서 하나만 있음 //채널 선택 출력 // Channel Selection Outputs
.do_out(do_out), //아날로그가 디지털로 변환된 값을 출력 //출력 데이터 버스 //adc값 들어있음 // Output data bus for dynamic reconfiguration port
.eoc_out(eoc_out) //변환 완료 신호 //adc변환이 끝나면 1나옴 // End of Conversion Signal
// eos_out, //시퀀스 완료 신호 // End of Sequence Signal
// alarm_out, //모든 알람의 출력// OR'ed output of all the Alarms
);
wire [15:0] adc_value;
bin_to_dec bcd_adc(
.bin({2'b0, do_out[15:6]}), //비트 줄임, 수정된곳
.bcd(adc_value)
);
fnd_cntr fnd_cntr_inst(
.clk(clk),
.reset_p(reset_p),
.value(adc_value),
.com(com),
.seg_7(seg_7)
);
endmodule
module adc_ch6_top(
input clk, reset_p,
input vauxp6, vauxn6,
output [3:0] com,
output [7:0] seg_7,
output led_pwm);
wire [4:0] channel_out;
wire [15:0] do_out;
wire eoc_out;
xadc_wiz_0 adc_6
(
.daddr_in({2'b0, channel_out}), // 채널 주소 넘겨받음 //주소 버스 //addr은 7비트 channel_out은 5비트 // Address bus for the dynamic reconfiguration port
.dclk_in(clk), //클럭 입력 // Clock input for the dynamic reconfiguration port
.den_in(eoc_out), //활성화 신호 // Enable Signal for the dynamic reconfiguration port
// di_in, //입력 데이터 버스// Input data bus for the dynamic reconfiguration port
// dwe_in, //쓰기 활성화 // Write Enable for the dynamic reconfiguration port
.reset_in(reset_p), //리셋 신호// Reset signal for the System Monitor control logic
.vauxp6(vauxp6), //JXADC포트로 아날로그 신호 입력받음, XDC 변경 필요 //채널6 양극// Auxiliary channel 6
.vauxn6(vauxn6), //JXADC포트로 아날로그 신호 입력받음, XDC 변경 필요 //채널6 음극
// busy_out, //adc작동 중 신호 // ADC Busy signal
// drdy_out, //데이터 준비 신호 // Data ready signal for the dynamic reconfiguration port
.channel_out(channel_out), //채널6, 현재 단일 채널로서 하나만 있음 //채널 선택 출력 // Channel Selection Outputs
.do_out(do_out), //아날로그가 디지털로 변환된 값을 출력 //출력 데이터 버스 //adc값 들어있음 // Output data bus for dynamic reconfiguration port
.eoc_out(eoc_out) //변환 완료 신호 //adc변환이 끝나면 1나옴 // End of Conversion Signal
// eos_out, //시퀀스 완료 신호 // End of Sequence Signal
// alarm_out, //모든 알람의 출력// OR'ed output of all the Alarms
);
pwm_Nstep_freq #(
.duty_step(256), //trueColor, 8bit, 사람이 느낄 수 있는 색 변화
.pwm_freq(10000) // PWM 주파수 10000Hz, led를 위한 주파수
) pwm_backlight(
.clk(clk),
.reset_p(reset_p),
.duty(do_out[15:8]), //10비트중 트루컬러 8비트만 사용
.pwm(led_pwm) ////XDC파일 LED부분으로 출력
);
wire [15:0] adc_value;
bin_to_dec bcd_adc(
.bin({2'b0, do_out[15:6]}), //16비트의 출력을 상위 12비트로만 디지털화 가능, 잡음제거를 위해 10비트만 사용 //bin입력의 12비트크기를 맞추기 위해 상위 2비트 0으로 채움
.bcd(adc_value)
);
fnd_cntr fnd_cntr_inst(
.clk(clk),
.reset_p(reset_p),
.value(adc_value),
.com(com),
.seg_7(seg_7)
);
endmodule