精华内容
下载资源
问答
  • I2C总线通信协议

    2020-12-22 10:48:14
    I2C协议简介     I2C通讯协议(Inter—Integrated Circuit)是由Philps公司开发的,由于...如芯片被分为内核层和片上外设;STM32标准库则是在寄存器与用户代码之间的软件层。对于通讯协议,我们也以分

    I2C协议简介

    I2C通讯协议(Inter—Integrated Circuit)是由Philps公司开发的,由于它引脚少,硬件实现简单,可扩展性强,不需要USART、CAN等通讯协议的外部收发设备,现在被广泛地使用在系统内多个集成电路(IC)间的通讯。
    在计算机科学里,大部分复杂的问题都可以通过分层来简化。如芯片被分为内核层和片上外设;STM32标准库则是在寄存器与用户代码之间的软件层。对于通讯协议,我们也以分层的方式来理解,最基本的是把它分为物理层和协议层。物理层规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。简单来说物理层规定我们用嘴巴还是用肢体来交流,协议层则规定我们用中文还是英文来交流。

    STM32 的 I2C 特性及架构

    如果我们直接控制 STM32的两个 GPIO 引脚,分别用作 SCL及 SDA,按照上述信号的
    时序要求,直接像控制 LED 灯那样控制引脚的输出(若是接收数据时则读取 SDA 电平),就
    可以实现 I2C 通讯。同样,假如我们按照 USART 的要求去控制引脚,也能实现 USART 通
    讯。所以只要遵守协议,就是标准的通讯,不管您如何实现它,不管是 ST 生产的控制器还
    是 ATMEL 生产的存储器, 都能按通讯标准交互。
    由于直接控制 GPIO 引脚电平产生通讯时序时,需要由 CPU 控制每个时刻的引脚状态,
    所以称之为“软件模拟协议”方式。
    相对地,还有“硬件协议”方式,STM32 的 I2C 片上外设专门负责实现 I2C 通讯协议,
    只要配置好该外设,它就会自动根据协议要求产生通讯信号,收发数据并缓存起来,CPU
    只要检测该外设的状态和访问数据寄存器,就能完成数据收发。这种由硬件外设处理 I2C
    协议的方式减轻了 CPU 的工作,且使软件设计更加简单。

    硬件I2C与软件I2C的区别

    硬件I2C

    - 硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的

    软件I2C

    - 软件I2C一般是用GPIO管脚,用软件控制管脚状态以模拟I2C通信波形
    - 硬件I2C的效率要远高于软件的,而软件I2C由于不受管脚限制,接口比较灵活 模拟I2C
    是通过GPIO,软件模拟寄存器的工作方式,而硬件(固件)I2C是直接调用内部寄存器进行配置。如果要从具体硬件上来看,可以去看下芯片手册。因为固件I2C的端口是固定的,所以会有所区别。

    区分

    - 可以看底层配置,比如IO口配置,如果配置了IO口的功能(IIC功能)那就是固件IIC
    - 可以看IIC写函数,看里面有木有调用现成的函数或者给某个寄存器赋值,如果有,则肯定是固件IIC功能,没有的话肯定是数据一个bit一个bit模拟发生送的,肯定用到了循环,则为模拟。
    - 根据代码量判断,模拟的代码量肯定比固件的要大

    1.硬件IIC用法比较复杂,模拟IIC的流程更清楚一些。

    2.硬件IIC速度比模拟快,并且可以用DMA

    3.模拟IIC可以在任何管脚上,而硬件只能在固定管脚上。

    实践

    阅读AHT20数据手册,编程实现:
    每隔2秒钟采集一次温湿度数据,并通过串口发送到上位机。

    环境

    这次实验在野火的MINI开发板中实现

    代码

    代码在奥松电子的官网中的AHT20的代码基础之上更改的(本人代码很渣的,只能再别人写好的基础上改一些)

    奥松下载中心中可以下载官方的例程资料
    在这里插入图片描述
    之后就可以在官方的代码中进一步的修改,得到自己需要的代码
    将下载后的示例代码,添加到之前野火MINI官方的I2C的实验的代码下,
    之后就可以自己更改初始化与配置,添加读取温度的代码进行调试
    由于在实验过程中用开发板出现了问题,所以实验最终将代码烧到了STM32的核心板中,结果都一样

    在这里插入图片描述

    代码

    实验代码就是在之前的I2C串口通信的基础之上实现的
    主要的main.c的代码如下

    #include "stm32f10x.h"
    #include "stm32f10x_usart.h"
    #include "misc.h"
    #include "stdio.h"
    #include "delay.h"
    #include "bsp_i2c.h"
    #include "ATH20.h"
    
    void RCC_Configuration(void);
    void GPIO_Configuration(void);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    
    #pragma import(__use_no_semihosting)
    struct __FILE
    {
    	int handle;
    
    };
    FILE __stdout;
    _sys_exit(int x)
    {
    	x = x;
    }
    int fputc(int ch, FILE *f)
    {
    	while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
        USART_SendData(USART1,(uint8_t)ch);
    	return ch;
    }
    
    void uart_init(u32 bound)
    {
        //GPIO¶Ë¿ÚÉèÖÃ
        GPIO_InitTypeDef GPIO_InitStructure;
    	USART_InitTypeDef USART_InitStructure;
    
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//ʹÄÜUSART1£¬GPIOAʱÖÓ
     	USART_DeInit(USART1);  //¸´Î»´®¿Ú1
        //USART1_TX   PA.9
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//¸´ÓÃÍÆÍìÊä³ö
        GPIO_Init(GPIOA, &GPIO_InitStructure); //³õʼ»¯PA9
    
        //USART1_RX	  PA.10
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//¸¡¿ÕÊäÈë
        GPIO_Init(GPIOA, &GPIO_InitStructure);  //³õʼ»¯PA10
    
        //USART ³õʼ»¯ÉèÖÃ
    	USART_InitStructure.USART_BaudRate = bound;//Ò»°ãÉèÖÃΪ9600;
    	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//×Ö³¤Îª8λÊý¾Ý¸ñʽ
    	USART_InitStructure.USART_StopBits = USART_StopBits_1;//Ò»¸öֹͣλ
    	USART_InitStructure.USART_Parity = USART_Parity_No;//ÎÞÆæżУÑéλ
    	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ÎÞÓ²¼þÊý¾ÝÁ÷¿ØÖÆ
    	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//ÊÕ·¢Ä£Ê½
    
        USART_Init(USART1, &USART_InitStructure); //³õʼ»¯´®¿Ú
    
        USART_Cmd(USART1, ENABLE);                    //ʹÄÜ´®¿Ú
    }
    
    int main(void)
    {
        uint8_t ret = 0;
        float P,T,ALT;
        uint32_t CT_data[2];
    	int  c1,t1;
        uint8_t LED_Stat = 0;
    
        RCC_Configuration();					   	//ÉèÖÃϵͳʱÖÓ
        GPIO_Configuration();					    //IO¿ÚÉè
        I2C_Bus_Init();
    
        uart_init(115200);
    
        ret = ATH20_Init();
        if(ret == 0)
        {
            printf("ATH20´«¸ÐÆ÷³õʼ»¯´íÎó\n");
            while(1);
        }
    
    
    
        while(1)
        {
            /* ¶ÁÈ¡ ATH20 ´«¸ÐÆ÷Êý¾Ý*/
            while(ATH20_Read_Cal_Enable() == 0)
            {
                ATH20_Init();//Èç¹ûΪ0ÔÙʹÄÜÒ»´Î
                SoftDelay_ms(30);
            }
            ATH20_Read_CTdata(CT_data);  //¶ÁȡζȺÍʪ¶È
            c1 = CT_data[0] * 1000 / 1024 / 1024;  //¼ÆËãµÃµ½Êª¶ÈÖµ£¨·Å´óÁË10±¶,Èç¹ûc1=523£¬±íʾÏÖÔÚʪ¶ÈΪ52.3%£©
            t1 = CT_data[1] * 200 *10 / 1024 / 1024 - 500;//¼ÆËãµÃµ½Î¶ÈÖµ£¨·Å´óÁË10±¶£¬Èç¹ût1=245£¬±íʾÏÖÔÚζÈΪ24.5¡æ£©
    
            printf("AHT20ÎÂʪ¶È¶ÁȡʵÑé:\n");
            printf("ζÈ: %d.%d ¡æ\n",(t1/10),(t1%10));
            printf("ʪ¶È: %d.%d %%\n",(c1/10),(c1%10));
            printf("\n\n");
           
    
            SoftDelay_ms(1000);//ÿ¸ôÁ½Ãë¶ÁÒ»´ÎÊý
    
        }
    }
    
    void RCC_Configuration(void)
    {
      SystemInit();
    
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC
      						| RCC_APB2Periph_GPIOD| RCC_APB2Periph_GPIOE , ENABLE);
    }
    
    void GPIO_Configuration(void)
    {
      GPIO_InitTypeDef GPIO_InitStructure;
    
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7;				     //״̬LED1
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;			 //ͨÓÃÍÆÍìÊä³öģʽ
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;			 //Êä³öģʽ×î´óËÙ¶È50MHz
      GPIO_Init(GPIOC, &GPIO_InitStructure);
    }
    

    实验结果

    将代码烧录进去之后就可以打开串口调制助手显示读取的温湿度数了,对着传感器哈一口气很明显看到温度的上升。
    在这里插入图片描述

    展开全文
  • I2C总线通信协议,基于I2C硬件协议的AHT20温湿度传感器的数据采集I2C简介软件I2C”和“硬件I2C”实践 I2C简介 I2C 通讯协议(Inter-Integrated Circuit)是由 Phiilps 公司开发的,由于它引脚少,硬件实现简单,可...

    I2C总线通信协议,基于I2C硬件协议的AHT20温湿度传感器的数据采集

    I2C简介

    I2C 通讯协议(Inter-Integrated Circuit)是由 Phiilps 公司开发的,由于它引脚少,硬件实现简单,可扩展性强,不需要 USART、CAN 等通讯协议的外部收发设备,现在被广泛地使用在系统内多个集成电路(IC)间的通讯。在计算机科学里,大部分复杂的问题都可以通过分层来简化。如芯片被分为内核层和片上外设;STM32 标准库则是在寄存器与用户代码之间的软件层。对于通讯协议,我们也以分层的方式来理解,最基本的是把它分为物理层和协议层。物理层规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。简单来说物理层规定我们用嘴巴还是用肢体来交流,协议层则规定我们用中文还是英文来交流。
    1.物理层
    在这里插入图片描述

    它的物理层有如下特点:
    (1) 它是一个支持设备的总线。“总线”指多个设备共用的信号线。在一个 I2C 通讯总线
    中,可连接多个 I2C 通讯设备,支持多个通讯主机及多个通讯从机。
    (2) 一个 I2C 总线只使用两条总线线路,一条双向串行数据线(SDA) ,一条串行时钟线
    (SCL)。数据线即用来表示数据,时钟线用于数据收发同步。
    (3) 每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之
    间的访问。
    (4) 总线通过上拉电阻接到电源。当 I2C 设备空闲时,会输出高阻态,而当所有设备都空
    闲,都输出高阻态时,由上拉电阻把总线拉成高电平。
    (5) 多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用
    总线。
    (6) 具有三种传输模式:标准模式传输速率为 100kbit/s ,快速模式为 400kbit/s ,高速模式
    下可达 3.4Mbit/s,但目前大多 I2C 设备尚不支持高速模式。
    (7) 连接到相同总线的 IC 数量受到总线的最大电容 400pF 限制 。

    2.协议层
    I2C 的协议定义了通讯的起始和停止信号、数据有效性、响应、仲裁、时钟同步和地
    址广播等环节。

    I2C 通讯过程的基本结构
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述在这里插入图片描述在这里插入图片描述

    软件I2C”和“硬件I2C”

    硬件I2C对应bai芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的。
    软件I2C一般是用GPIO管脚,用软件控制管脚状态以模拟I2C通信波形。

    区别:
    硬件I2C的效率要远高于软件的,而软件I2C由于不受管脚限制,接口比较灵活。
    模拟I2C 是通过GPIO,软件模拟寄存器的工作方式,而硬件(固件)I2C是直接调用内部寄存器进行配置。如果要从具体硬件上来看,可以去看下芯片手册。因为固件I2C的端口是固定的,所以会有所区别。
    硬件IIC用法比较复杂,模拟IIC的流程更清楚一些。 2. 硬件IIC速度比模拟快,并且可以用DMA 3. 模拟IIC可以在任何管脚上,而硬件只能在固定管脚上。 软件i2c是程序员使用程序控制SCL,SDA线输出高低电平,模拟i2c协议的时序。一般较硬件i2c稳定,但是程序较为繁琐,但不难。 硬件i2c程序员只要调用i2c的控制函数即可,不用直接的去控制SCL,SDA高低电平的输出。但是有些单片机的硬件i2c不太稳定,调试问题较多。

    至于如何区分它们
    1.可以看底层配置,比如IO口配置,如果配置了IO口的功能(IIC功能)那就是固件IIC,否则就是模拟
    2.可以看IIC写函数,看里面有木有调用现成的函数或者给某个寄存器赋值,如果有,则肯定是固件IIC功能,没有的话肯定是数据一个bit一个bit模拟发生送的,肯定用到了循环,则为模拟。
    3.根据代码量判断,模拟的代码量肯定比固件的要大。

    实践

    编程实现:每隔2秒钟采集一次温湿度数据,并通过串口发送到上位机(win10)

    主函数部分

    #include "stm32f10x.h"
    #include "stm32f10x_usart.h"
    #include "misc.h"
    #include "stdio.h"
    #include "delay.h"
    #include "bsp_i2c.h"
    #include "ATH20.h"
    
    void RCC_Configuration(void);
    void GPIO_Configuration(void);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    
    #pragma import(__use_no_semihosting)
    struct __FILE
    {
    	int handle;
    
    };
    FILE __stdout;
    _sys_exit(int x)
    {
    	x = x;
    }
    int fputc(int ch, FILE *f)
    {
    	while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
        USART_SendData(USART1,(uint8_t)ch);
    	return ch;
    }
    
    void uart_init(u32 bound)
    {
        //GPIO端口设置
        GPIO_InitTypeDef GPIO_InitStructure;
    	USART_InitTypeDef USART_InitStructure;
    
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟
     	USART_DeInit(USART1);  //复位串口1
        //USART1_TX   PA.9
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
        GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9
    
        //USART1_RX	  PA.10
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
        GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PA10
    
        //USART 初始化设置
    	USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
    	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
    	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
    	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
    	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
    
        USART_Init(USART1, &USART_InitStructure); //初始化串口
    
        USART_Cmd(USART1, ENABLE);                    //使能串口
    }
    
    int main(void)
    {
        uint8_t ret = 0;
        float P,T,ALT;
        uint32_t CT_data[2];
    	int  c1,t1;
        uint8_t LED_Stat = 0;
    
        RCC_Configuration();					   	//设置系统时钟
        GPIO_Configuration();					    //IO口设
        I2C_Bus_Init();
    
        uart_init(115200);
    
        ret = ATH20_Init();
        if(ret == 0)
        {
            printf("ATH20传感器初始化错误\n");
            while(1);
        }
    
    
    
        while(1)
        {
            /* 读取 ATH20 传感器数据*/
            while(ATH20_Read_Cal_Enable() == 0)
            {
                ATH20_Init();//如果为0再使能一次
                SoftDelay_ms(30);
            }
            ATH20_Read_CTdata(CT_data);  //读取温度和湿度
            c1 = CT_data[0] * 1000 / 1024 / 1024;  //计算得到湿度值(放大了10倍,如果c1=523,表示现在湿度为52.3%)
            t1 = CT_data[1] * 200 *10 / 1024 / 1024 - 500;//计算得到温度值(放大了10倍,如果t1=245,表示现在温度为24.5℃)
    
            printf("***************************\n");
            printf("AHT20温湿度传感器测试数据:\n");
            printf("温度: %d.%d ℃\n",(t1/10),(t1%10));
            printf("湿度: %d.%d %%\n",(c1/10),(c1%10));
            printf("\n");
           
    
            SoftDelay_ms(1000);//每隔两秒读一次数
    
            if(LED_Stat == 0)
            {
                LED_Stat = 1;
                GPIO_ResetBits(GPIOC, GPIO_Pin_2);
            }
            else
            {
                LED_Stat = 0;
                GPIO_SetBits(GPIOC, GPIO_Pin_2);
            }
        }
    }
    
    void RCC_Configuration(void)
    {
      SystemInit();
    
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC
      						| RCC_APB2Periph_GPIOD| RCC_APB2Periph_GPIOE , ENABLE);
    }
    
    void GPIO_Configuration(void)
    {
      GPIO_InitTypeDef GPIO_InitStructure;
    
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7;				     //状态LED1
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;			 //通用推挽输出模式
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;			 //输出模式最大速度50MHz
      GPIO_Init(GPIOC, &GPIO_InitStructure);
    }
    
    

    主函数串口

    void uart_init(u32 bound)
    {
        //GPIO端口设置
        GPIO_InitTypeDef GPIO_InitStructure;
    	USART_InitTypeDef USART_InitStructure;
    
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟
     	USART_DeInit(USART1);  //复位串口1
        //USART1_TX   PA.9
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
        GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9
    
        //USART1_RX	  PA.10
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
        GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PA10
    
        //USART 初始化设置
    	USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
    	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
    	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
    	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
    	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
    
        USART_Init(USART1, &USART_InitStructure); //初始化串口
    
        USART_Cmd(USART1, ENABLE);                    //使能串口
    }
    
    

    在这里插入图片描述
    总结:I2C这种协议一种串行总线,具有引脚少,硬件实现简单,可扩展性强的优点。I2C总线的另一优点是支持多主控,总线上任何能够进行发送/接收数据的设备都可以占领总线。掌握好I2C对我们今后的学习十分重要。

    展开全文
  • 通信协议总线

    2019-10-05 02:08:04
     总线(Bus)是计算机各种功能部件之间传送信息的公共通信干线,由导线组成,传统的总线可以分为数据总线、地址总线、控制总线 总线的数据线线数代表总线宽度,常见的总线标准是:PCI总线,PC中使用最多的是:RS-232...

    一、总线

      总线(Bus)是计算机各种功能部件之间传送信息的公共通信干线,由导线组成,传统的总线可以分为数据总线、地址总线、控制总线

    总线的数据线线数代表总线宽度,常见的总线标准是:PCI总线,PC中使用最多的是:RS-232总线,外设经常使用的是:USB总线

    点击了解什么是总线,总线的定义和基本知识

    二、RS-232

     

    三、RS-485

      RS-485总线采用串行半双工工作方式,采用平衡发送差分接收接口标准,支持多点数据通信。标准的发送流程为:发送端将串行

    口的TTL电平信号转换成差分信号由A、B两条线传输,接收端收到后,将差分信号还原成TTL电平信号。RS-485具有极强的抗共模干扰

    能力,通信距离理论可达1200m,如果通信距离较短,最大传输速率将大幅提高,如果通信距离较长,可以增加485中继器。RS-485总线

    网络拓扑一般采用终端匹配的总线型结构,即一条总线将各个节点串联起来,如果要使用星型结构,必须使用485中继器。

    RS-485总线布线规则:

     1.传输差分信号时数据线最好采用外加屏蔽层的双绞线,且屏蔽层需要可靠接地

     2.终端电阻作用:.实际上差分信号传输的是电流信号,根据U=IR可知,增加电阻可以将电流信号转成电压信号

               .实现阻抗匹配,信号在传输线末端突然遇到电缆阻抗很小甚至没有,信号在这个地方就会引起反射,消除反射的方法

     就是在电缆的末端接一个与电缆的特性阻抗(双绞线通常为120欧)同样大小的终端电阻,使电缆的阻抗连续由于信号在电缆上的传输是双

     向的,因此,在通信电缆的另一端需要接一个同样大小的终端电阻

    四、USB

     

    五、IIC

     

    六、SPI

    转载于:https://www.cnblogs.com/imyang/p/11606253.html

    展开全文
  • IIC通信协议详解

    2020-12-21 14:13:51
    IIC通信协议详解IIC的概述IIC分为软件IIC和硬件IICIIC通信协议空闲状态开始信号与停止信号开始信号程序: IIC的概述 IIC:两线式串行总线,它是由数据线SDA和时钟线SCL构成的串行总线,可发送和接收数据。 在CPU与被...

    一、前言

    1、IIC的概述

    IIC:两线式串行总线,它是由数据线SDA和时钟线SCL构成的串行总线,可发送和接收数据。

    在CPU与被控IC之间、IC与IC之间进行双向传送,高速IIC总线一般可达400kbs以上。

    时钟线SCL:在通信过程起到控制作用。
    数据线SDA:用来一位一位的传送数据。

    2、IIC分为软件IIC和硬件IIC

    • 软件IIC:软件IIC通信指的是用单片机的两个I/O端口模拟出来的IIC,用软件控制管脚状态以模拟I2C通信波形,软件模拟寄存器的工作方式。

    • 硬件IIC:一块硬件电路,硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的,硬件(固件)I2C是直接调用内部寄存器进行配置。
      补充:

    • 硬件I2C的效率要远高于软件的,而软件I2C由于不受管脚限制,接口比较灵活。

    • IIC是半双工通信方式


    二、IIC通信协议

    IIC通信过程由开始、结束、发送、响应、接收五个部分构成。

    • (在发送、接收数据的时候)当SCL为高电平时,SDA线不允许变化;当SCL线为低电平时,SDA线可以任意0、1变化。

    • (在任意时候)只有当SCL为高电平时,IIC电路才对SDA线上的电平(0或者1)进行记录,当SCL线为低电平时,无论SDA是高还是低,IIC电路都不对SDA进行采样。

    1、空闲状态

    在介绍上面五个部分前,我们首先说说空闲状态,什么是空闲状态,就是没有通信时的状态(初始状态)

    • I2C总线的SDA和SCL两条信号同时处于高电平时,规定为总线的空闲状态。此时各个器件的输出级场效管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。

    2、开始信号与停止信号

    • 开始信号:当SCL为高期间,SDA由高到低的跳变;启动信号是一种电平跳变时序信号,而不是一个电平。
    • 停止信号:当SCL为高期间,SDA由低到高的跳变;停止信号也是一种电平跳变时序信号,而不是一个电平信号。
      在这里插入图片描述
      开始信号程序:
    //产生IIC起始信号
    //1.设置SDA输出
    //2.先拉高SDA,再拉高SCL,空闲状态
    //3.拉低SDA
    //4.准备接收数据
    void IIC_Start(void)
    {
        SDA_OUT();     //sda线输出
        IIC_SDA=1;            
        IIC_SCL=1;
        delay_us(4);
         IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
        delay_us(4);
        IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
    }
    

    停止信号程序:

    //产生IIC停止信号
    //1.设置SDA输出
    //2.先拉低SDA,再拉低SCL
    //3.拉高SCL
    //4.拉高SDA
    //5.停止接收数据
    void IIC_Stop(void)
    {
        SDA_OUT();//sda线输出
        IIC_SCL=0;
        IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
         delay_us(4);
        IIC_SCL=1; 
        IIC_SDA=1;//发送I2C总线结束信号
        delay_us(4);                                   
    }
     
    

    3、 应答信号

    • 发送器每发送一个字节,就在时钟脉冲9期间释放数据先,由接收器反馈一个应答信号。应答信号为低电平时,规定为有效应答位(ACK简称应答位),表示接收器已经成功接收了该字节;应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。
    • 对于反馈有效应答位ACK的要求是,接收器在第9个时钟脉冲之前的低电平期间将SDA线拉低,并且确保在该时钟的高电平期间位稳定的低电平。如果接收器是主控器,则在它收到最后一个字节后,发送一个NACK信号,以通知被控发送器结束数据发送,并释放SDA线,以便主控接收器发送一个停止信号P

    每当主机向从机发送完一个字节(8bit)的数据,主机总是需要等待从机给出一个应答信号,以确认从机是否成功接收到了数据,从机应答主机所需要的时钟仍是主机提供的,应答出现在每一次主机完成8个数据位传输后紧跟着的时钟周期,低电平0表示应答,1表示非应答:
    在这里插入图片描述
    应答程序

    //产生ACK应答
    //这里就很清楚了,产生应答:SCL在SDA一直为低电平期间完成低高电平转换
    void IIC_Ack(void)
    {
        IIC_SCL=0;
        SDA_OUT();
        IIC_SDA=0;
        delay_us(2);
        IIC_SCL=1;
        delay_us(2);
        IIC_SCL=0;
    }
    //不产生ACK应答    
    //这里就很清楚了,不产生应答:SCL在SDA一直为高电平期间完成低高电平转换
    void IIC_NAck(void)
    {
        IIC_SCL=0;
        SDA_OUT();
        IIC_SDA=1;
        delay_us(2);
        IIC_SCL=1;
        delay_us(2);
        IIC_SCL=0;
    }
    

    4、 发送数据

    • 在I2C总线上传送的每位数据都有一个时钟脉冲相对应(或同步控制),即在SCL串行时钟的配合下,SDA逐位地串行传送每一位数据。数据位的传输是边沿触发。

    发送程序

    //IIC发送一个字节
    //返回从机有无应答
    //1,有应答
    //0,无应答            
    
    //IIC_SCL=0;
    //在SCL上升沿时准备好数据,进行传送数据时,拉高拉低SDA,因为传输一个字节,一个SCL脉冲里传输一个位。
    //数据传输过程中,数据传输保持稳定(在SCL高电平期间,SDA一直保持稳定,没有跳变)
    //只有当SCL被拉低后,SDA才能被改变
    //总结:在SCL为高电平期间,发送数据,发送8次数据,数据为1,SDA被拉高,数据为0,SDA被拉低。
    //传输期间保持传输稳定,所以数据线仅可以在时钟SCL为低电平时改变。
    void IIC_Send_Byte(u8 txd)
    {                        
        u8 t;   
        SDA_OUT();         
        IIC_SCL=0;//拉低时钟开始数据传输
        for(t=0;t<8;t++)
        {              
            //IIC_SDA=(txd&0x80)>>7;
            //获取数据的最高位,然后左移7位
            //如果某位为1,则SDA为1,否则相反
            if((txd&0x80)>>7)
                IIC_SDA=1;
            else
                IIC_SDA=0;
            txd<<=1;       
            delay_us(2);   //对TEA5767这三个延时都是必须的
            IIC_SCL=1;
            delay_us(2); 
            IIC_SCL=0;    
            delay_us(2);
        }     
    }
    

    单片机发送完一个字节后面必须跟一个等外应答函数:
    思路:先让SDA=1,再判断在一定时间内SDA是否变为0,从而识别出外设有没有发送应答信号。

    //等待应答信号到来
    //返回值:1,接收应答失败
    //        0,接收应答成功
    //1.设置SDA为输入
    //2.拉高SDA
    //3.拉高SCL
    //4.等待接收器返回应答信号,如果数据线SDA一直为高,就一直等待,并返回1(无效应答),如果数据线SDA为低,返回0(有效应答)
    u8 IIC_Wait_Ack(void)
    {
        u8 ucErrTime=0;
        SDA_IN();      //SDA设置为输入  
        IIC_SDA=1;delay_us(1);       
        IIC_SCL=1;delay_us(1);     
        while(READ_SDA)
        {
            ucErrTime++;
            if(ucErrTime>250)
            {
                IIC_Stop();
                return 1;
            }
        }
        IIC_SCL=0;//时钟输出0        
        return 0;  
    }
    

    5、接收数据

    发送数据是一位一位发送,接收数据也是一位一位接收进来,最后返回应答信号:

    接收程序

    //读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
    
    //先拉低SCL,延时后拉高
    //读取数据
    //是否发送应答
    u8 IIC_Read_Byte(unsigned char ack)
    {
        unsigned char i,receive=0;
        SDA_IN();//SDA设置为输入
        for(i=0;i<8;i++ )
        {
            IIC_SCL=0; 
            delay_us(2);
            IIC_SCL=1;
            receive<<=1;
            if(READ_SDA)receive++;   
            delay_us(1); 
        }                     
        if (!ack)
            IIC_NAck();//发送nACK
        else
            IIC_Ack(); //发送ACK   
        return receive;
    }
    

    三、STM32的IIC的IO初始化

    //初始化 IIC
    void IIC_Init(void)
    {
     GPIO_InitTypeDef GPIO_InitStructure;
     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能 GPIOB 时钟
     //GPIOB8,B9 初始化设置
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
     GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
    IIC_SCL=1;
    IIC_SDA=1;
    }
    

    注: 该部分为 IIC 驱动代码,实现包括 IIC 的初始化(IO 口)、IIC 开始、IIC 结束、ACK、IIC读写等功能,在其他函数里面,只需要调用相关的 IIC 函数就可以和外部 IIC 器件通信了,该段代码可以用在任何 IIC 设备上。
    打开 myiic.h 头文件可以看到,我们除了函数申明之外,还定义了几个宏定义标识符:

    //IO 方向设置
    #define SDA_IN() {GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=0<<9*2;}
    //PB9 输入模式
    #define SDA_OUT() {GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=1<<9*2;} 
    //PB9 输出模式
    //IO 操作函数
    #define IIC_SCL PBout(8) //SCL
    #define IIC_SDA PBout(9) //SDA
    #define READ_SDA PBin(9) //输入 SDA
    

    该部分代码的 SDA_IN()和 SDA_OUT()分别用于设置 IIC_SDA 接口为输入和输出,是 IO 口的使用。其他几个宏定义就是我们通过位带实现 IO 口操作。

    展开全文
  • Modbus通信协议主要分为以下三种: Modbus RTU Modbus ASCII Modbus TCP 其中Modbus RTU与Modbus ASCII均为支持RS-485总线通信协议,其中Modbus RTU由于其采用二进制表现形式以及紧凑数据结构,通信效率较...
  • IIC通信协议

    2020-12-11 14:13:41
    I2C(Inter-Integrated CircuitBUS) 集成电路总线,该总线由NXP(原PHILIPS)公司设计,多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。 经常IIC和SPI...
  • I2C总线我会基于I2C官方协议共分两个章节为大家解惑,主分为入门与进阶, 入门主要讲解I2C协议是如何通信的,主机和从机之间是如何进行数据读写与传输。 进阶主要讲解I2C的高级使用,也就是常说的I2C的冒险与竞争,...
  • SPI通信协议总结

    2021-05-23 14:12:12
    概要 SPI是一种高速的,全双工,同步的通信总线。 SPI分为主、从两种模式,一个SPI通讯系统...缺点:没有指定的流控制,没有应答机制确认是否接收到数据,所以跟IIC总线协议比较在数据的可靠性上有一定的缺陷。 通
  • CAN通信协议

    2019-10-15 11:11:05
    目录 物理层 位速率 帧种类 总线仲裁 ...STM32 CAN控制器简介­bxCAN ...CAN控制器根据CAN_L和CAN_H上...总线电平分为显性电平和隐性电平,二者必居其一。发送方通过使总线电平发生变化,将消息发送给接收方。 如...
  • 1、连接在IIC总线上的器件分为主机和从机,主机可以发起和结束一次通信,从机只能被主机呼叫。 2、冲突检测、仲裁功能:多个主机同时启用总线,防止错误。 3、IIC总线上的器件都有一个唯一的地址(7bit),且每个...
  • 彻底弄懂IIC总线协议

    2020-11-29 22:56:56
    IIC总线是一种多主机总线,连接在IIC总线上的部分器件分为主机和从机,主机有权发起和结束一次通信,而从机只能被主机呼叫;当总线上有多个主机同时启用总线时,IIC也具有冲突检测和仲裁的功能来防止错误产生;每个...
  • IIC通信协议总结

    万次阅读 多人点赞 2015-09-07 15:31:51
    I2C(Inter-Integrated Circuit BUS) 集成电路总线,该总线由NXP(原PHILIPS)公司设计,多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。 经常IIC和SPI...
  • I2C通信协议

    千次阅读 2019-08-20 17:11:35
    1. 协议简介 I2C总线是PHLIPS公司在20世纪80年代推出的一种串行总线。具有引脚少,硬件实现简单...在嵌入式开发中,通讯协议分为两层:物理层和协议层。物理层是数据在物理媒介传输的保障;协议层主要是规定通讯...
  • IIC通信协议学习

    2018-03-21 14:50:00
    I2C(Inter-Integrated CircuitBUS) 集成电路总线,该总线由NXP(原PHILIPS)公司设计,多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。 经常IIC和SPI...
  • modbus通信协议

    热门讨论 2010-08-06 15:26:22
    Modbus通信协议 摘 要:工业控制已从单机控制走向集中监控、集散控制,如今已进入网络时代,工业控制器连网也为网络管理提供了方便。Modbus就是工业控制器的网络协议中的一种。关键词:Modbus协议;串行通信;LRC...
  • sccb 串行摄像机控制总线协议

    千次阅读 2016-06-01 10:52:29
    目前,SCCB总线通信协议只支持100Kb/s或400Kb/s的传输速度,并且支持两种地址形式:①从设备地址(ID Address,8bit),分为读地址和写地址,高7位用于选中芯片, 第0位是读/写控制位(R/W),决定是对该芯片进行...
  • 一、 引言  一个现代化工业企业的网络环境一般可分为四个层次:  ·Internet:实现企业之间的信息交流; ·Intranet:实现企业内部管理... Infranet的建设目前主要采用各种现场总线协议,如ProfiBus、Lonwork、CA
  • IIC总线协议和时序

    2018-06-24 11:39:00
    IIC标准速率为100Kbit/s,快速模式400Kbit/s,支持多机通信,支持多主控模块,但是同一时刻只允许有一个主控。由数据线SDA和时钟SCL构成串行总线;每个电路模块都有唯一地址。I2C设备的操作可分为写单个字节存储,写...
  • IIC总线是一种多主机总线,连接在IIC线上的器件分为主机和从机,主机有权发起和结束一次通信,而从机只能被主机呼叫;当总线上有多个主机同时启用总线时,IIC也具备冲突检测和仲裁的功能来防止错误产生;每个连接到...
  • I2C总线协议原理

    2020-03-26 11:24:45
    首先I2C总线一共分为2根,一根是SCL(serial clock),还有一根是SDA(serial data),一根是用来同步时钟的,一根是发送接收数据的,因为有时钟的同步,所以很显然,I2C用的是同步通信的方式。 在SDA和SCL总线上...
  • I2C总线协议详解系列3

    2019-12-24 11:33:35
    BUS) 集成电路总线,该总线由NXP(原PHILIPS)公司设计,多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。 经常IIC和SPI接口被认为指定是一种硬件设备,...
  • OSI参考模型是一个逻辑上的定义,一个规范,它把网络从逻辑上分为七层,每一层都对应着不同的作用,这七层分别为应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。对OSI七层网络模型的定义,对后续的...
  • 帧:时间概念,在USB通信中,一帧就是1ms,它是一个独立的单元,包含一系列总线动作,USB将一帧分为好几份,每一份就是一个USB传输动作。 上行、下行:设备到主机为上行,主机到设备为下行。 USB 的基础知识 USB的...
  • 总线(BUS,即公共汽车,数据的公共传输路线)分类的方式有很多,如被分为外部和内部总线、系统总线和非系统总线等等,下面是几种最常用的分类方法。另外,总线的传输核心思想是多路复用:时分多路复用-TDMA/频分多...
  • 本文主要介绍一个简单的单一设备PCIE驱动程序和设备的通信协议,从上到下大致分为三层:应用层、驱动层和设备层。其中,应用层和驱动层通过系统总线(win32 API调用)实现通信,驱动层和设备层通过PCI总线(地址空间...
  • IIC(Inter-Integrated Circuit, 内部集成电路)总线是飞利浦公司开发的两线式串行总线,用于短距离传输,常用于微控制器及其外围设备,只有二根信号线,一根是双向的数据线SDA,另一根是时钟线SCL,两条线可以挂多个...
  • ,使用该协议通信波特率可以达到10Mbps,达到RS422接口总线的波特率上限[3],是其它一些同类常用串行通信协议(如SSI,EnDat,Hiperface,起止式异步协议)的5倍以上。  注:起止式指一种常用的异步串行通

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 207
精华内容 82
关键字:

总线通信协议分为