嵌入式接口期末复习-(江苏海洋大学)---(第六部分 SPI IIC)

一: 回顾USART 已经内容补充

1.回顾USART (具体内容见以往文件)

 2.IIC通信(了解就好)

1.IIC是半双工通信方式

2. 多主机IIC总线系统结构

 3.IIC协议

[1]空闲状态

        IIC总线的SDA和SCL两条信号线同时处于高电平时,规定为总线的空闲状态。

        此时各个器件的输出级场效应管均处在截止状态,也就是释放总线,由两条信号线各自的上拉电阻把电平拉高


[2]起始信号与停止信号

       起始信号:  当SCL为高期间,SDA由高到低的跳变;启动信号时一种电平跳变时序信号,而不是一个电平信号

       停止信号:  当SCL为高期间,SDA由低到高的跳变;启动信号时一种电平跳变时序信号,而不是一个电平信号

 


 [3]应答信号ACK

         发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。应答信号为低电平时,规定为有效应答位(ACK简称应答位),表示接收器已经成功地接收了该字节:应答信号为高电平时,规定为非应答!位(NACK),一 般表示接收器接收该字节没有成功。

        对于反馈有效应答位ACK的要求是,接收器在第9个时钟脉冲之前的低电平 期间将SDA线拉低,并且确保在该时钟的高电平期间为稳定的低电平。如果 接收器是主控器,则在它收到最后一个字节后,发送一个NACK信号,以通知 被控发送器结束数据发送,并释放SDA线,以便主控接收器发送一个停止信号P。

 


[4]数据的有效性 

        IIC总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必 须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平 或低电平状态才允许变化。 即:数据在SCL的上升沿到来之前就需准备好。并在在下降沿到来之 前必须稳定。

 

 



#include "stm32f4xx.h"
#include "delay.h"
#define I2C_GPIO                GPIOA
#define I2C_CLK                 RCC_AHB1Periph_GPIOA
#define PIN_SCL                 GPIO_Pin_1 
#define PIN_SDA                 GPIO_Pin_0  

#define SDA_R                   GPIO_ReadInputDataBit(I2C_GPIO,PIN_SDA)

/*********************************************************************************************
* 名称:iic_init()
* 功能:I2C初始化函数
* 参数:无
* 返回:无
*********************************************************************************************/
void iic_init(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
  RCC_AHB1PeriphClockCmd(I2C_CLK, ENABLE);
  
  GPIO_InitStructure.GPIO_Pin = PIN_SCL | PIN_SDA;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  
  GPIO_Init(I2C_GPIO, &GPIO_InitStructure);  
  
}

/*********************************************************************************************
* 名称:sda_out()
* 功能:设置SDA为输出
* 参数:无
* 返回:无
*********************************************************************************************/
void sda_out(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = PIN_SDA;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  
  GPIO_Init(I2C_GPIO, &GPIO_InitStructure);  
}

/*********************************************************************************************
* 名称:sda_in()
* 功能:设置SDA为输入
* 参数:无
* 返回:无
*********************************************************************************************/
void sda_in(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = PIN_SDA;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  
  GPIO_Init(I2C_GPIO, &GPIO_InitStructure);  
}

/*********************************************************************************************
* 名称:iic_start()
* 功能:I2C起始信号
* 参数:无
* 返回:无
*********************************************************************************************/
void iic_start(void)
{
  sda_out();
  GPIO_SetBits(I2C_GPIO,PIN_SDA);                               //拉高数据线
  GPIO_SetBits(I2C_GPIO,PIN_SCL);                               //拉高时钟线
  delay_us(5);                                                  //延时
  GPIO_ResetBits(I2C_GPIO,PIN_SDA);                             //产生下降沿
  delay_us(5);                                                  //延时
  GPIO_ResetBits(I2C_GPIO,PIN_SCL);                             //拉低时钟线
}

/*********************************************************************************************
* 名称:iic_stop()
* 功能:I2C停止信号
* 参数:无
* 返回:无
*********************************************************************************************/
void iic_stop(void)
{
  sda_out();
  GPIO_ResetBits(I2C_GPIO,PIN_SDA);                             //拉低数据线
  GPIO_SetBits(I2C_GPIO,PIN_SCL);                               //拉高时钟线
  delay_us(5);                                                  //延时5us
  GPIO_SetBits(I2C_GPIO,PIN_SDA);                               //产生上升沿
  delay_us(5);                                                  //延时5us
}

