打印
[STM32F4]

STM32知识点分享+控制PCA9548

[复制链接]
5823|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 gujiamao12345 于 2017-9-13 10:10 编辑

在一个项目中需要比较多的IIC从设备,但是又担心驱动能力不够,所以选用了PCA9548这个八通道的IIC开关,部分电路图如附件所示,主控用的是STM32F405,为什么要用它呢,明明STM8就可以实现同样的功能,因为没用过F4系列,尝试下。

MCU.png (456.59 KB )

MCU.png
沙发
gujiamao12345|  楼主 | 2017-9-13 10:12 | 只看该作者
代码如下:
#include "PCA9548.h"

__IO uint32_t  PCA9548I2CTimeout = PCA9548_I2C_Open_LONG_TIMEOUT;
void pca9548_init(void)
{
        I2C_InitTypeDef  I2C_InitStructure;
        GPIO_InitTypeDef  GPIO_InitStructure;
       
        RCC_AHB1PeriphClockCmd(PCA9548_I2C_SDA_GPIO_CLK | PCA9548_I2C_SCL_GPIO_CLK,ENABLE);
       
        RCC_APB1PeriphClockCmd(PCA9548_I2C_CLK,ENABLE);
       
        GPIO_PinAFConfig(PCA9548_I2C_SDA_GPIO_PORT, PCA9548_I2C_SDA_SOURCE, PCA9548_I2C_SDA_AF);
        GPIO_PinAFConfig(PCA9548_I2C_SCL_GPIO_PORT, PCA9548_I2C_SCL_SOURCE, PCA9548_I2C_SCL_AF);
       
        GPIO_InitStructure.GPIO_Pin =  PCA9548_I2C_SDA_PIN | PCA9548_I2C_SCL_PIN;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
               
        I2C_DeInit(PCA9548_I2C);
        I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
        I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
        I2C_InitStructure.I2C_OwnAddress1 = PCA9548_I2C_SLAVE_ADDRESS7;
        I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
        I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
        I2C_InitStructure.I2C_ClockSpeed = PCA9548_I2C_SPEED;
       
        I2C_Cmd(PCA9548_I2C, ENABLE);
        I2C_Init(PCA9548_I2C, &I2C_InitStructure);
       
        I2C_AcknowledgeConfig(PCA9548_I2C, ENABLE);
}

static void I2C_AcknowledgePolling(I2C_TypeDef *I2Cx,uint8_t I2C_Addr)
{
  vu16 SR1_Tmp;
  do {   
    I2C_GenerateSTART(I2Cx, ENABLE);
    SR1_Tmp = I2C_ReadRegister(I2Cx, I2C_Register_SR1);
          I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);
  } while(!(I2C_ReadRegister(I2Cx, I2C_Register_SR1) & 0x0002));
  
  I2C_ClearFlag(I2Cx, I2C_FLAG_AF);  
  I2C_GenerateSTOP(I2Cx, ENABLE);
}

//option : 0 -> write
//option : 1 -> read
uint8_t PCA9548_Channel_Select(uint8_t channel)
{
        PCA9548I2CTimeout = PCA9548_I2C_Open_LONG_TIMEOUT;
        while(I2C_GetFlagStatus(PCA9548_I2C, I2C_FLAG_BUSY)) {
                if((PCA9548I2CTimeout--) == 0) {
                        return 10;
                }
        }
       
        I2C_GenerateSTART(PCA9548_I2C, ENABLE);
        PCA9548I2CTimeout = PCA9548_I2C_Open_FLAG_TIMEOUT;
        while(!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_MODE_SELECT)) {
                if((PCA9548I2CTimeout--) == 0) {
                        return 11;
                }
        }
       
        PCA9548I2CTimeout = PCA9548_I2C_Open_FLAG_TIMEOUT;
        I2C_Send7bitAddress(PCA9548_I2C, 0xE8, I2C_Direction_Transmitter);
        while(!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
                if((PCA9548I2CTimeout--) == 0) {
                        return 12;
                }
        }

        I2C_SendData(PCA9548_I2C, 0xE8);

        PCA9548I2CTimeout = PCA9548_I2C_Open_FLAG_TIMEOUT;  
        while(!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
                if((PCA9548I2CTimeout--) == 0) {
                        return 13;
                }
        }

        I2C_SendData(PCA9548_I2C, channel);
        PCA9548I2CTimeout = PCA9548_I2C_Open_FLAG_TIMEOUT;  
  while(!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
    if((PCA9548I2CTimeout--) == 0) {
                        return 14;
                }
  }
       
        I2C_GenerateSTOP(PCA9548_I2C, ENABLE);
        I2C_AcknowledgePolling(PCA9548_I2C, 0xE8);
       
        return 0;
}

