第五篇 STM32L051硬件I2C主机测试

2019-07-20 22:45发布

一、准备工程,随意建立一个
二、新建对应的文件,我只建立了hal_i2c.c和hal_i2c.h
三、编写初始化I2C主机代码
  1. /**
  2.   *****************************************************************************
  3.   * [url=home.php?mod=space&uid=67211]@name[/url]   : I2C Master接口初始化
  4.   *
  5.   * @Brief  : 硬件I2C方式
  6.   *
  7.   * @Input  : none
  8.   *
  9.   * @Output : none
  10.   *
  11.   * @Return : none
  12.   *****************************************************************************
  13. **/
  14. void HAL_I2CHardMasterInit(void)
  15. {
  16.         uint32_t i2c_temp = 0;
  17.        
  18.         //I2C时钟源选择
  19.         RCC->CCIPR &= ~RCC_CCIPR_I2C1SEL;
  20.         RCC->CCIPR |= RCC_CCIPR_I2C1SEL_0;  //System clock selected as I2C1 clock
  21.        
  22.         RCC->IOPENR |= RCC_IOPENR_GPIOBEN;
  23.         RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
  24.        
  25.         //
  26.         //管脚复用
  27.         //
  28.         GPIOB->AFR[0] &= ~(GPIO_AFRL_AFSEL6 | GPIO_AFRL_AFSEL7);
  29.         GPIOB->AFR[0] |= 0x01<<(4 * 6);
  30.         GPIOB->AFR[0] |= 0x01<<(4 * 7);
  31.        
  32.         //
  33.         //初始化管脚
  34.         //
  35.         GPIOB->MODER   &= ~(GPIO_MODER_MODE6 | GPIO_MODER_MODE7);
  36.         GPIOB->OTYPER  &= ~(GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7);
  37.         GPIOB->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEED6 | GPIO_OSPEEDER_OSPEED7);
  38.         GPIOB->PUPDR   &= ~(GPIO_PUPDR_PUPD6 | GPIO_PUPDR_PUPD7);
  39.        
  40.         GPIOB->MODER   |= (GPIO_MODER_MODE6_1 | GPIO_MODER_MODE7_1);  //Alternate function mode
  41.         GPIOB->OTYPER  |= (GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7);
  42.         GPIOB->OSPEEDR |= (GPIO_OSPEEDER_OSPEED6 | GPIO_OSPEEDER_OSPEED7);
  43. //        GPIOB->PUPDR   |= (GPIO_PUPDR_PUPD6_0 | GPIO_PUPDR_PUPD7_0);
  44.        
  45.         //
  46.         //复位I2C设备
  47.         //
  48.         RCC->APB1RSTR |= RCC_APB1RSTR_I2C1RST;
  49.         RCC->APB1RSTR &= ~RCC_APB1RSTR_I2C1RST;
  50.        
  51.         //
  52.         //初始化IIC寄存器
  53.         //
  54.         I2C_DEVICE->CR1 &= ~I2C_CR1_PE;  /*!< Disable I2C */
  55.         I2C_DEVICE->CR1 &= 0x00CFE0FF;
  56.        
  57.         /*!< 时钟延展功能 */
  58.         #if HAL_I2C_NOSTRETCH_EN
  59.         I2C_DEVICE->CR1 &= ~I2C_CR1_NOSTRETCH;  /*!< Enable Nostretch */
  60.         #else
  61.         I2C_DEVICE->CR1 |= I2C_CR1_NOSTRETCH;  /*!< Disable Nostretch */
  62.         #endif
  63.        
  64.         I2C_DEVICE->TIMINGR = I2C_TIMING;  /*!< Timing register */
  65.         I2C_DEVICE->CR1 |= I2C_CR1_PE;  /*!< Enable I2C */
  66.        
  67.         i2c_temp = 0;
  68.         I2C_DEVICE->OAR1 = i2c_temp;
  69.         i2c_temp = (uint32_t)(I2C_ADDRESS & 0x00FF);
  70.         I2C_DEVICE->OAR1 |= i2c_temp;  /*!< Slave Address */
  71.         I2C_DEVICE->OAR1 |= I2C_OAR1_OA1EN;  /*!< Own Address1 enable */
  72.        
  73.         I2C_DEVICE->CR2 &= 0x07FF7FFF;
  74.         I2C_DEVICE->CR2 &= ~I2C_CR2_NACK;  /*!< ACK enable */
  75. }
