STM32---SPI 的CPOL、CPHA

设备与设备之间通过某种硬件接口通讯,目前存在很多种接口,SPI接口是其中的一种。

SPI中分Master主设备和Slave从设备,数据发送都是由Master控制。

一个master可以接一个或多个slave常见用法是一个Master接一个slave.

通信只需要4根线:SCLK, MISO, MOSI, SS

SCLK:(Serial Clock)(串行)时钟

MISO(Master In Slave Out)主设备输入,从设备输出

MOSI:(Master Out Slave In)主设备输出,从设备输入

SS:(Slave Select)从设备,片选

SPI由于接口相对简单(只需要4根线),用途算是比较广泛,主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。

SPI的相位和极性】

CPOLCPHA,分别都可以是0或时1,对应的四种组合就是:

Mode 0 CPOL=0, CPHA=0
Mode 1 CPOL=0, CPHA=1
Mode 2 CPOL=1, CPHA=0
Mode 3 CPOL=1, CPHA=1

image001.png

单独看这张图,的确很难明白具体含义,所以下面会有更详细的解释。

 CPOL极性】

Clock Polarity = IDLE state of SCK

再用中文详解:

SPICPOL,表示当SCLK空闲idle的时候,其电平的值是低电平0还是高电平1

CPOL=0,时钟空闲idle时候的电平是低电平,所以当SCLK有效的时候,就是高电平,就是所谓的active-high

CPOL=1,时钟空闲idle时候的电平是高电平,所以当SCLK有效的时候,就是低电平,就是所谓的active-low


 CPHA相位】

首先说明一点,capture strobe = latch = read = sample,都是表示数据采样,数据有效的时刻。

相位,对应着数据采样是在第几个边沿(edge),是第一个边沿还是第二个边沿,0对应着第一个边沿,1对应着第二个边沿。

对于:

CPHA=0,表示第一个边沿:

对于CPOL=0idle时候的是低电平,第一个边沿就是从低变到高,所以是上升沿;

对于CPOL=1idle时候的是高电平,第一个边沿就是从高变到低,所以是下降沿;

CPHA=1,表示第二个边沿:

对于CPOL=0idle时候的是低电平,第二个边沿就是从高变到低,所以是下降沿;

对于CPOL=1idle时候的是高电平,第一个边沿就是从低变到高,所以是上升沿;

用图文形式表示,更加容易看懂:

image002.jpg


image003.jpg

image004.jpg




  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
很高兴为您解答这个问题。以下是针对STM32-24位AD7799驱动手册代码详解的简要说明。 首先,AD7799是一款24位精度的模数转换器,可用于测量各种传感器的输出信号。它可通过SPI接口与微控制器(如STM32)通信,以读取和写入寄存器值。 在STM32中,可以采用模拟SPI或硬件SPI与AD7799通信,具体实现方式取决于使用的STM32型号和开发环境。以下是一些可能使用的代码和说明: 1. 模拟SPI方式: ```c // 初始化GPIO口 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); // 初始化SPI void SPI_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB,&GPIO_InitStructure); } void AD7799_SPI_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); SPI_InitTypeDef SPI_InitStructure; SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_Init(SPI1, &SPI_InitStructure); SPI_Cmd(SPI1, ENABLE); } // SPI发送数据 uint8_t AD7799_SPI_Write(uint8_t data) { uint8_t i; for(i = 0; i < 8; i++) { if(data & 0x80) GPIO_SetBits(GPIOB, GPIO_Pin_9); else GPIO_ResetBits(GPIOB, GPIO_Pin_9); data <<= 1; GPIO_ResetBits(GPIOB, GPIO_Pin_10); GPIO_SetBits(GPIOB, GPIO_Pin_10); } return data; } // SPI接收数据 uint8_t AD7799_SPI_Read(void) { uint8_t i, data = 0; for(i = 0; i < 8; i++) { data <<= 1; GPIO_ResetBits(GPIOB, GPIO_Pin_10); if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)) data |= 0x01; GPIO_SetBits(GPIOB, GPIO_Pin_10); } return data; } ``` 2. 硬件SPI方式: ```c // 初始化SPI void AD7799_SPI_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); SPI_InitTypeDef SPI_InitStructure; SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_Init(SPI1, &SPI_InitStructure); SPI_Cmd(SPI1, ENABLE); } // SPI发送数据 uint8_t AD7799_SPI_Write(uint8_t data) { while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI1, data); while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); return SPI_I2S_ReceiveData(SPI1); } ``` 上述代码只是示例,具体实现方式需要根据您的应用场景进行调整。同时,还需要编写读取和写入AD7799寄存器的函数,例如: ```c // AD7799写寄存器函数 void AD7799_WriteReg(uint8_t reg, uint16_t value) { AD7799_SPI_Write(reg << 3); AD7799_SPI_Write(value >> 8); AD7799_SPI_Write(value & 0xFF); } // AD7799读寄存器函数 uint16_t AD7799_ReadReg(uint8_t reg) { uint16_t value = 0; AD7799_SPI_Write((reg << 3) | 0x04); value |= AD7799_SPI_Read() << 8; value |= AD7799_SPI_Read(); return value; } ``` 以上是一个简单的STM32-24位AD7799驱动手册代码详解。希望能帮助到您!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值