Chinaunix首页 | 论坛 | 博客
  • 博客访问: 810806
  • 博文数量: 281
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2770
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-02 19:45
个人简介

邮箱:zhuimengcanyang@163.com 痴爱嵌入式技术的蜗牛

文章分类
文章存档

2020年(1)

2018年(1)

2017年(56)

2016年(72)

2015年(151)

分类: 嵌入式

2016-11-30 09:42:41

利用STM32的硬件平台实现的IIC模拟通信,这里实现了两路IIC接口,可以选择。

bsp_iic.c

点击(此处)折叠或打开

  1. #include "bsp_iic.h"
  2.  
  3.  
  4. static void IIC_Init(E_I2cChn e_i2cChn)
  5. {            
  6.     uint16_t u16SDAPin, u16SCLPin;
  7.     GPIO_InitTypeDef GPIO_InitStructure;    
  8.     RCC_APB2PeriphClockCmd(    RCC_APB2Periph_GPIOB, ENABLE );        
  9.     
  10.     if( e_i2cChn_RhTemp == e_i2cChn)
  11.     {
  12.         u16SDAPin = GPIO_Pin_7;
  13.         u16SCLPin = GPIO_Pin_6;
  14.     }

  15.     else
  16.     {
  17.         u16SDAPin = GPIO_Pin_11;
  18.         u16SCLPin = GPIO_Pin_10;    
  19.     }
  20.     
  21.     GPIO_InitStructure.GPIO_Pin = u16SDAPin | u16SCLPin;
  22.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;
  23.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  24.     GPIO_Init(GPIOB, &GPIO_InitStructure);
  25.  
  26.     IIC_SCL(e_i2cChn, 1);
  27.     IIC_SDA(e_i2cChn, 1);
  28. }


  29. static void IIC_Start(E_I2cChn e_i2cChn)
  30. {
  31.     SDA_OUT(e_i2cChn);
  32.     IIC_SDA(e_i2cChn, 1);         
  33.     IIC_SCL(e_i2cChn, 1);

  34.     delay_us(4);
  35.      IIC_SDA(e_i2cChn, 0); //START:when CLK is high,DATA change form high to low
  36.      
  37.     delay_us(4);
  38.     IIC_SCL(e_i2cChn, 0);
  39. }    


  40. static void IIC_Stop(E_I2cChn e_i2cChn)
  41. {
  42.     SDA_OUT(e_i2cChn);
  43.     IIC_SCL(e_i2cChn, 0);
  44.     IIC_SDA(e_i2cChn, 0);//STOP:when CLK is high DATA change form low to high
  45.     
  46.      delay_us(4);
  47.     IIC_SCL(e_i2cChn, 1);
  48.     IIC_SDA(e_i2cChn, 1);
  49.     
  50.     delay_us(4);                                 
  51. }


  52. // 等待应答信号到来 等待应答信号到来
  53. // 返回值: 0,接收应答失败
  54. // 1,接受应答成功
  55. static etError IIC_receivedAck(E_I2cChn e_i2cChn)
  56. {
  57.     uint8_t ucErrTime = 0;
  58.     SDA_IN(e_i2cChn);
  59.     IIC_SDA(e_i2cChn, 1);
  60.     delay_us(1);    
  61.     
  62.     IIC_SCL(e_i2cChn, 1);
  63.     delay_us(1);    
  64.     
  65.     while(READ_SDA(e_i2cChn))
  66.     {
  67.         ucErrTime++;
  68.         if(ucErrTime > 250)
  69.         {
  70.             IIC_Stop(e_i2cChn);
  71.             return ACK_ERROR;
  72.         }
  73.     }
  74.     IIC_SCL(e_i2cChn, 0);     
  75.     return NO_ERROR;
  76. }

  77. /* ACK: SDA low level */
  78. static void IIC_sendAck(E_I2cChn e_i2cChn)
  79. {
  80.     IIC_SCL(e_i2cChn, 0);
  81.     SDA_OUT(e_i2cChn);
  82.     
  83.     IIC_SDA(e_i2cChn, 0);
  84.     delay_us(2);
  85.     
  86.     IIC_SCL(e_i2cChn, 1);
  87.     delay_us(2);
  88.     
  89.     IIC_SCL(e_i2cChn, 0);
  90. }

  91. /* no ack: SDA high level */
  92. static void IIC_sendNAck(E_I2cChn e_i2cChn)
  93. {
  94.     IIC_SCL(e_i2cChn, 0);
  95.     SDA_OUT(e_i2cChn);
  96.     
  97.     IIC_SDA(e_i2cChn, 1);
  98.     delay_us(2);
  99.     
  100.     IIC_SCL(e_i2cChn, 1);
  101.     delay_us(2);
  102.     
  103.     IIC_SCL(e_i2cChn, 0);
  104. }                                     

  105.             
  106. static etError IIC_Send_Byte(E_I2cChn e_i2cChn, uint8_t u8SendByte)
  107. {
  108.     etError error;
  109.     uint8_t i;
  110.     SDA_OUT(e_i2cChn);     
  111.     IIC_SCL(e_i2cChn, 0); // scl = low level, to enable data transimit in IIC bus.

  112.     for(i = 0; i < 8; i ++)
  113.     {
  114.         /* send bits via IIC bus */
  115.         IIC_SDA(e_i2cChn, ((u8SendByte & 0x80) >> 7));
  116.         u8SendByte <<= 1;     
  117.         delay_us(2);

  118.         IIC_SCL(e_i2cChn, 1);
  119.         delay_us(2);
  120.         
  121.         IIC_SCL(e_i2cChn, 0);    
  122.         delay_us(2);
  123.     }    

  124.     
  125.     /**
  126.      * check whether received ACK from slave device after sending command to slave device.
  127.      * if received ACK, indicate NO_ERROR; else indicate error.
  128.      **/
  129.     if(IIC_receivedAck(e_i2cChn) == NO_ERROR)
  130.     {
  131.         error = NO_ERROR;
  132.     }
  133.     else
  134.         error = ACK_ERROR;

  135.     return error;
  136. }     



  137. /**
  138. * etAck: ack signal.
  139. */
  140. static uint8_t IIC_Read_Byte(E_I2cChn e_i2cChn, etI2cAck etAck)
  141. {
  142.     uint8_t i = 0, receive = 0;
  143.     
  144.     SDA_IN(e_i2cChn);
  145.     for(i = 0; i < 8; i++)
  146.     {
  147.         IIC_SCL(e_i2cChn, 0);
  148.         delay_us(2);
  149.         
  150.         IIC_SCL(e_i2cChn, 1);
  151.         receive <<= 1;
  152.         
  153.         if(READ_SDA(e_i2cChn))
  154.             receive++;
  155.         delay_us(2);
  156.     }                

  157.     /**
  158.      * master read one byte from slave device, then send ACK/nACK signal to slave device
  159.      * to enable continously sending command to slave(sending ACK) or stop commuincation(sending nACK).
  160.      */
  161.     if (etAck == ACK)
  162.         IIC_sendAck(e_i2cChn);
  163.     else
  164.         IIC_sendNAck(e_i2cChn);
  165.     return receive;
  166. }


  167. const T_IICOpera g_tIICOpera = {

  168.     IIC_Init,
  169.     
  170.     IIC_Start,
  171.     IIC_Stop,

  172.     /* master send/read byte to/from slave */
  173.     IIC_Send_Byte,
  174.     IIC_Read_Byte,
  175. };