//option : 0 -> write
//option : 1 -> read
uint8_t PCA9548_Channel_Select_1(uint8_t channel)
{
        PCA9548I2CTimeout = PCA9548_I2C_Open_LONG_TIMEOUT;
        while(I2C_GetFlagStatus(PCA9548_I2C, I2C_FLAG_BUSY)) {
                if((PCA9548I2CTimeout--) == 0) {
                        return 10;
                }
        }
       
        I2C_GenerateSTART(PCA9548_I2C, ENABLE);
        PCA9548I2CTimeout = PCA9548_I2C_Open_FLAG_TIMEOUT;
        while(!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_MODE_SELECT)) {
                if((PCA9548I2CTimeout--) == 0) {
                        return 11;
                }
        }
       
        PCA9548I2CTimeout = PCA9548_I2C_Open_FLAG_TIMEOUT;
        I2C_Send7bitAddress(PCA9548_I2C, 0xEC, I2C_Direction_Transmitter);
        while(!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
                if((PCA9548I2CTimeout--) == 0) {
                        return 12;
                }
        }

        I2C_SendData(PCA9548_I2C, 0xEC);

        PCA9548I2CTimeout = PCA9548_I2C_Open_FLAG_TIMEOUT;  
        while(!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
                if((PCA9548I2CTimeout--) == 0) {
                        return 13;
                }
        }

        I2C_SendData(PCA9548_I2C, channel);
        PCA9548I2CTimeout = PCA9548_I2C_Open_FLAG_TIMEOUT;  
  while(!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
    if((PCA9548I2CTimeout--) == 0) {
                        return 14;
                }
  }
       
        I2C_GenerateSTOP(PCA9548_I2C, ENABLE);
        I2C_AcknowledgePolling(PCA9548_I2C, 0xEC);
       
        return 0;
}

//must called after PCA9548_Channel_Select
uint8_t DS125BR401A_Write_Reg(uint8_t addr, uint8_t reg, uint8_t value)
{
        PCA9548I2CTimeout = PCA9548_I2C_Open_LONG_TIMEOUT;
        while(I2C_GetFlagStatus(PCA9548_I2C, I2C_FLAG_BUSY)) {
                if((PCA9548I2CTimeout--) == 0) {
                        return 10;
                }
        }
       
        I2C_GenerateSTART(PCA9548_I2C, ENABLE);
        PCA9548I2CTimeout = PCA9548_I2C_Open_FLAG_TIMEOUT;
        while(!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_MODE_SELECT)) {
                if((PCA9548I2CTimeout--) == 0) {
                        return 11;
                }
        }
       
        PCA9548I2CTimeout = PCA9548_I2C_Open_FLAG_TIMEOUT;
        I2C_Send7bitAddress(PCA9548_I2C, addr, I2C_Direction_Transmitter);
        while(!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
                if((PCA9548I2CTimeout--) == 0) {
                        return 12;
                }
        }

        /*I2C_SendData(PCA9548_I2C, addr);
        PCA9548I2CTimeout = PCA9548_I2C_Open_FLAG_TIMEOUT;  
        while(!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
                if((PCA9548I2CTimeout--) == 0) {
                        return 13;
                }
        }*/
       
        I2C_SendData(PCA9548_I2C, reg);
        PCA9548I2CTimeout = PCA9548_I2C_Open_FLAG_TIMEOUT;  
        while(!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
                if((PCA9548I2CTimeout--) == 0) {
                        return 14;
                }
        }
       
        I2C_SendData(PCA9548_I2C, value);
        PCA9548I2CTimeout = PCA9548_I2C_Open_FLAG_TIMEOUT;  
  while(!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
    if((PCA9548I2CTimeout--) == 0) {
                        return 15;
                }
  }
       
        I2C_GenerateSTOP(PCA9548_I2C, ENABLE);
        I2C_AcknowledgePolling(PCA9548_I2C, addr);
       
        return 0;
}

