AG32 的引脚定义
AG32只有模拟相关的IO是固定的,其它数字IO接口可以任意分配。
QFN-32 | Pin name | AG32VFxxxK | AGRV2KQ32 |
1 | PIN_1 | IO/RTC | IO_GB |
2 | PIN_2 | IO/OSC_IN | IO |
3 | PIN_3 | IO/OSC_OUT | IO |
4 | NRST | NRST | NRST |
5 | PIN_5 | IO_ADC_IN12 | IO |
6 | VDDA33 | VDDA33 | VDDA33 |
7 | PIN_7 | IO_WKUP_ADC_IN0_CMP_PA0 | IO |
8 | PIN_8 | IO_ADC_IN1_CMP_PA1 | IO |
9 | PIN_9 | IO_ADC_IN2_CMP_PA2 | IO |
10 | PIN_10 | IO_ADC_IN3_CMP_PA3 | IO |
11 | PIN_11 | IO_ADC_IN4_CMP_PA4_DAC0 | IO |
12 | PIN_12 | IO_ADC_IN5_CMP_PA5_DAC1 | IO |
13 | PIN_13 | IO_ADC_IN6 | IO |
14 | PIN_14 | IO_ADC_IN7 | IO |
15 | PIN_15 | IO_BOOT1 | IO |
16 | VDD33 | VDD33 | VDD33 |
17 | GND | GND | GND |
18 | PIN_18 | IO | IO |
19 | PIN_19 | IO | IO |
20 | PIN_20 | IO_UART0_TX | IO |
21 | PIN_21 | IO_UART0_RX | IO |
22 | PIN_22 | IO_USBDM | IO |
23 | PIN_23 | IO_USBDP | IO |
24 | PIN_24 | IO_JTMS | JTMS |
25 | PIN_25 | IO_JTCK | JTCK |
26 | PIN_26 | IO_JTDI | IO |
27 | PIN_27 | IO_JTDO | IO |
28 | PIN_28 | IO_JNTRST | IO |
29 | PIN_29 | IO | IO |
30 | BOOT0 | BOOT0 | GND |
31 | PIN_31 | IO | IO |
32 | VDD33 | VDD33 | VDD33 |
website: | www.hizyuan.com |
AG32VF407VGT6 LQFP100封装,有5个UART。除了MCU本身带的5个UART,需要更多就用内部FPGA编程实现。
目前我们可以提供新的多串口参考设计,用FPGA逻辑实现了10个,MCU自带5个。总共可以实现15个串口UART通信。
Logic设计相关的参考设计:
multi_uart.v 参考代码:
uart_tx #(DATA_WIDTH, FIFO_DEPTH) u_tx[CNT-1:0](
.clk (apb_clock ),
.rstn (apb_resetn ),
.baud16 (baud16 ),
.tx_write (tx_write ),
.tx_data (apb_pwdata[DATA_WIDTH-1:0]),
.lcr_sps (lcr_sps ),
.lcr_stp2 (lcr_stp2 ),
.lcr_eps (lcr_eps ),
.lcr_pen (lcr_pen ),
.tx_clear (clear_flags ),
.tx_full (tx_full ),
.tx_empty (tx_empty ),
.tx_busy (tx_busy ),
.tx_complete(tx_complete ),
.tx_dma_en (tx_dma_en ),
.tx_dma_clr (tx_dma_clr ),
.tx_dma_req (tx_dma_req ),
.uart_txd (uart_txd )
);
uart_rx #(DATA_WIDTH, FIFO_DEPTH) u_rx[CNT-1:0](
.clk (apb_clock ),
.rstn (apb_resetn ),
.baud16 (baud16 ),
.lcr_sps (lcr_sps ),
.lcr_stp2 (lcr_stp2 ),
.lcr_eps (lcr_eps ),
.lcr_pen (lcr_pen ),
.rx_read (rx_read ),
.rx_clear (clear_flags ),
.rx_full (rx_full ),
.rx_empty (rx_empty ),
.rx_data (rx_data ),
.rx_idle (rx_idle ),
.framing_error(framing_error),
.parity_error (parity_error ),
.break_error (break_error ),
.overrun_error(overrun_error),
.rx_dma_en (rx_dma_en ),
.rx_dma_clr (rx_dma_clr ),
.rx_dma_req (rx_dma_req ),
.uart_rxd (uart_rxd )
);
endmodule
uart_rx.v 参考代码:
module uart_rx #(parameter DATA_WIDTH = 8, FIFO_DEPTH = 4) (
input clk,
input rstn,
input baud16,
input uart_rxd,
input lcr_sps,
input lcr_stp2,
input lcr_eps,
input lcr_pen,
input rx_read,
input rx_clear,
output rx_full,
output rx_empty,
output [DATA_WIDTH-1:0] rx_data,
output reg rx_idle,
input rx_dma_en,
input rx_dma_clr,
output reg rx_dma_req,
output reg framing_error,
output reg parity_error,
output reg break_error,
output reg overrun_error
);
parameter UART_IDLE = 3'h0;
parameter UART_START = 3'h1;
parameter UART_DATA = 3'h2;
parameter UART_PARITY = 3'h3;
parameter UART_STOP = 3'h4;
parameter BAUD_CNT = 16;
parameter SAMPLE_CNT = 3;
reg [2:0] rx_state;
reg [SAMPLE_CNT+1:0] rx_in; // 2 extra bits for synchronization
reg [1:0] rx_val;
reg [3:0] rx_baud_cnt;
reg rx_bit;
reg rx_parity;
reg [$clog2(DATA_WIDTH):0] rx_data_cnt;
reg [DATA_WIDTH-1:0] rx_shift_reg;
reg rx_idle_en;
wire rx_lo = rx_val <= 1;
wire rx_hi = !rx_lo;
wire rx_sample = baud16 && rx_baud_cnt == BAUD_CNT / 2 + 1; // Where to sample rx input
wire fifo_wren = rx_state == UART_STOP && rx_sample;
sync_fifo #(.WIDTH(DATA_WIDTH), .DEPTH(FIFO_DEPTH), .SHOWAEAD(1)) rx_fifo(
.clk (clk ),
.rstn (rstn ),
.wren (fifo_wren ),
.rden (rx_read ),
.din (rx_shift_reg),
.dout (rx_data ),
.full (rx_full ),
.empty(rx_empty )
);
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
rx_in <= {SAMPLE_CNT+1{1'b1}};
end else if (baud16) begin
rx_in <= { rx_in[SAMPLE_CNT:0], uart_rxd };
end
end
integer i;
always @(*) begin
rx_val = 0;
for (i = 2; i < SAMPLE_CNT + 2; i = i + 1)
rx_val = rx_val + rx_in[i];
end
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
rx_bit <= 1'b0;
end else if (baud16 && rx_baud_cnt == 15) begin
rx_bit <= 1'b1;
end else begin
rx_bit <= 1'b0;
end
end
always @(posedge clk) begin
if (rx_state == UART_START) begin
rx_data_cnt <= DATA_WIDTH - 1;
end else if (rx_bit) begin
if (rx_state == UART_DATA && rx_data_cnt == 0) begin
rx_data_cnt <= DATA_WIDTH + 1 + lcr_pen + lcr_stp2;
end else begin
rx_data_cnt <= rx_data_cnt - 1;
end
end
end
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
rx_shift_reg <= 0;
end else if (rx_state == UART_DATA && rx_sample) begin
rx_shift_reg <= { rx_hi, rx_shift_reg[DATA_WIDTH-1:1] };
end
end
always @(posedge clk) begin
if (rx_state == UART_START) begin
rx_parity <= !lcr_eps;
end else if (rx_state == UART_DATA && rx_bit && !lcr_sps) begin
rx_parity <= rx_parity ^ rx_shift_reg[7];
end
end
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
rx_baud_cnt <= 0;
end else if (rx_state == UART_IDLE && rx_lo) begin
rx_baud_cnt <= SAMPLE_CNT - 1;
end else if (baud16) begin
rx_baud_cnt <= rx_baud_cnt + 1;
end
end
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
rx_idle_en <= 1'b0;
end else if (!rx_empty) begin
rx_idle_en <= 1'b1;
end else if (rx_clear) begin
rx_idle_en <= 1'b0;
end
end
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
rx_idle <= 1'b0;
end else if (rx_state == UART_IDLE && rx_data_cnt == 0 && rx_bit && rx_idle_en) begin
rx_idle <= 1'b1;
end else if (rx_clear) begin
rx_idle <= 1'b0;
end
end
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
framing_error <= 1'b0;
end else if (rx_state == UART_STOP && rx_sample && rx_lo) begin
framing_error <= 1'b1;
end else if (rx_clear) begin
framing_error <= 1'b0;
end
end
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
parity_error <= 1'b0;
end else if (rx_state == UART_PARITY && rx_sample && rx_parity != rx_hi) begin
parity_error <= 1'b1;
end else if (rx_clear) begin
parity_error <= 1'b0;
end
end
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
break_error <= 1'b0;
end else if (rx_state == UART_STOP && rx_sample && rx_lo && rx_shift_reg == 0) begin
break_error <= 1'b1;
end else if (rx_clear) begin
break_error <= 1'b0;
end
end
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
overrun_error <= 1'b0;
end else if (fifo_wren && rx_full) begin
overrun_error <= 1'b1;
end else if (rx_clear) begin
overrun_error <= 1'b0;
end
end
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
rx_dma_req <= 1'b0;
end else if (!rx_dma_en || rx_dma_clr) begin
rx_dma_req <= 1'b0;
end else if (!rx_empty) begin
rx_dma_req <= 1'b1;
end
end
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
rx_state <= UART_IDLE;
end else begin
case (rx_state)
UART_IDLE: if (rx_lo) rx_state <= UART_START;
UART_START: if (rx_bit && rx_baud_cnt == 0) rx_state <= UART_DATA;
UART_DATA: if (rx_bit && rx_data_cnt == 0) rx_state <= lcr_pen ? UART_PARITY : UART_STOP;
UART_PARITY: if (rx_bit) rx_state <= UART_STOP;
UART_STOP: if (rx_sample && rx_hi) rx_state <= UART_IDLE;
endcase
end
end
endmodule
更多参考设计,欢迎私信交流沟通。