复制代码master的初始化和slave初始化差不多,具体大伙们可以对比前面帖子
四、本例子提供如下函数
      读取一个字节:HAL_I2CMasterHardReadData()
      读取多个字节:HAL_I2CMasterHardReadMultiData()
      写入一个字节:HAL_I2CMasterHardWriteData()
      写入多个字节:HAL_I2CMasterHardWriteMultiData()
五、操作函数中,设备地址大于10bits的没有测试,还不知道行不行,寄存器地址大于0xFF的,已经测试,目前可用
六、目前测试SCL时钟频率有100K和400K
七、对应测试的slave使用的是前面帖子的例子,稍作修改
  1. /**
  2.   *****************************************************************************
  3.   * @Name   : 事件中断服务函数
  4.   *
  5.   * @Brief  : none
  6.   *
  7.   * @Input  : none
  8.   *
  9.   * @Output : none
  10.   *
  11.   * @Return : none
  12.   *****************************************************************************
  13. **/
  14. I2C_DEVICE_EVENT_IRQ
  15. {
  16.         u32 temp = 0;
  17.         GPIOB->BSRR = GPIO_BSRR_BR_8;
  18.         /*!< Read Event Flag */
  19.         temp = I2C_DEVICE->ISR;
  20.         i2c_dev.I2C_EventStatus = (uint32_t)(temp & I2C_STATUS_EVT_MASK);
  21.         i2c_dev.I2C_ErrorStatus = (uint32_t)(temp & I2C_STATUS_ERR_MASK);
  22.        
  23.         /* ==================================================== */
  24.         /*                    地址适配中断                       */
  25.         /* ==================================================== */
  26.         if ((i2c_dev.I2C_EventStatus & I2C_ISR_ADDR) != 0)
  27.         {
  28.                 /*!< ************************************ */
  29.                 /*!<          Enable Nostretch            */
  30.                 /*!< ************************************ */
  31.                 #if I2C_NOSTRETCH_EN
  32.                 {
  33.                         if ((I2C_DEVICE->ISR & I2C_ISR_DIR) != 0)  /*!< Slave enter transmitter mode, Host read data */
  34.                         {
  35.                                 I2C_DEVICE->ISR |= I2C_ISR_TXE;  /*!< set TXE bit */
  36.                                 i2c_dev.I2C_DeviceFlag |= I2C_DEVICE_FLAG_DIR_SEND;
  37.                         }
  38.                         else  /*!< Host write data (slave receive data from host) */
  39.                         {
  40.                                 i2c_dev.I2C_DeviceFlag &= ~I2C_DEVICE_FLAG_DIR_SEND;
  41.                         }
  42.                 }
  43.                 /*!< ************************************ */
  44.                 /*!<          Disable Nostretch           */
  45.                 /*!< ************************************ */
  46.                 #else
  47.                 {
  48.                         if ((I2C_DEVICE->ISR & I2C_ISR_DIR) != 0)  /*!< Slave enter transmitter mode, Host read data */
  49.                         {
  50.                                 i2c_dev.I2C_DeviceFlag |= I2C_DEVICE_FLAG_DIR_SEND;
  51.                                 I2C_DEVICE->ISR |= I2C_ISR_TXE;  /*!< set TXE bit, I2C_TXDR empty */
  52.                                 //
  53.                                 //根据不同寄存器地址来填充data1
  54.                                 //
  55.                                 if (I2C_DEVICE_REGADDRESS == I2C_REG_TEST_ADD)
  56.                                 {
  57.                                         if (I2C_DEVICE_REGOFFSET < I2C_REG_TEST_SIZE)
  58.                                         {
  59.                                                 I2C_DEVICE->TXDR = I2C_REG_TEST[I2C_DEVICE_REGOFFSET];
  60.                                                 I2C_DEVICE_REGOFFSET++;
  61.                                         }
  62.                                         else
  63.                                         {
  64.                                                 I2C_DEVICE->TXDR = I2C_DEVICE_DR_NULL_S;
  65.                                         }
  66.                                 }
  67.                                 else
  68.                                 {
  69.                                         I2C_DEVICE->TXDR = I2C_DEVICE_DR_NULL_R;
  70.                                 }
  71.                         }
  72.                         else  //Receiver mode
  73.                         {
  74.                                 i2c_dev.I2C_DeviceFlag &= ~I2C_DEVICE_FLAG_DIR_SEND;
  75.                         }
  76.                 }
  77.                 #endif
  78. //                I2C_ClearITPendingBit(I2C1, I2C_IT_ADDR);  /*!< set ADDRCF */
  79.                 I2C_DEVICE->ICR = I2C_IT_ADDR;  /*!< set ADDRCF */
  80.         }
  81.        
  82.         /* ==================================================== */
  83.         /*                   从机发送数据中断                    */
  84.         /* ==================================================== */
  85.         if ((i2c_dev.I2C_EventStatus & I2C_ISR_TXIS) != 0)
  86.         {
  87.                 //
  88.                 //根据不同的寄存器地址来发送数据,主机读取数据
  89.                 //
  90. //                printf ("Evt=%x ", i2c_dev.I2C_EventStatus);
  91.                 //
  92.                 //测试寄存器
  93.                 //
  94.                 if (I2C_DEVICE_REGADDRESS == I2C_REG_TEST_ADD)  //read and write
  95.                 {
  96.                         if (I2C_DEVICE_REGOFFSET < I2C_REG_TEST_SIZE)
  97.                         {
  98.                                 i2c_regtemp = I2C_REG_TEST[I2C_DEVICE_REGOFFSET];
  99.                                 I2C_DEVICE_REGOFFSET++;
  100.                         }
  101.                         else
  102.                         {
  103.                                 I2C_DEVICE_REGOFFSET = 0;
  104.                                 i2c_regtemp = I2C_DEVICE_DR_NULL_S;
  105.                         }
  106.                 }
  107.                 else
  108.                 {
  109.                         i2c_regtemp = I2C_DEVICE_DR_NULL_R;
  110.                 }
  111.                
  112.                 I2C_DEVICE->TXDR = i2c_regtemp;
  113.                 printf ("data=%02X ", i2c_regtemp);
  114.         }
  115.        
  116.         /* ==================================================== */
  117.         /*                   从机接收数据中断                    */
  118.         /* ==================================================== */
  119.         if ((i2c_dev.I2C_EventStatus & I2C_ISR_RXNE) != 0)
  120.         {
  121.                 i2c_regtemp = I2C_DEVICE->RXDR;
  122.                
  123.                 #if 0
  124.                 if (I2C_DEVICE_REGOFFSET < I2C_REG_TEST_SIZE)
  125.                 {
  126.                         I2C_REG_TEST[I2C_DEVICE_REGOFFSET] = i2c_regtemp;
  127. //                        printf ("data=%02X ", I2C_REG_TEST[I2C_DEVICE_REGOFFSET]);
  128.                         I2C_DEVICE_REGOFFSET++;
  129.                 }
  130.                 else
  131.                 {
  132.                         I2C_DEVICE_REGOFFSET = 0;
  133.                 }
  134.                 #else
  135.                 if (I2CFirstByteFlag > 1)
  136.                 {
  137.                         //
  138.                         //根据不同的寄存器偏移量进行接收主机数据,主机写入数据
  139.                         //
  140. //                        i2c_regtemp = I2C_DEVICE->RXDR;
  141.                        
  142.                         //
  143.                         //测试寄存器
  144.                         //
  145.                         if (I2C_DEVICE_REGADDRESS == I2C_REG_TEST_ADD)  //read and write
  146.                         {
  147.                                 if (I2C_DEVICE_REGOFFSET < I2C_REG_TEST_SIZE)
  148.                                 {
  149.                                         I2C_REG_TEST[I2C_DEVICE_REGOFFSET] = i2c_regtemp;
  150. //                                        printf ("data=%02X ", I2C_REG_TEST[I2C_DEVICE_REGOFFSET]);
  151.                                         I2C_DEVICE_REGOFFSET++;
  152.                                 }
  153.                                 else
  154.                                 {
  155.                                         I2C_DEVICE_REGOFFSET = 0;
  156.                                 }
  157.                         }
  158.                        
  159.                         i2c_regtemp = 0;
  160.                 }
  161.                 else
  162.                 {
  163. //                        i2c_regtemp = I2C_DEVICE->RXDR;
  164.                         //
  165.                         //接收第一个地址字节,十六位寄存器地址,高8位类型,低8位偏移量
  166.                         //
  167.                         if (I2CFirstByteFlag == 0)
  168.                         {
  169.                                 I2C_DEVICE_REGADDRESS = i2c_regtemp & 0xFF;
  170.                                 I2CFirstByteFlag++;
  171.                                 printf ("reg=%02X ", I2C_DEVICE_REGADDRESS);
  172.                         }
  173.                         else if (I2CFirstByteFlag == 1)
  174.                         {
  175.                                 I2C_DEVICE_REGOFFSET  = i2c_regtemp & 0xFF;
  176.                                 I2CFirstByteFlag++;
  177.                                 printf ("off=%02X ", I2C_DEVICE_REGOFFSET);
  178.                         }
  179.                 }
  180.                 #endif
  181.         }
  182.        
  183.         /* ==================================================== */
  184.         /*                      非应答中断                       */
  185.         /* ==================================================== */
  186.         if ((i2c_dev.I2C_EventStatus & I2C_ISR_NACKF) != 0)
  187.         {
  188. //                I2C_ClearITPendingBit(I2C_DEVICE, I2C_IT_NACKF);
  189.                 I2C_DEVICE->ICR = I2C_IT_NACKF;
  190.                 if (I2CFirstByteFlag != 0)
  191.                 {
  192.                         I2CFirstByteFlag = 0;
  193.                 }
  194.                 i2c_dev.I2C_DeviceFlag |= I2C_DEVICE_FLAG_NACK;
  195.         }
  196.        
  197.         /* ==================================================== */
  198.         /*                     停止信号中断                      */
  199.         /* ==================================================== */
  200.         if ((i2c_dev.I2C_EventStatus & I2C_ISR_STOPF) != 0)
  201.         {
  202.                 if ((i2c_dev.I2C_DeviceFlag & I2C_DEVICE_FLAG_DIR_SEND) != 0)  /*!< Slave send to host */
  203.                 {
  204.                         /*!< ************************************ */
  205.                         /*!<          Enable Nostretch            */
  206.                         /*!< ************************************ */
  207.                         #if I2C_NOSTRETCH_EN
  208.                        
  209.                         /*!< ************************************ */
  210.                         /*!<          Disable Nostretch           */
  211.                         /*!< ************************************ */
  212.                         #else
  213.                         I2C1->ISR |= I2C_ISR_TXE;
  214.                         I2C1->ISR |= I2C_ISR_TXIS;
  215.                         #endif
  216.                         i2c_dev.I2C_DeviceFlag &= ~I2C_DEVICE_FLAG_DIR_SEND;
  217.                         i2c_dev.I2C_DeviceFlag |= I2C_DEVICE_FLAG_READ;
  218.                 }
  219.                 else
  220.                 {
  221.                         i2c_dev.I2C_DeviceFlag |= I2C_DEVICE_FLAG_WRITE;  //置操作标志
  222.                 }
  223.                 if (I2CFirstByteFlag != 0)
  224.                 {
  225.                         I2CFirstByteFlag = 0;
  226.                 }
  227. //                I2C_ClearITPendingBit(I2C_DEVICE, I2C_IT_STOPF);  /*!< set STOPCF */
  228.                 I2C_DEVICE->ICR = I2C_IT_STOPF;  /*!< set STOPCF */
  229.         }
  230.        
  231.        
  232.         /* ==================================================== */
  233.         /*                       错误中断                        */
  234.         /* ==================================================== */
  235.         //
  236.         //总线错误
  237.         //
  238.         if ((i2c_dev.I2C_ErrorStatus & I2C_ISR_BERR) != 0)
  239.         {
  240.                 I2C_DEVICE->ICR = I2C_ICR_BERRCF;
  241.                 i2c_dev.I2C_DeviceFlag |= I2C_DEVICE_FLAG_ERROR;
  242.         }
  243.         //
  244.         //总裁失败
  245.         //
  246.         if ((i2c_dev.I2C_ErrorStatus & I2C_ISR_ARLO) != 0)
  247.         {
  248.                 I2C_DEVICE->ICR = I2C_ICR_ARLOCF;
  249.                 i2c_dev.I2C_DeviceFlag |= I2C_DEVICE_FLAG_ERROR;
  250.         }
  251.         //
  252.         //溢出
  253.         //
  254.         if ((i2c_dev.I2C_ErrorStatus & I2C_ISR_OVR) != 0)
  255.         {
  256.                 I2C_DEVICE->ICR = I2C_ICR_OVRCF;
  257.                 i2c_dev.I2C_DeviceFlag |= I2C_DEVICE_FLAG_ERROR;
  258.         }
  259.        
  260.         GPIOB->BSRR = GPIO_BSRR_BS_8;
  261. }
复制代码     主要修改是寄存器地址大于0xFF的操作,模拟eeprom的操作,详情可参考AT24C128/256/512协议部分

0条回答

一周热门 更多>