uint8_t DS125BR401A_Read_Reg(uint8_t addr, uint8_t reg)
{
        uint8_t Byte = 0;
        while(I2C_GetFlagStatus(PCA9548_I2C, I2C_FLAG_BUSY));
               
        I2C_AcknowledgeConfig(PCA9548_I2C, ENABLE);

        I2C_GenerateSTART(PCA9548_I2C, ENABLE);
        while(!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_MODE_SELECT));

        I2C_Send7bitAddress(PCA9548_I2C,  addr, I2C_Direction_Transmitter);
        while (!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

        I2C_SendData(PCA9548_I2C, reg);
        while (!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
               
        I2C_GenerateSTART(PCA9548_I2C, ENABLE);
        while(!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_MODE_SELECT));
       
        I2C_Send7bitAddress(PCA9548_I2C, addr, I2C_Direction_Receiver);
        while(!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
       
        I2C_AcknowledgeConfig(PCA9548_I2C, DISABLE);
        I2C_GenerateSTOP(PCA9548_I2C, ENABLE);
            
        while(!I2C_CheckEvent(PCA9548_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED));  /* EV7 */
        Byte = I2C_ReceiveData(PCA9548_I2C);

        I2C_AcknowledgeConfig(PCA9548_I2C, ENABLE);

        return Byte;
}

uint8_t DS125BR401A_Write_All_Regs(uint8_t addr)
{
        volatile uint8_t value = 0;
        value = DS125BR401A_Read_Reg(addr, 0x51);
        //power down
        if(DS125BR401A_Write_Reg(addr, 0x1, 0x0)) {
                return 1;
        }
        //if(0x0 != DS125BR401A_Read_Reg(addr, 0x1)) {
                //return 0;
        //}
        //allow power down
        if(DS125BR401A_Write_Reg(addr, 0x2, 0x0)) {
                return 2;
        }
        //linera EQ
        if(DS125BR401A_Write_Reg(addr, 0x4, 0xf)) {
                return 3;
        }
        //crc bit??
        if(DS125BR401A_Write_Reg(addr, 0x5, 0x0)) {
                return 4;
        }
        //slave register control
        if(DS125BR401A_Write_Reg(addr, 0x6, 0x18)) {
                return 5;
        }
        //digital reset and control
        if(DS125BR401A_Write_Reg(addr, 0x7, 0x1)) {
                return 6;
        }
        //if(0x1 != DS125BR401A_Read_Reg(addr, 0x7)) {
                //return 0;
        //}
        //
        if(DS125BR401A_Write_Reg(addr, 0x8, 0x5c)) { //0x5c
                return 7;
        }
        //IDEL RXDET
        if(DS125BR401A_Write_Reg(addr, 0xe, 0xc)) {
                return 8;
        }
        if(DS125BR401A_Write_Reg(addr, 0x15, 0xc)) {
                return 9;
        }
        if(DS125BR401A_Write_Reg(addr, 0x1c, 0xc)) {
                return 10;
        }
        if(DS125BR401A_Write_Reg(addr, 0x23, 0xc)) {
                return 11;
        }
        if(DS125BR401A_Write_Reg(addr, 0x2b, 0x0)) {
                return 12;
        }
        if(DS125BR401A_Write_Reg(addr, 0x32, 0x0)) {
                return 13;
        }
        if(DS125BR401A_Write_Reg(addr, 0x39, 0x0)) {
                return 14;
        }
        if(DS125BR401A_Write_Reg(addr, 0x40, 0x0)) {
                return 15;
        }
        //EQ
        if(DS125BR401A_Write_Reg(addr, 0xf, 0x0)) { //2f
                return 16;
        }
        if(DS125BR401A_Write_Reg(addr, 0x16, 0x0)) {
                return 17;
        }
        if(DS125BR401A_Write_Reg(addr, 0x1d, 0x0)) {
                return 18;
        }
        if(DS125BR401A_Write_Reg(addr, 0x24, 0x0)) {
                return 19;
        }
        if(DS125BR401A_Write_Reg(addr, 0x2c, 0x3)) {
                return 20;
        }
        if(DS125BR401A_Write_Reg(addr, 0x33, 0x3)) {
                return 21;
        }
        if(DS125BR401A_Write_Reg(addr, 0x3a, 0x3)) {
                return 22;
        }
        if(DS125BR401A_Write_Reg(addr, 0x41, 0x3)) {
                return 23;
        }
        //VOD
        if(DS125BR401A_Write_Reg(addr, 0x10, 0xad)) { //af
                return 24;
        }
        if(DS125BR401A_Write_Reg(addr, 0x17, 0xad)) {
                return 25;
        }
        if(DS125BR401A_Write_Reg(addr, 0x1e, 0xad)) {
                return 26;
        }
        if(DS125BR401A_Write_Reg(addr, 0x25, 0xad)) {
                return 27;
        }
        if(DS125BR401A_Write_Reg(addr, 0x2d, 0xaf)) {
                return 28;
        }
        if(DS125BR401A_Write_Reg(addr, 0x34, 0xaf)) {
                return 29;
        }
        if(DS125BR401A_Write_Reg(addr, 0x3b, 0xaf)) {
                return 30;
        }
        if(DS125BR401A_Write_Reg(addr, 0x42, 0xaf)) {
                return 31;
        }
        //DEM
        if(DS125BR401A_Write_Reg(addr, 0x11, 0x0)) {
                return 32;
        }
        if(DS125BR401A_Write_Reg(addr, 0x18, 0x0)) {
                return 33;
        }
        if(DS125BR401A_Write_Reg(addr, 0x1f, 0x0)) {
                return 34;
        }
        if(DS125BR401A_Write_Reg(addr, 0x26, 0x0)) {
                return 35;
        }
        if(DS125BR401A_Write_Reg(addr, 0x2e, 0x0)) {
                return 36;
        }
        if(DS125BR401A_Write_Reg(addr, 0x35, 0x0)) {
                return 37;
        }
        if(DS125BR401A_Write_Reg(addr, 0x3c, 0x0)) {
                return 38;
        }
        if(DS125BR401A_Write_Reg(addr, 0x43, 0x0)) {
                return 39;
        }
        //SD Threshold
        if(DS125BR401A_Write_Reg(addr, 0x12, 0x5)) {
                return 40;
        }
        if(DS125BR401A_Write_Reg(addr, 0x19, 0x5)) {
                return 41;
        }
        if(DS125BR401A_Write_Reg(addr, 0x20, 0x5)) {
                return 42;
        }
        if(DS125BR401A_Write_Reg(addr, 0x27, 0x5)) {
                return 43;
        }
        if(DS125BR401A_Write_Reg(addr, 0x2f, 0x5)) {
                return 44;
        }
        if(DS125BR401A_Write_Reg(addr, 0x36, 0x5)) {
                return 45;
        }
        if(DS125BR401A_Write_Reg(addr, 0x3d, 0x5)) {
                return 46;
        }
        if(DS125BR401A_Write_Reg(addr, 0x44, 0x5)) {
                return 47;
        }
       
        return 0;
}

使用特权

评论回复
板凳
gujiamao12345|  楼主 | 2017-9-13 10:12 | 只看该作者
先实现最底层的IIC的读写,再实现芯片级的寄存器读写,最后实现所有的寄存器读写;

使用特权

评论回复
地板
修一明| | 2017-9-13 10:36 | 只看该作者
cool  感谢分享

使用特权

评论回复
5
mmuuss586| | 2017-9-13 19:46 | 只看该作者

谢谢分享;

使用特权

评论回复
6
10299823| | 2017-9-13 22:48 | 只看该作者
处理器不是自己选的吗?

使用特权

评论回复
7
10299823| | 2017-9-13 22:52 | 只看该作者
可能是方便日后升级其他的外设。

使用特权

评论回复
8
gujiamao12345|  楼主 | 2017-9-14 09:35 | 只看该作者
10299823 发表于 2017-9-13 22:48
处理器不是自己选的吗?

可以自己选,只是没用过F4,想尝试下而已,哈哈哈!
至于成本,板子上xilinx的v7赶得上上百片F4,就无所谓啦!

使用特权

评论回复
9
山东电子小菜鸟| | 2017-9-14 13:11 | 只看该作者
学习下

使用特权

评论回复
10
lihui567| | 2017-9-15 12:31 | 只看该作者
能否分享一下IIC的通讯

使用特权

评论回复
11
gujiamao12345|  楼主 | 2017-9-18 09:13 | 只看该作者
lihui567 发表于 2017-9-15 12:31
能否分享一下IIC的通讯

iic相关的代码都贴了。
从初始化到底层到应用层code。

使用特权

评论回复
12
lihui567| | 2017-9-19 23:23 | 只看该作者
我说的主要IIC通讯的原理

使用特权

评论回复
13
韬铸88| | 2018-8-30 20:46 | 只看该作者
看一下,或许会用得着

使用特权

评论回复
14
xqiang89| | 2018-11-12 12:47 | 只看该作者
感谢分享!!!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

48

主题

2442

帖子

12

粉丝