首页 > 其他分享 >05 AXI4总线axi-full-master

05 AXI4总线axi-full-master

时间:2023-12-30 14:55:06浏览次数:27  
标签:begin full end 05 burst axi else master AXI

软件版本:vitis2021.1(vivado2021.1)

操作系统:WIN10 64bit

硬件平台:适用XILINX A7/K7/Z7/ZU/KU系列FPGA

登录"米联客"FPGA社区-www.uisrc.com视频课程、答疑解惑!

1概述

使用XILINX 的软件工具VIVADO以及XILINX的7代以上的FPGA或者SOC掌握AXI-4总线结束,并且可以灵活使用AXI-4总线技术完成数据的交换,可以让我们在构建强大的FPGA内部总线数据互联通信方面取得高效、高速、标准化的优势。

关于AXI4总线协议的部分介绍请阅读"01AXI4总线axi-lite-slave"。

本文实验目的:

1:掌握基于VIVADO工具产生AXI协议模板

2:掌握通过VIVADO工具产生AXI-full-master代码

3:理解AXI-full-master中自定义寄存器的地址分配

4:掌握通过VIVADO封装AXI-full-slave图形化IP

5:通过仿真验证AXI-full-master IP的工作是否正常。

2创建axi4-full-master总线接口IP

新建fpga工程,过程省略

新建完成工程后,单击菜单栏Tools->Create and Package New IP,开始创建一个AXI4-Full接口总线IP

选择使用vivado自带的AXI总线模板创建一个AXI4-FULL接口IP

设置IP的名字为maxi_full

模板支持3种协议,分别是AXI4-Full ,AXI4-Lite ,AXI4-Stream,这选择Full;总线包括Master和Slave两种模式,这里选择Master模式

这里选择Verify Peripheral IP using AXI4 VIP可以对AXI4-Lite快速验证

单击Finish后展开VIVADO自动产生的demo,单击Block Design的工程,可以看到如下2个IP。其中maxi_full_0就是我们自定义的IP,另外一个slave_0是用来验证maxi_full_0正确性。

采用默认地址分配即可

继续再看代码看看里面有什么东西

路径uisrc/03_ip/ maxi_full_1.0/hdl路径下的maxi_full_v1_0_M00_AXI.v就是我们的源码。另外一个maxi_full_v1_0.v是软件产生了一个接口文件,如果我们自己定义IP可有可无。

3程序分析

axi总线信号的关键无非是地址和数据,而写地址的有效取决于AXI_AWVALID和AXI_AWREADY,写数据的有效取决于S_AXI_WVALID和S_AXI_WREADY。同理,读地址的有效取决于AXI_ARVALID和AXI_ARREADY,读数据的有效取决于S_AXI_RVALID和S_AXI_RREADY。所以以下代码的阅读分析注意也是围绕以上4个信号的有效时序。

以下程序我们把关键信号的代码拆分阅读

1:产生初始化信号

    //Generate a pulse to initiate AXI transaction.

    always @(posedge M_AXI_ACLK)                                              

      begin                                                                        

        // Initiates AXI transaction delay    

        if (M_AXI_ARESETN == 0 )                                                  

          begin                                                                    

            init_txn_ff <= 1'b0;                                                  

            init_txn_ff2 <= 1'b0;                                                  

          end                                                                              

        else                                                                      

          begin  

            init_txn_ff <= INIT_AXI_TXN;

            init_txn_ff2 <= init_txn_ff;                                                                

          end                                                                      

      end    

2:axi-full-master的axi_awvalid

当(~axi_awvalid && start_single_burst_write)==1条件满足,开始一次写传输,设置axi_awvalid有效。

      always @(posedge M_AXI_ACLK)                                  

      begin                                                                

                                                                             

        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 )                                          

          begin                                                            

            axi_awvalid <= 1'b0;                                          

          end                                                              

        // If previously not valid , start next transaction                

        else if (~axi_awvalid && start_single_burst_write)                

          begin                                                            

            axi_awvalid <= 1'b1;                                          

          end                                                              

        /* Once asserted, VALIDs cannot be deasserted, so axi_awvalid      

        must wait until transaction is accepted */                        

        else if (M_AXI_AWREADY && axi_awvalid)                            

          begin                                                            

            axi_awvalid <= 1'b0;                                          

          end                                                              

        else                                                              

          axi_awvalid <= axi_awvalid;                                      

        end    