bsp_iic.h

点击(此处)折叠或打开

  1. #ifndef _BSP_IIC_H
  2. #define _BSP_IIC_H

  3. #include "bsp_SysConfig.h"


  4. typedef enum E_I2cChn{

  5.     e_i2cChn_RhTemp = 0,
  6.     e_i2cChn_Pressure = 1,
  7. }E_I2cChn;


  8. // I2C acknowledge
  9. typedef enum{
  10.     ACK = 0,
  11.     NACK = 1,
  12. }etI2cAck;


  13. #if 1
  14. static __INLINE void SDA_IN(E_I2cChn eIICChn)
  15. {
  16.     if(eIICChn == e_i2cChn_RhTemp)
  17.     {
  18.         GPIOB->CRL &=~ (((uint32_t)0x0f) << 28);
  19.         GPIOB->CRL |= ((uint32_t)8) << 28;
  20.     }
  21.     else
  22.     {
  23.         GPIOB->CRH &=~ (((uint32_t)0x0f) << 12);
  24.         GPIOB->CRH |= ((uint32_t)8) << 12;    
  25.     }
  26. }


  27. static __INLINE void SDA_OUT(E_I2cChn eIICChn)
  28. {
  29.     if(eIICChn == e_i2cChn_RhTemp){
  30.         GPIOB->CRL &=~ (((uint32_t)0x0f) << 28);
  31.         GPIOB->CRL |= ((uint32_t)3) << 28;    
  32.     }                                
  33.     else                            
  34.     {                                
  35.         GPIOB->CRH &=~ (((uint32_t)0x0f) << 12);
  36.         GPIOB->CRH |= ((uint32_t)3) << 12;        
  37.     }        
  38. }


  39. static __INLINE void IIC_SCL(E_I2cChn eIICChn, uint8_t value)
  40. {
  41.     if(eIICChn == e_i2cChn_RhTemp)
  42.     {
  43.         PBout(6) = value;
  44.     }
  45.     else
  46.     {
  47.         PBout(10) = value;
  48.     }     
  49. }


  50. static __INLINE void IIC_SDA(E_I2cChn eIICChn, uint8_t value)
  51. {
  52.     if(eIICChn == e_i2cChn_RhTemp)    
  53.     {                                
  54.         PBout(7)= value;
  55.     }                                
  56.     else                            
  57.     {                                
  58.         PBout(11) = value;    
  59.     }                                
  60. }

  61. static __INLINE uint8_t READ_SDA(E_I2cChn e_i2cChn)
  62. {
  63.     volatile uint8_t u8SDAbit;
  64.     if(e_i2cChn == e_i2cChn_RhTemp)
  65.     {
  66.         u8SDAbit = PBin(7);
  67.     }
  68.     else
  69.     {
  70.         u8SDAbit = PBin(11);
  71.     }
  72.     return u8SDAbit;
  73. }

  74. #else
  75. // IO方向设置
  76. //
  77. #define SDA_IN() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}
  78. #define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}

  79. //IO操作函数    
  80. #define IIC_SCL PCout(12) //SCL
  81. #define IIC_SDA PCout(11) //SDA    
  82. #define READ_SDA PCin(11) //输入SDA

  83. #endif


  84. static __INLINE void delay_us(uint16_t t)
  85. {
  86.     uint16_t x, y;
  87.     for(x = t; x >0; x --)
  88.         for(y = 650; y >0 ; y--);
  89. }



  90. typedef struct T_IICOpera{

  91.     void (*init)(E_I2cChn e_i2cChn);
  92.     
  93.     void (*start)(E_I2cChn e_i2cChn);
  94.     void (*stop)(E_I2cChn e_i2cChn);
  95.     
  96.     etError (*sendByte)(E_I2cChn e_i2cChn, uint8_t u8Byte);
  97.     uint8_t (*readByte)(E_I2cChn e_i2cChn, etI2cAck etAck);

  98. }T_IICOpera;



  99. extern const T_IICOpera g_tIICOpera;



  100. #endif /* _BSP_IIC_H */


阅读(2644) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~