Eurasia32 发表于 2022-7-21 12:45

[国民技术N32WB452测评] 二.部分通讯接口测试(USART, SPI, I2C)

本帖最后由 Eurasia32 于 2022-7-21 12:45 编辑

<p>一般来说,单片机开发中出现次数较多的通信接口主要有U(S)ART,SPI以及I2C,本次测试将主要着眼于以上三种通信接口的开发与测试。</p>

<ol>
        <li>U(S)ART
        <ol>
                <li>开发板资源:7个U(S)ART接口,最高速率达到4.5Mbps,其中3个USART接口(支持1xISO7816,1xIrDA,LIN),4个UART接口。</li>
                <li style="">测试:
                <ol>
                        <li style="">\USART\Printf:</li>
                </ol>
                </li>
        </ol>
        </li>
</ol>

<p>&nbsp;&nbsp;&nbsp;&nbsp;该测例演示了USARTx与PC间通过查询检测标识实现的基础通信。重定向printf函数至USARTx,并使用printf函数输出消息至终端。USARTx可以是USART1或USART2。</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;该例程使用USART1,PA9为USART_Tx,PA10为USART_Rx,GPIO初始化时PA10设置为浮空输入,PA9为推挽输出。在main函数开头使用USART_InitType结构体对象USART_InitStructure进行USART初始化,即设置波特率、停止位等。</p>

<pre>
<code>USART_InitStructure.BaudRate            = 115200;

USART_InitStructure.WordLength          = USART_WL_8B;

USART_InitStructure.StopBits            = USART_STPB_1;

USART_InitStructure.Parity              = USART_PE_NO;

USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;

USART_InitStructure.Mode         = USART_MODE_RX | USART_MODE_TX;</code></pre>

<p style="">&nbsp;&nbsp;&nbsp;&nbsp;设置完成后使用USART_Init()函数进行初始化并使用USART_Enable()函数使能USART,并通过重载fputc()函数进行printf()函数使用USART输出的重定向。</p>

<pre>
<code>int fputc(int ch, FILE* f)

{

    USART_SendData(USARTx, (uint8_t)ch);

    while (USART_GetFlagStatus(USARTx, USART_FLAG_TXDE) == RESET);

    return (ch);

}</code></pre>

<p style="">&nbsp;&nbsp;&nbsp;&nbsp;编译并下载至开发板后,通过串口调试助手可以看到所设置的printf所设置的输出,如下图所示:<br />
&nbsp;</p>

<ol start="2">
        <li style="">SPI
        <ol>
                <li>开发板资源:3个SPI接口,速度高达36MHz,其中两个支持I2S。</li>
                <li>测试:
                <ol>
                        <li>\SPI\CRC</li>
                </ol>
                </li>
        </ol>
        </li>
</ol>

<p style="">&nbsp;&nbsp;&nbsp;&nbsp;该例程中使用SPI1,SPI2分别发送并接收数据,进行CRC校验,若相同则置TransferStatus1与TransferStatus2为PASSED。main函数起始进行SPI1与SPI2的初始化,其中SPI1初始化为主机,SPI2初始化为从机:&nbsp;&nbsp;&nbsp;&nbsp;</p>

<pre>
<code class="language-cpp">    /* SPI1 configuration ------------------------------------------------------*/

    SPI_InitStructure.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;

    SPI_InitStructure.SpiMode       = SPI_MODE_MASTER;

    SPI_InitStructure.DataLen       = SPI_DATA_SIZE_16BITS;

    SPI_InitStructure.CLKPOL        = SPI_CLKPOL_LOW;

    SPI_InitStructure.CLKPHA        = SPI_CLKPHA_SECOND_EDGE;

    SPI_InitStructure.NSS           = SPI_NSS_SOFT;

    SPI_InitStructure.BaudRatePres  = SPI_BR_PRESCALER_8;

    SPI_InitStructure.FirstBit      = SPI_FB_MSB;

    SPI_InitStructure.CRCPoly       = 7;

    SPI_Init(SPI1, &amp;SPI_InitStructure);



    /* SPI2 configuration ------------------------------------------------------*/

    SPI_InitStructure.SpiMode = SPI_MODE_SLAVE;

    SPI_Init(SPI2, &amp;SPI_InitStructure);</code></pre>

<p style="">&nbsp;&nbsp;&nbsp;&nbsp;随后使用所提供库文件中的SPI_EnableCalculateCrc()函数使能SPI1与SPI2的CRC计算功能,随后通过SPI_Enable()使能SPI1与SPI2,SPI_I2S_TransmitData()函数进行数据的发送,SPI_I2S_ReceiveData()函数读取数据,SPI_TransmitCrcNext()函数使能CRC传输,在最后进行比较,若相同则使TransferStatusx为PASSED。</p>

<p style="">&nbsp;&nbsp;&nbsp;&nbsp;编译程序并下载至开发板后,连接SPI1与SPI2,打开Keil5 Debug,在Watch界面添加TransferStatus1与TransferStatus2,运行后可以看到其值由0x00 FAILED变为 0x01 PASSED,说明运行成功,如下图所示:(连接后可能出现蜂鸣器持续鸣叫的情况,不用在意)</p>