3:axi-full-slave的axi_awaddr

写通道地址每当M_AXI_AWREADY && axi_awvalid地址加1

    // Next address after AWREADY indicates previous address acceptance    

      always @(posedge M_AXI_ACLK)                                        

      begin                                                                

        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)                                            

          begin                                                            

            axi_awaddr <= 'b0;                                            

          end                                                              

        else if (M_AXI_AWREADY && axi_awvalid)                            

          begin                                                            

            axi_awaddr <= axi_awaddr + burst_size_bytes;                  

          end                                                              

        else                                                              

          axi_awaddr <= axi_awaddr;                                        

        end

4:axi-full-master的axi_wvalid

设置axi_wvalid <= 1'b1开始写数据。wnext信号有效代码axi_full_master写数据有效。

      assign wnext = M_AXI_WREADY & axi_wvalid;                                  

                                                                                         

    // WVALID logic, similar to the axi_awvalid always block above                      

      always @(posedge M_AXI_ACLK)                                                      

      begin                                                                            

        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 )                                                        

          begin                                                                        

            axi_wvalid <= 1'b0;                                                        

          end                                                                          

        // If previously not valid, start next transaction                              

        else if (~axi_wvalid && start_single_burst_write)                              

          begin                                                                        

            axi_wvalid <= 1'b1;                                                        

          end                                                                          

        /* If WREADY and too many writes, throttle WVALID                              

        Once asserted, VALIDs cannot be deasserted, so WVALID                          

        must wait until burst is complete with WLAST */                                

        else if (wnext && axi_wlast)                                                    

          axi_wvalid <= 1'b0;                                                          

        else                                                                            

          axi_wvalid <= axi_wvalid;                                                    

      end  

5:axi-full-master的axi_master_last

axi_master_last信号,当条件满足(((write_index == C_M_AXI_BURST_LEN-2 && C_M_AXI_BURST_LEN >= 2) && wnext) || (C_M_AXI_BURST_LEN == 1 ))==1的时候,axi_wlast <= 1'b1。这是VIVADO自带的模板,但是这里有个bug,那就是必须确保slave可以连续接收数据,假设发送last的时候wnext==0,这样就不能把最后一个数据正确写入到slave中了。

//WLAST generation on the MSB of a counter underflow                                

    // WVALID logic, similar to the axi_awvalid always block above                      

      always @(posedge M_AXI_ACLK)                                                      

      begin                                                                            

        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 )                                                        

          begin                                                                        

            axi_wlast <= 1'b0;                                                          

          end                                                                          

        // axi_wlast is asserted when the write index                                  

        // count reaches the penultimate count to synchronize                          

        // with the last write data when write_index is b1111                          

        // else if (&(write_index[C_TRANSACTIONS_NUM-1:1])&& ~write_index[0] && wnext)  

        else if (((write_index == C_M_AXI_BURST_LEN-2 && C_M_AXI_BURST_LEN >= 2) && wnext) || (C_M_AXI_BURST_LEN == 1 ))

          begin                                                                        

            axi_wlast <= 1'b1;                                                          

          end                                                                          

        // Deassrt axi_wlast when the last write data has been                          

        // accepted by the slave with a valid response                                  

        else if (wnext)                                                                

          axi_wlast <= 1'b0;                                                            

        else if (axi_wlast && C_M_AXI_BURST_LEN == 1)                                  

          axi_wlast <= 1'b0;                                                            

        else                                                                            

          axi_wlast <= axi_wlast;                                                      

      end        

删除以上代码,并且添加以下代码:

      wire  wlast=(write_index==C_M_AXI_BURST_LEN-1)&&wnext;                                                        

      reg   wlast_r1 = 1'b0;

      always @(posedge M_AXI_ACLK)

        wlast_r <= wlast;

      assign   axi_wlast = (wlast_r==1'b0)&&(wlast==1'b1);  

另外需要修改reg axi_wlast;为wire axi_wlast;

这样就可以确保发送wlast的时候数据肯定是有效的。

6:写次数记录write_index计数器