/*********************************************************************************************
* 名称:iic_send_ack()
* 功能:I2C发送应答
* 参数:ack -- 应答信号
* 返回:无
*********************************************************************************************/
void iic_send_ack(int ack)
{
  sda_out();
  if(ack)
    GPIO_SetBits(I2C_GPIO,PIN_SDA);                             //写应答信号
  else
    GPIO_ResetBits(I2C_GPIO,PIN_SCL); 
  GPIO_SetBits(I2C_GPIO,PIN_SCL);                               //拉高时钟线
  delay_us(5);                                                  //延时
  GPIO_ResetBits(I2C_GPIO,PIN_SCL);                             //拉低时钟线
  delay_us(5);                                                  //延时
}

/*********************************************************************************************
* 名称:iic_recv_ack()
* 功能:I2C接收应答
* 参数:无
* 返回:无
*********************************************************************************************/
int iic_recv_ack(void)
{
  int CY = 0;
  sda_in();
  GPIO_SetBits(I2C_GPIO,PIN_SCL);                               //拉高时钟线
  delay_us(5);                                                  //延时
  CY = SDA_R;                                                   //读应答信号
  GPIO_ResetBits(I2C_GPIO,PIN_SDA);                             //拉低时钟线
  delay_us(5);                                                  //延时
  return CY;
}

/*********************************************************************************************
* 名称:iic_write_byte()
* 功能:I2C写一个字节数据,返回ACK或者NACK,从高到低,依次发送
* 参数:data -- 要写的数据
* 返回:无
*********************************************************************************************/
unsigned char iic_write_byte(unsigned char data)
{
  unsigned char i;
  sda_out();
  GPIO_ResetBits(I2C_GPIO,PIN_SCL);                             //拉低时钟线
  for(i = 0;i < 8;i++){                                         
    if(data & 0x80){                                            //判断数据最高位是否为1
      GPIO_SetBits(I2C_GPIO,PIN_SDA);  	                                                
    }
    else
      GPIO_ResetBits(I2C_GPIO,PIN_SDA); 
    delay_us(5);                                                //延时5us
    GPIO_SetBits(I2C_GPIO,PIN_SCL); 	                        //输出SDA稳定后,拉高SCL给出上升沿,从机检测到后进行数据采样
    delay_us(5);                                                //延时5us
    GPIO_ResetBits(I2C_GPIO,PIN_SCL);                           //拉低时钟线
    delay_us(5);                                                //延时5us
    data <<= 1;                                                 //数组左移一位
  } 
  delay_us(5);                                                  //延时2us
  sda_in();
  GPIO_SetBits(I2C_GPIO,PIN_SDA);                               //拉高数据线
  GPIO_SetBits(I2C_GPIO,PIN_SCL);                               //拉高时钟线
  delay_us(5);                                                  //延时2us,等待从机应答
  if(SDA_R){			                                //SDA为高,收到NACK
    return 1;	
  }else{ 				                        //SDA为低,收到ACK
    GPIO_ResetBits(I2C_GPIO,PIN_SCL);                           //释放总线                  
    delay_us(5);                                                //延时2us,等待从机应答
    return 0;
  }
}

/*********************************************************************************************
* 名称:iic_read_byte()
* 功能:I2C写一个字节数据,返回ACK或者NACK,从高到低,依次发送
* 参数:data -- 要写的数据
* 返回:无
*********************************************************************************************/
unsigned char iic_read_byte(unsigned char ack)
{
  unsigned char i,data = 0;
  sda_in();
  GPIO_ResetBits(I2C_GPIO,PIN_SCL); 
  GPIO_SetBits(I2C_GPIO,PIN_SDA);  			        //释放总线	
  for(i = 0;i < 8;i++){
    GPIO_SetBits(I2C_GPIO,PIN_SCL);  		                //给出上升沿
    delay_us(30);	                                        //延时等待信号稳定
    data <<= 1;	
    if(SDA_R){ 		                                        //采样获取数据
      data |= 0x01;
    }else{
      data &= 0xfe;
    }
    delay_us(10);
    GPIO_ResetBits(I2C_GPIO,PIN_SCL);    		        //下降沿,从机给出下一位值
    delay_us(20);
  }
  sda_out();
  if(ack)
    GPIO_SetBits(I2C_GPIO,PIN_SDA);	                        //应答状态
  else
    GPIO_ResetBits(I2C_GPIO,PIN_SDA);  
  delay_us(10);
  GPIO_SetBits(I2C_GPIO,PIN_SCL);                        
  delay_us(50);          
  GPIO_ResetBits(I2C_GPIO,PIN_SCL); 
  delay_us(50);
  return data;
}