<p style=""> &nbsp;</p>

<ol start="3">
        <li style="">I2C
        <ol>
                <li>开发板资源:4个I2C接口,速率高达1MHz,主从模式可配,从机模式下支持双地址响应。</li>
                <li>测试:
                <ol>
                        <li>\I2C\I2C_10bit:</li>
                </ol>
                </li>
        </ol>
        </li>
</ol>

<p style="">&nbsp;&nbsp;&nbsp;&nbsp;此例程展示了I2C模块10bit地址模式下的读写操作。</p>

<p style="">&nbsp;&nbsp;&nbsp;&nbsp;该例程中I2C1为主机,I2C2为从机,分别进行I2C1写I2C2读以及I2C1读I2C2写的测试并比较所写内容和读取内容是否一致,若一致则通过USART串口输出PASSED。main函数起始使用自定义的i2c_master_init()以及i2c_slave_init()两个函数进行I2C主从机的初始化:</p>

<pre>
<code class="language-cpp">int i2c_master_init(void)

{

    I2C_InitType i2c1_master;

    GPIO_InitType i2c1_gpio;

    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_I2C1, ENABLE);

    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);

    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);

    GPIO_ConfigPinRemap(GPIO_RMP_I2C1, ENABLE);

    

    /*PB8 -- SCL; PB9 -- SDA*/

    i2c1_gpio.Pin               = GPIO_PIN_8 | GPIO_PIN_9;

    i2c1_gpio.GPIO_Speed        = GPIO_Speed_2MHz;

    i2c1_gpio.GPIO_Mode         = GPIO_Mode_AF_OD;

    GPIO_InitPeripheral(GPIOB, &amp;i2c1_gpio);



    I2C_DeInit(I2C1);

    i2c1_master.BusMode     = I2C_BUSMODE_I2C;

    i2c1_master.FmDutyCycle = I2C_FMDUTYCYCLE_2;

    i2c1_master.OwnAddr1    = I2C_MASTER_ADDR;

    i2c1_master.AckEnable   = I2C_ACKEN;

    i2c1_master.AddrMode    = I2C_ADDR_MODE_10BIT;

    i2c1_master.ClkSpeed    = 100000; //100K



    I2C_Init(I2C1, &amp;i2c1_master);

    // int enable

    I2C_ConfigInt(I2C1, I2C_INT_EVENT | I2C_INT_BUF | I2C_INT_ERR, ENABLE);

    NVIC_Configuration(1);

    I2C_Enable(I2C1, ENABLE);

    return 0;

}

int i2c_slave_init(void)

{

    I2C_InitType i2c2_slave;

    GPIO_InitType i2c2_gpio;

    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_I2C2, ENABLE);

    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);



    /*PB10 -- SCL; PB11 -- SDA*/

    i2c2_gpio.Pin               = GPIO_PIN_10 | GPIO_PIN_11;

    i2c2_gpio.GPIO_Speed        = GPIO_Speed_2MHz;

    i2c2_gpio.GPIO_Mode         = GPIO_Mode_AF_OD;

    GPIO_InitPeripheral(GPIOB, &amp;i2c2_gpio);

    

    I2C_DeInit(I2C2);

    i2c2_slave.BusMode     = I2C_BUSMODE_I2C;

    i2c2_slave.FmDutyCycle = I2C_FMDUTYCYCLE_2;

    i2c2_slave.OwnAddr1    = I2C_SLAVE_ADDR;

    i2c2_slave.AckEnable   = I2C_ACKEN;

    i2c2_slave.AddrMode    = I2C_ADDR_MODE_10BIT;

    i2c2_slave.ClkSpeed    = 100000; //100K



    I2C_Init(I2C2, &amp;i2c2_slave);

    // int enable

    I2C_ConfigInt(I2C2, I2C_INT_EVENT | I2C_INT_BUF | I2C_INT_ERR, ENABLE);

    NVIC_Configuration(2);

    I2C_Enable(I2C2, ENABLE);

    return 0;

}</code></pre>

<p style="">&nbsp;&nbsp;&nbsp;&nbsp;在I2C初始化后便使用库文件中所提供I2C_SendData()函数进行数据发送。</p>

<p style="">&nbsp;&nbsp;&nbsp;&nbsp;编译该项目并下载至开发板后,连接I2C1与I2C2,打开串口调试助手,复位后出现下图所示情况,说明运行正常:</p>

<p style=""> &nbsp;</p>

<ol start="4">
        <li style="">总结</li>
</ol>

<p style="">&nbsp;&nbsp;&nbsp;&nbsp;N32WB452单片机与STM32在相关通讯接口的开发中十分相似,在相关使用中可以充分地代替STM32的作用。</p>

Jacktang 发表于 2022-7-22 07:22

<p>通讯接口测试比较全,USART, SPI, I2C三种通信方式都测了</p>
页: [1]
查看完整版本: [国民技术N32WB452测评] 二.部分通讯接口测试(USART, SPI, I2C)