/* Burst length counter. Uses extra counter register bit to indicate terminal      

     count to reduce decode logic */                                                    

      always @(posedge M_AXI_ACLK)                                                      

      begin                                                                            

        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 || start_single_burst_write == 1'b1)    

          begin                                                                        

            write_index <= 0;                                                          

          end                                                                          

        else if (wnext && (write_index != C_M_AXI_BURST_LEN-1))                        

          begin                                                                        

            write_index <= write_index + 1;                                            

          end                                                                          

        else                                                                            

          write_index <= write_index;                                                  

      end                      

7:axi-full-master的axi_wdata

axi_full_master写数据计数写数据

    /* Write Data Generator                                                            

     Data pattern is only a simple incrementing count from 0 for each burst  */        

      always @(posedge M_AXI_ACLK)                                                      

      begin                                                                            

        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)                                                        

          axi_wdata <= 'b1;                                                            

        //else if (wnext && axi_wlast)                                                  

        //  axi_wdata <= 'b0;                                                          

        else if (wnext)                                                                

          axi_wdata <= axi_wdata + 1;                                                  

        else                                                                            

          axi_wdata <= axi_wdata;                                                      

        end  

8:axi-full-master的axi_bready

设置axi_bready信号

      always @(posedge M_AXI_ACLK)                                    

      begin                                                                

        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 )                                            

          begin                                                            

            axi_bready <= 1'b0;                                            

          end                                                              

        // accept/acknowledge bresp with axi_bready by the master          

        // when M_AXI_BVALID is asserted by slave                          

        else if (M_AXI_BVALID && ~axi_bready)                              

          begin                                                            

            axi_bready <= 1'b1;                                            

          end                                                              

        // deassert after one clock cycle                                  

        else if (axi_bready)                                                

          begin                                                            

            axi_bready <= 1'b0;                                            

          end                                                              

        // retain the previous value                                        

        else                                                                

          axi_bready <= axi_bready;                                        

      end

9:axi-full-slave的axi_arvalid

Axi_full_master读通道的分析非常类似,代码是对称的。

当(~axi_arvalid && start_single_burst_read)==1条件满足,开始一次写传输,设置axi_arvalid有效。

      always @(posedge M_AXI_ACLK)                                

      begin                                                              

                                                                           

        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 )                                        

          begin                                                          

            axi_arvalid <= 1'b0;                                        

          end                                                            

        // If previously not valid , start next transaction              

        else if (~axi_arvalid && start_single_burst_read)                

          begin                                                          

            axi_arvalid <= 1'b1;                                        

          end                                                            

        else if (M_AXI_ARREADY && axi_arvalid)                          

          begin                                                          

            axi_arvalid <= 1'b0;                                        

          end                                                            

        else                                                            

          axi_arvalid <= axi_arvalid;                                    

      end          

10:axi-full-slave的axi_araddr

读地址计算

    // Next address after ARREADY indicates previous address acceptance  

      always @(posedge M_AXI_ACLK)                                      

      begin                                                              

        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)                                          

          begin                                                          

            axi_araddr <= 'b0;                                          

          end                                                            

        else if (M_AXI_ARREADY && axi_arvalid)                          

          begin                                                          

            axi_araddr <= axi_araddr + burst_size_bytes;                

          end                                                            

        else                                                            

          axi_araddr <= axi_araddr;                                      

      end    

11:axi-full-master的axi_rready

读数据准备好

    /*                                                                      

     The Read Data channel returns the results of the read request       

     In this example the data checker is always able to accept              

     more data, so no need to throttle the RREADY signal             

*/        

      always @(posedge M_AXI_ACLK)                                          

      begin                                                                

        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 )                  

          begin                                                            

            axi_rready <= 1'b0;                                            

          end                                                              

        // accept/acknowledge rdata/rresp with axi_rready by the master    

        // when M_AXI_RVALID is asserted by slave                          

        else if (M_AXI_RVALID)                      

          begin                                      

             if (M_AXI_RLAST && axi_rready)          

              begin                                  

                axi_rready <= 1'b0;                  

              end                                    

             else                                    

               begin                                

                 axi_rready <= 1'b1;                

               end                                  

          end                                        

        // retain the previous value                

      end  

12:读次数记录read_index计数器