/*********************************************************************************************
* 名称:delay()
* 功能:延时
* 参数:t -- 设置时间
* 返回:无
*********************************************************************************************/
void delay(unsigned int t)                                      //延时函数
{
  unsigned char i;
  while(t--){
    for(i = 0;i < 200;i++);
  }					   
}

3:SPI

 1.接口框图

 2.内部结构图

 3.

 4.工作原理

[1]硬件上为4根线。

[2]主机和从机都有一个串行移位寄存器, 主机通过 向它的SPI 串行寄存器写入一个字节来发起一次传输。

[3]串行移位寄存器通过MOSI信号线将字节传送给从机,从机 也将自己的串行移位寄存器中的内容通过MISO信号线返回 给主机。这样,两个移位寄存器中的内容就被交换。

[4]外设的写操作和读操作是同步完成的。如果只进行写操作, 主机只需忽略接收到的字节,反之,若主机要读取从机的一 个字节,就必须发送一一个空字节来引发从机的传输。

5.

 

 


#include "spi.h"

* 名称:SPI3_Init
* 功能:SPI3初始化,配置成主机模式 

void SPI3_Init(void)
{	 
  GPIO_InitTypeDef  GPIO_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;
  
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);         //使能GPIOB时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);          //使能SPI3时钟
  
  //GPIOB3,4,5初始化设置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;//PB3~5复用功能输出	
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;                  //复用功能
  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);                        //初始化
  
  GPIO_PinAFConfig(GPIOB,GPIO_PinSource3,GPIO_AF_SPI3);         //PB3复用为 SPI3
  GPIO_PinAFConfig(GPIOB,GPIO_PinSource4,GPIO_AF_SPI3);         //PB4复用为 SPI3
  GPIO_PinAFConfig(GPIOB,GPIO_PinSource5,GPIO_AF_SPI3);         //PB5复用为 SPI3	
  
  //这里只针对SPI口初始化
  RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3,ENABLE);           //复位SPI3
  RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3,DISABLE);          //停止复位SPI3
  
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;		        //设置SPI工作模式:设置为主SPI
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;		//设置SPI的数据大小:SPI发送接收8位帧结构
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;		        //串行同步时钟的空闲状态为高电平
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;	                //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;		        //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;		//定义波特率预分频的值:波特率预分频值为256
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
  SPI_InitStructure.SPI_CRCPolynomial = 7;	                //CRC值计算的多项式
  SPI_Init(SPI3, &SPI_InitStructure);                           //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
  
  SPI_Cmd(SPI3, ENABLE);                                        //使能SPI外设
  
  SPI3_ReadWriteByte(0xff);                                     //启动传输		 
}   

/*********************************************************************************************
* 名称:SPI3_SetSpeed(u8 SPI_BaudRatePrescaler)
* 功能:SPI3速度设置函数
* 参数:SPI_BaudRatePrescaler
* 返回:
* 修改:
* 注释:SPI速度=fAPB2/分频系数
SPI_BaudRate_Prescaler:SPI_BaudRatePrescaler_2~SPI_BaudRatePrescaler_256  
fAPB2时钟一般为84Mhz
*********************************************************************************************/
void SPI3_SetSpeed(u8 SPI_BaudRatePrescaler)
{
  assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));//判断有效性
  SPI3->CR1&=0XFFC7;                                            //位3-5清零,用来设置波特率
  SPI3->CR1|=SPI_BaudRatePrescaler;	                        //设置SPI1速度 
  SPI_Cmd(SPI2,ENABLE);                                         //使能SPI1
} 

