查看: 567|回复: 0
收起左侧

第三十八章:I2C-7位地址模式,主机发送从机接收

[复制链接]

  离线 

  • TA的每日心情
    慵懒
    2021-7-23 17:16
  • 签到天数: 17 天

    [LV.4]

    发表于 2021-4-27 21:25:41 | 显示全部楼层 |阅读模式

    有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    本帖最后由 草帽王子 于 2021-9-10 17:25 编辑

    CH32V103应用教程——I2C-7位地址模式,主机发送从机接收


    前面章节第14章和第37章已经进行过IIC读写EEPROM的实验,本章教程将在I2C7位地址模式下进行主机发送从机接收测试,并通过串口调试助手将结果打印显示。

    注意,本章例程使用CH32V103硬件IIC。


    1、I2C简介及相关函数介绍

    I2C(内部集成电路)总线接口用作微控制器和I2C串行总线之间的接口。它提供多主模式功能,可以控制所有I2C总线特定的序列、协议、仲裁和时序。它支持标准和快速模式。它还与SMBus2.0兼容。它可以用于多种用途,包括CRC生成和验证、SMBus(系统管理总线)以及PMBus(电源管理总线)。根据器件的不同,可利用DMA功能来减轻CPU的工作量。

    I2C主要特征如下:
    • 支持主模式和从模式
    • 支持 7 位或 10 位地址
    • 从设备支持双 7 位地址
    • 支持两种速度模式:100KHz 和 400KHz
    • 多种状态模式,多种错误标志
    • 支持加长的时钟功能
    • 2个中断向量
    • 支持 DMA
    • 支持 PEC
    • 兼容 SMBus

    I2C是个半双工的总线,它同时只能运行在下列四种模式中之一:主设备发送模式、主设备接收模式、从设备发送模式和从设备接收模式。I2C 模块默认工作在从模式,在产生起始条件后,会自动地切换到主模式,当仲裁丢失或者产生停止信号后,会切换到从模式。I2C模块支持多主机功能。工作在主模式时,I2C 模块会主动发出数据和地址。数据和地址都以8位为单位进行传输,高位在前,低位在后,在起始事件后的是一个字节(7位地址模式下)或两个字节(10位地址模式下)地址,主机每发送8位数据或地址,从机需要回复一个应答ACK,即把SDA总线拉低,如图所示。

    CH32V CH573单片机芯片-第三十八章:I2C-7位地址模式,主机发送从机接收risc-v单片机中文社区(1)

    为了正常使用必须给 I2C 输入正确的时钟,其中标准模式下,输入时钟最低为 2MHz,在快速模式下,输入时钟最低为 4MHz。
    关于CH32V103各模式介绍以及具体信息,可参考CH32V103应用手册。I2C标准库函数在第十四章节已介绍,在此不再赘述。


    2、硬件设计

    本章教程使用开发板硬件I2C进行主机发送从机接收实验,需用到两个开发板,将两个开发板对应IIC引脚连接起来即可。
    注意:此处需要将开发板I2C引脚外接上拉电阻。


    3、软件设计

    本章教程使用硬件I2C在7位地址模式下进行主机发送从机接收实验,其代码量相对较小,具体程序如下:
    iic.h文件
    1. #ifndef __IIC_H
    2. #define __IIC_H

    3. #include "ch32v10x_conf.h"

    4. /* I2C Mode Definition */
    5. #define HOST_MODE    0
    6. #define SLAVE_MODE   1

    7. /* I2C Communication Mode Selection */
    8. #define I2C_MODE   HOST_MODE
    9. //#define I2C_MODE   SLAVE_MODE

    10. /* Global define */
    11. #define Size   7
    12. #define RXAdderss   0x02
    13. #define TxAdderss   0x02

    14. void IIC_Init( u32 bound, u16 address );


    15. #endif
    复制代码
    iic.h文件主要进行宏定义和函数声明;
    iic.c文件
    1. #include "iic.h"

    2. /*******************************************************************************
    3. * Function Name  : IIC_Init
    4. * Description    : Initializes the IIC peripheral.
    5. * Input          : None
    6. * Return         : None
    7. *******************************************************************************/
    8. void IIC_Init( u32 bound, u16 address )
    9. {
    10.     GPIO_InitTypeDef GPIO_InitStructure;
    11.     I2C_InitTypeDef I2C_InitTSturcture;

    12.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE );
    13.     GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE); //重映射功能,PB8和PB9重映射为I2C1
    14.     RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C1, ENABLE );

    15.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    16.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    17.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    18.     GPIO_Init( GPIOB, &GPIO_InitStructure );

    19.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    20.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    21.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    22.     GPIO_Init( GPIOB, &GPIO_InitStructure );

    23.     I2C_InitTSturcture.I2C_ClockSpeed = bound;     //设置I2C传输速率
    24.     I2C_InitTSturcture.I2C_Mode = I2C_Mode_I2C;    //指定I2C工作模式
    25.     I2C_InitTSturcture.I2C_DutyCycle = I2C_DutyCycle_16_9;  //指定时钟占空比
    26.     I2C_InitTSturcture.I2C_OwnAddress1 = address;  //指定I2C自身设备地址
    27.     I2C_InitTSturcture.I2C_Ack = I2C_Ack_Enable;   //使能或者关闭响应 (一般都是使能)
    28.     I2C_InitTSturcture.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;  //指定地址的长度,可以是7位或10位
    29.     I2C_Init( I2C1, &I2C_InitTSturcture );

    30.     I2C_Cmd( I2C1, ENABLE );

    31. #if (I2C_MODE == HOST_MODE)
    32.     I2C_AcknowledgeConfig( I2C1, ENABLE );

    33. #endif
    34. }
    复制代码
    iic.c文件主要对开发板硬件I2C进行初始化配置,包括硬件I2C对应GPIO引脚配置以及指定I2C外设配置,其中I2C外设配置可结合ch32v10x_i2c.c文件中I2C_Init函数以及CH32V103应用手册中I2C主模式和从模式通讯步骤进行理解。
    当作为主机模式时,需要将指定I2C设备地址设置为主机地址,同时需要开启I2C响应设置。当作为从机模式时,需要将指定I2C设备地址设置为从机地址。
    main.c文件
    1. /********************************** (C) COPYRIGHT *******************************
    2. * File Name          : main.c
    3. * Author             : WCH
    4. * Version            : V1.0.0
    5. * Date               : 2020/04/30
    6. * Description        : Main program body.
    7. *******************************************************************************/

    8. #include "debug.h"
    9. #include "iic.h"

    10. /* Global Variable */
    11. u8 TxData[Size] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
    12. u8 RxData[Size];
    13. /*******************************************************************************
    14. * Function Name  : main
    15. * Description    : Main program.
    16. * Input          : None
    17. * Return         : None
    18. *******************************************************************************/
    19. int main(void)
    20. {
    21.     u8 i=0;

    22.     Delay_Init();
    23.     USART_Printf_Init(115200);
    24.     printf("SystemClk:%d\r\n",SystemCoreClock);

    25. //当I2C作为主机时
    26. #if (I2C_MODE == HOST_MODE)
    27.     printf("IIC Host mode\r\n");

    28.     //I2C进行主机初始化配置
    29.     IIC_Init( 80000, TxAdderss);

    30.     //当I2C1处于空闲状态时,跳过此while循环,开启起始信号
    31.     while( I2C_GetFlagStatus( I2C1, I2C_FLAG_BUSY ) != RESET ); //检查是否设置了指定I2C标志

    32.     //开启I2C1通信起始信号
    33.     I2C_GenerateSTART( I2C1, ENABLE );

    34.     //当最后一个事件为I2C_EVENT_MASTER_MODE_SELECT事件时,说明选择I2C作为主机模式,跳过此while循环,进行下一步
    35.     while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );  //检查最后一个I2Cx事件是否等于作为参数传递的事件

    36.     //发送地址来选择从机设备
    37.     I2C_Send7bitAddress( I2C1, 0x02, I2C_Direction_Transmitter );

    38.     //当最后一个事件为I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED事件时,说明选择I2C进行主机发送,跳过此while循环,进行下一步数据发送
    39.     while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) );

    40.     while( i<6 )
    41.     {
    42.         //当当前标志状态为I2C_FLAG_TXE时,进行数据发送
    43.         if( I2C_GetFlagStatus( I2C1, I2C_FLAG_TXE ) !=  RESET )
    44.         {
    45.             I2C_SendData( I2C1, TxData[i] );
    46.             i++;
    47.         }
    48.     }

    49.     //当最后一个事件为I2C_EVENT_MASTER_BYTE_TRANSMITTED事件时,说明发送结束,跳过此while循环,进行下一步
    50.     while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) );

    51.     //开启I2C通信停止信号
    52.     I2C_GenerateSTOP( I2C1, ENABLE );

    53. //当I2C作为从机时
    54. #elif (I2C_MODE == SLAVE_MODE)
    55.     printf("IIC Slave mode\r\n");

    56.     //I2C进行从机初始化配置
    57.     IIC_Init( 80000, RXAdderss);

    58.     //当最后一个事件为I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED事件时,说明选择I2C作为从机进行数据接收,跳过此while循环,进行数据接收
    59.     while( !I2C_CheckEvent( I2C1, I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED ) );

    60.     while( i<6 )
    61.     {
    62.         //当当前标志状态为I2C_FLAG_RXNE时,进行数据接收
    63.         if( I2C_GetFlagStatus( I2C1, I2C_FLAG_RXNE ) !=  RESET )
    64.         {
    65.             RxData[i] = I2C_ReceiveData( I2C1 );
    66.             i++;
    67.         }
    68.     }

    69.     printf( "RxData:\r\n" );
    70.     for( i=0; i<6; i++ )
    71.     {
    72.         printf( "%02x\r\n", RxData[i] );
    73.     }

    74. #endif

    75.     while(1);
    76. }

    复制代码
    main.c文件主要进行主机模式下的数据发送配置和从机模式下的数据接收配置。其中在7位地址模式下,发送的第一个字节为地址字节,头7位代表的是目标从设备地址,第8位决定了后续报文的方向,0代表是主设备写入数据到从设备,1代表是主设备向从设备读取信息。其中I2C_Send7bitAddress函数会根据第三个输入进行写入和读取的判断。


    4、下载验证

    将编译好的程序分别在主机模式和从机模式下下载到两个开发版,并将两个开发板的PB8和PB9引脚接上拉电阻然后连接起来,将两个开发板进行复位,即可进行I2C通信,从机接收开发板串口打印情况具体如下:

    CH32V CH573单片机芯片-第三十八章:I2C-7位地址模式,主机发送从机接收risc-v单片机中文社区(2)
    IIC-7位地址模式,主机发送从机接收.
    CH32V CH573单片机芯片-第三十八章:I2C-7位地址模式,主机发送从机接收risc-v单片机中文社区(3) 37、IIC-7位地址模式,主机发送从机接收.rar (482.1 KB, 下载次数: 13)




    上一篇:第三十七章:CH32V103应用教程——I2C-软件模拟I2C读写EEPROM
    下一篇:第三十九章:I2C-7位地址模式,主机接收从机发送
    RISCV作者优文
    全球首家只专注于RISC-V单片机行业应用的中文网站
    点评回复

    使用道具 举报

    高级模式
    B Color Image Link Quote Code Smilies

    本版积分规则

    关闭

    RISC-V单片机中文网上一条 /2 下一条



    版权及免责声明|RISC-V单片机中文网 |网站地图

    GMT+8, 2022-11-27 06:23 , Processed in 1.530207 second(s), 49 queries .

    快速回复 返回顶部 返回列表