读数据索引计数

      assign rnext = M_AXI_RVALID && axi_rready;                                                                                 

    // Burst length counter. Uses extra counter register bit to indicate    

    // terminal count to reduce decode logic                                

      always @(posedge M_AXI_ACLK)                                          

      begin                                                                

        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 || start_single_burst_read)                  

          begin                                                            

            read_index <= 0;                                                

          end                                                              

        else if (rnext && (read_index != C_M_AXI_BURST_LEN-1))              

          begin                                                            

            read_index <= read_index + 1;                                  

          end                                                              

        else                                                                

          read_index <= read_index;                                        

      end  

13:产生对比数据expected_rdata

数据expected_rdata用于和读出的M_AXI_RDATA进行对比以此验证数据的正确性。

    //Generate expected read data to check against actual read data

      always @(posedge M_AXI_ACLK)                    

      begin                                                  

        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)// || M_AXI_RLAST)            

            expected_rdata <= 'b1;                            

        else if (M_AXI_RVALID && axi_rready)                  

            expected_rdata <= expected_rdata + 1;            

        else                                                  

            expected_rdata <= expected_rdata;                

      end

14:比对数据正确性

读写数据比较

//Check received read data against data generator                      

      always @(posedge M_AXI_ACLK)                                          

      begin                                                                

        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)                  

          begin                                                            

            read_mismatch <= 1'b0;                                          

          end                                                              

        //Only check data when RVALID is active                            

        else if (rnext && (M_AXI_RDATA != expected_rdata))                  

          begin                                                            

            read_mismatch <= 1'b1;                                          

          end                                                              

        else                                                                

          read_mismatch <= 1'b0;                                            

      end      

15:读写状态机