/*********************************************************************************************
* 名称:SPI3_ReadWriteByte(u8 TxData)
* 功能:SPI3 读写一个字节
* 参数:TxData:要写入的字节
* 返回:读取到的字节
* 修改:
* 注释:
*********************************************************************************************/
u8 SPI3_ReadWriteByte(u8 TxData)
{		 			 
  
  while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET){}//等待发送区空  
  
  SPI_I2S_SendData(SPI3, TxData);                               //通过外设SPIx发送一个byte  数据
  
  while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET){} //等待接收完一个byte  
  
  return SPI_I2S_ReceiveData(SPI3);                             //返回通过SPIx最近接收的数据	
  
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: iic_slaver.rar_iic时序是一个嵌入式文档类资源。在嵌入式系统中,iic_slaver.rar文件是一个包含了iic(Inter-Integrated Circuit)接口的从设备(slaver)的时序信息的压缩文件。 iic是一种串行通信协议,主要用于各种嵌入式设备之间的数据传输。iic接口由两根线组成,一根是数据线(SDA),另一根是时钟线(SCL)。在iic_slaver.rar中,我们可以找到从设备在这个接口上进行数据传输的具体时序信息。 iic_slave.rar文件中的时序信息对于开发者来说是非常重要的,因为它们描述了从设备与主设备之间的数据传输时机、数据的发送和接收顺序,以及时钟信号的频率等细节。通过分析时序信息,开发者可以了解从设备与主设备之间的通信规则,从而正确编写驱动程序以实现数据的稳定传输。 此外,iic_slaver.rar_iic时序还可能包含从设备的相关文档,如寄存器映射表和时序等。这些文档提供了关于从设备硬件的更详细的信息,帮助开发者了解从设备的工作原理和寄存器的使用方法。 总之,iic_slaver.rar_iic时序是一个非常实用的嵌入式文档资源,它包含了关于iic接口从设备的时序信息以及相关的文档资料,对于进行嵌入式开发的人员来说,这些资料是非常重要的参考。 ### 回答2: iic_slaver.rar_iic时序是一种嵌入式文档类资源。嵌入式系统是指嵌入在其他设备或系统中的计算机系统,通常用于控制、监测或通信等目的。这种时序文档资源主要用于描述iic从设备的时序,以指导嵌入式开发人员在设计和实现中遵循正确的时序要求。 在嵌入式系统中,IIC(Inter-Integrated Circuit)是一种常见的串行通信接口协议,用于在主设备和从设备之间进行数据传输。IIC协议通常被用于连接各种外设(如传感器、存储器等)和微控制器等嵌入式系统中的主控制器。 iic_slaver.rar_iic时序资源是一个被压缩为.rar文件的文档资源。该资源通过解压缩后,可以获取到其中的iic时序文档,该文档对于嵌入式开发人员来说非常有用。iic时序文档描述了在使用IIC协议进行通信时所需的时序要求,包括信号的时序顺序、时钟信号的频率、数据传输的速率等。 嵌入式系统的开发通常需要遵循一定的时序规范,以确保数据传输的准确性和稳定性。因此,iic_slaver.rar_iic时序文档资源可以为开发人员提供了解和理解IIC协议时序要求的参考资料。在使用这一资源时,开发人员可以通过查阅其中的iic时序文档,了解IIC协议的时序要求,并根据文档中的指导,设计和调整嵌入式系统中与IIC通信相关的电路和程序。 总之,iic_slaver.rar_iic时序是一种嵌入式文档类资源,通过提供IIC通信协议的时序要求文档,帮助嵌入式开发人员编写和调试与IIC相关的程序和电路。 ### 回答3: iic_slaver.rar_iic时序是一种嵌入式文档类资源。在嵌入式系统中,I2C总线被广泛应用于连接微处理器和各种外设,用于实现数据传输和通信。iic_slaver.rar文件中包含了关于I2C从机(iic_slaver)的相关文档和资源。 I2C(Inter-Integrated Circuit)是由飞利浦公司开发的一种串行通信总线标准。它采用两根线进行数据传输,即SDA(Serial Data Line)和SCL(Serial Clock Line)。其中SDA用于数据传输,SCL用于时钟同步。通过使用I2C总线,嵌入式设备可以与各种传感器、存储器、显示器、控制器等外设进行通信。 iic_slaver.rar文件中的I2C时序文档详细描述了iic_slaver从机设备与主控设备之间的数据传输时序要求。通过按照这些时序要求进行数据读取和写入操作,可以实现可靠的数据传输和通信。这些时序要求包括时钟频率、数据传输速率、起始信号、停止信号等。 此外,iic_slaver.rar文件中可能还包含有关iic_slaver从机设备的硬件设计参考资料、软件开发工具和示例代码等。这些资源可以帮助开发人员设计和开发符合I2C标准的嵌入式设备,并实现与其他设备的通信和数据交换。 总之,iic_slaver.rar_iic时序是一种嵌入式文档类资源,它提供了关于I2C从机设备的时序要求、硬件设计参考和开发工具等资源,帮助开发人员设计和实现嵌入式设备之间的可靠通信和数据传输。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值