读写状态机源码

 //implement master command interface state machine                                                        

      always @ ( posedge M_AXI_ACLK)                                                                            

      begin                                                                                                    

        if (M_AXI_ARESETN == 1'b0 )                                                                            

          begin                                                                                                

            // reset condition                                                                                  

            // All the signals are assigned default values under reset condition                                

            mst_exec_state      <= IDLE;                                                                

            start_single_burst_write <= 1'b0;                                                                  

            start_single_burst_read  <= 1'b0;                                                                  

            compare_done      <= 1'b0;                                                                          

            ERROR <= 1'b0;  

          end                                                                                                  

        else                                                                                                    

          begin                                                                                                

            // state transition                                                                                

            case (mst_exec_state)                                                                              

              IDLE:                                                                                    

                // This state is responsible to wait for user defined C_M_START_COUNT                          

                // number of clock cycles.                                                                      

                if ( init_txn_pulse == 1'b1)                                                      

                  begin                                                                                        

                    mst_exec_state  <= INIT_WRITE;                                                              

                    ERROR <= 1'b0;

                    compare_done <= 1'b0;

                  end                                                                                          

                else                                                                                            

                  begin                                                                                        

                    mst_exec_state  <= IDLE;                                                            

                  end                                                                                          

              INIT_WRITE:                                                                                      

                // This state is responsible to issue start_single_write pulse to                              

                // initiate a write transaction. Write transactions will be                                    

                // issued until burst_write_active signal is asserted.                                          

                // write controller                                                                            

                if (writes_done)                                                                                

                  begin                                                                                        

                    mst_exec_state <= INIT_READ;//                                                              

                  end                                                                                          

                else                                                                                            

                  begin                                                                                        

                    mst_exec_state  <= INIT_WRITE;                                                              

                    if (~axi_awvalid && ~start_single_burst_write && ~burst_write_active)                      

                      begin                                                                                    

                        start_single_burst_write <= 1'b1;                                                      

                      end                                                                                      

                    else                                                                                        

                      begin                                                                                    

                        start_single_burst_write <= 1'b0; //Negate to generate a pulse                          

                      end                                                                                      

                  end                                                                                          

              INIT_READ:                                                                                        

                // This state is responsible to issue start_single_read pulse to                                

                // initiate a read transaction. Read transactions will be                                      

                // issued until burst_read_active signal is asserted.                                          

                // read controller                                                                              

                if (reads_done)                                                                                

                  begin                                                                                        

                    mst_exec_state <= INIT_COMPARE;                                                            

                  end                                                                                          

                else                                                                                            

                  begin                                                                                        

                    mst_exec_state  <= INIT_READ;                                                              

                    if (~axi_arvalid && ~burst_read_active && ~start_single_burst_read)                        

                      begin                                                                                    

                        start_single_burst_read <= 1'b1;                                                        

                      end                                                                                      

                   else                                                                                        

                     begin                                                                                      

                       start_single_burst_read <= 1'b0; //Negate to generate a pulse                            

                     end                                                                                        

                  end                                                                                          

              INIT_COMPARE:                                                                                    

                // This state is responsible to issue the state of comparison                                  

                // of written data with the read data. If no error flags are set,                              

                // compare_done signal will be asseted to indicate success.                                    

                //if (~error_reg)                                                                              

                begin                                                                                          

                  ERROR <= error_reg;

                  mst_exec_state <= IDLE;                                                              

                  compare_done <= 1'b1;                                                                        

                end                                                                                            

              default :                                                                                        

                begin                                                                                          

                  mst_exec_state  <= IDLE;                                                              

                end                                                                                            

            endcase                                                                                            

          end                                                                                                  

      end //MASTER_EXECUTION_PROC      

 

整理成流程图,更加容易理解:

16:正在写burst_write_active

burst_write_active代表正在写操作

      always @(posedge M_AXI_ACLK)                                                                              

      begin                                                                                                    

        if(M_AXI_ARESETN==0||init_txn_pulse==1'b1)                                                                                

          burst_write_active<=1'b0;                                                                                              

        //The burst_write_active is asserted when a write burst transaction is initiated                        

        else if (start_single_burst_write)                                                                      

          burst_write_active <= 1'b1;                                                                          

        else if (M_AXI_BVALID && axi_bready)                                                                    

          burst_write_active <= 0;                                                                              

      end  

17:写完成writes_done

写数据完成writes_done信号

      always @(posedge M_AXI_ACLK)                                                                              

      begin                                                                                                    

        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)                                                        

          writes_done <= 1'b0;                                                 

        //The writes_done should be associated with a bready response                                          

        //else if (M_AXI_BVALID && axi_bready && (write_burst_counter == {(C_NO_BURSTS_REQ-1){1}}) && axi_wlast)

        else if (M_AXI_BVALID && (write_burst_counter[C_NO_BURSTS_REQ]) && axi_bready)                          

          writes_done <= 1'b1;                                                                                  

        else                                                                                                    

          writes_done <= writes_done;                                                                          

        end

18:正在读burst_read_active

读burst_read_active代表正在读数据

// burst_read_active signal is asserted when there is a burst write transaction                          

      // is initiated by the assertion of start_single_burst_write. start_single_burst_read                    

      // signal remains asserted until the burst read is accepted by the master                                

      always @(posedge M_AXI_ACLK)                                                                              

      begin                                                                                                    

        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)                                                

          burst_read_active <= 1'b0;                                                                  

        //The burst_write_active is asserted when a write burst transaction is initiated                        

        else if (start_single_burst_read)                                                                      

          burst_read_active <= 1'b1;                                                                            

        else if (M_AXI_RVALID && axi_rready && M_AXI_RLAST)                                                    

          burst_read_active <= 0;                                                                              

        end  

19:读完成reads_done

读数据完成reads_done信号

      always @(posedge M_AXI_ACLK)                                                                              

      begin                                                                                                    

        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)    

          reads_done <= 1'b0;                                                                                  

        //The reads_done should be associated with a rready response                                            

        //else if (M_AXI_BVALID && axi_bready && (write_burst_counter == {(C_NO_BURSTS_REQ-1){1}}) && axi_wlast)

        else if (M_AXI_RVALID && axi_rready && (read_index == C_M_AXI_BURST_LEN-1) && (read_burst_counter[C_NO_BURSTS_REQ]))

          reads_done <= 1'b1;                                                                                  

        else                                                                                                    

          reads_done <= reads_done;                                                                            

        end

20:IP的更新

由于修改了代码,需要先更新IP状态,完成IP更新

4实验结果

仿真结果

一次axi4写操作burst lenth=16如下图所示,由于WREADY信号不是连续的,所以可以传输效率不是最高的

一共进行64次burst共计写了1024个32bit数据

一次读操作的burst lenth也是16如下图,但是可以看到读数据时连续的,所以效率最高

一共进行64次burst共计读了1024个32bit数据

可以看到读出的数据RDATA和expected_rdata一致,所以代码正确。

标签:begin,full,end,05,burst,axi,else,master,AXI
From: https://www.cnblogs.com/milianke/p/17936369.html

相关文章

  • 05uifdma_dbuf 3.0 IP介绍
    软件版本:vitis2021.1(vivado2021.1)操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录"米联客"FPGA社区-www.uisrc.com视频课程、答疑解惑!5.1概述        uifdma_dbufIP是米联客研发用于配合FDMA完成数据传输控制的IP模块。FDMA-DBUFIP代码采用"......
  • 3-1-02AXI4-FULL-uiFDMA IP仿真验证
    软件版本:vitis2021.1(vivado2021.1)操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录"米联客"FPGA社区-www.uisrc.com视频课程、答疑解惑!2.1概述本文试验中对前面编写的FDMAIP进行仿真验证。2.2saxi_full_memIP介绍这个IP的源码可以基于XILINX提供的ax......
  • 3-1-01 AXI4-FULL-MASTER IP FDMA介绍
    件版本:vitis2021.1(vivado2021.1)操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录"米联客"FPGA社区-www.uisrc.com视频课程、答疑解惑!1.1概述    FDMA是米联客的基于AXI4总线协议定制的一个DMA控制器。本文对AXI4-FULL总线接口进行了封装,同时定义了简......
  • 3-1-05 Modesim软件安装
    1.1Modelsim软件版本选择不同的Vivado版本支持使用的Modesim版本不同,具体可查看Xilinx提供的文档UG973-vivado-release-notes-install-license。我们使用的Vivado软件版本是vivado2017.4,推荐使用版本是ModelSimSE/DE/PE(10.6b),经过安装发现,使用低于推荐的版本,在Vivado库......
  • 【充电管理】TP4056引脚定义
    1.引脚定义:TEMP(引脚1):电池温度检测输入端,实现电池温度检测功能。将TEMP管脚接到电池的NTC传感器的输出端。如果TEMP管脚的电压小于输入电压的45%或者大于输入电压的80%,意味着电池温度过低或过高,则充电被暂停。如果TEMP直接接GND,电池温度检测功能取消,其他充电功能正常。......
  • CF1806F GCD Master 题解
    题目链接EasyversionHardversion题目解法参考DeaphetS的题解很有意思的题,感觉\(F1\)不到\(*2900\),\(F2\)超过\(*2900\)F1简化题目中的操作:把\(n\)个数放到\(n-k\)组中,求\(\max(\sum\)每组\(a_i\)的\(\gcd)\)首先考虑所有数互不相同的情况结论1:把\(k+......
  • 基于stm32f103c8t6蓝牙连接模块hc-05
    一、蓝牙通信流程最简单实际的的蓝牙通信过程就是单片机——蓝牙——手机蓝牙app蓝牙作为桥梁进行单片机与手机数据的交换蓝牙就如同一个无线的USART一样,将两者连接。二、硬件资料1.管教图 连接图: 实物:连接图    三、软件资料1.电脑蓝牙调试软件网址广州汇承......
  • 20 I2C MASTER控制器驱动设计
    1系统框图I2CMaster控制器主要包含I2C收发数据状态机,SCL时钟分频器、发送移位模块、接收移位模块、空闲控制忙指示模块。SCL和SDA的输出逻辑和时序通过SCL和I2C状态机控制。重点介绍关键信号:IO_sda为I2C双向数据总线O_scl为I2C时钟I_wr_cnt写数据字节长度,包含了器件地址,发......
  • this is incompatible with sql_mode=only_full_group_by
    MySQ:mysql-5.7.30-linux-glibc2.12-x86_64生未知异常.org.springframework.jdbc.BadSqlGrammarException:###Errorqueryingdatabase.Cause:java.sql.SQLSyntaxErrorException:Expression#21ofSELECTlistisnotinGROUPBYclauseandcontainsnonaggregatedcolum......
  • Gartner 魔力象限:全生命周期 API 管理 2023 (Magic Quadrant for Full Life Cycle API
    Gartner魔力象限:全生命周期API管理2023GartnerMagicQuadrantforFullLifeCycleAPIManagement2023作者主页:sysin.orgMagicQuadrantforAPIManagementPublished11October2023魔力象限API为数字化转型、现代化和数字化业务生态系统提供了基础,但管理和治理它们具有......