Search

2015年6月4日 星期四

HDC1000 Breakout

    HDC1000轉接版實驗用,STM32 PB15連接HDC1000 DRDYn開外部中斷等接收資料即可,轉換公式看Datasheet,下面是STM32 Example,話說STM32的Hardware IIC真的很鳥...


壹圓下面那個

example:

#include "stm32f10x.h"
#include "stdio.h"

#define HDC1000_ADDR  0x40 << 1

#define HDC1000_BOTH_TEMP_HUMI 0x10
#define HDC1000_TEMP_HUMI_14BIT 0x00
#define HDC1000_HEAT_ON 0x20

#define HDC1000_TEMP  0X00
#define HDC1000_HUMI  0X01
#define HDC1000_CONFIG 0x02

#define true 1
#define false 0

uint8_t HDC1000_SYNC = true;

uint8_t HDC1000_FLAG = HDC1000_TEMP;

double temperature = 0,humidity = 0;

volatile uint32_t delay = 0;

void Delay(volatile uint32_t n)
{
   delay = n;
   while(delay != 0);
}

void Init_I2C() {
   I2C_InitTypeDef I2C_InitStructure;
   GPIO_InitTypeDef GPIO_InitStructure;

   I2C_Cmd(I2C1,ENABLE);

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
   GPIO_Init(GPIOB, &GPIO_InitStructure);  

   I2C_InitStructure.I2C_Mode = I2C_Mode_SMBusHost;
   I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
   I2C_InitStructure.I2C_OwnAddress1 = 0x00;
   I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
   I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
   I2C_InitStructure.I2C_ClockSpeed = 100000 ;
   I2C_Init(I2C1, &I2C_InitStructure);
}

void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction){
    while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));

    I2C_GenerateSTART(I2Cx, ENABLE);

    while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));

    I2C_Send7bitAddress(I2Cx, address, direction);

    if(direction == I2C_Direction_Transmitter){
        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
    } else if(direction == I2C_Direction_Receiver){
        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
    }
}

void I2C_write(I2C_TypeDef* I2Cx, uint8_t data)
{
    I2C_SendData(I2Cx, data);
    while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}

uint8_t I2C_read_ack(I2C_TypeDef* I2Cx){
    uint8_t data;
    I2C_AcknowledgeConfig(I2Cx, ENABLE);
    while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) );
    data = I2C_ReceiveData(I2Cx);
    return data;
}

uint8_t I2C_read_nack(I2C_TypeDef* I2Cx){
    uint8_t data;
    I2C_AcknowledgeConfig(I2Cx, DISABLE);
    I2C_GenerateSTOP(I2Cx, ENABLE);
    while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) );
    data = I2C_ReceiveData(I2Cx);
    return data;
}

void I2C_stop(I2C_TypeDef* I2Cx){
    I2C_GenerateSTOP(I2Cx, ENABLE);
}

void Init_BT(void){
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef interrup;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_Init(USART2, &USART_InitStructure);

    USART_Cmd(USART2, ENABLE);
}

void BT_Send_String(volatile char *string)
{
   while(*string){
      USART_SendData(USART2,*string);
      ++string;
      while(USART_GetFlagStatus(USART2,USART_FLAG_TC) == RESET){}
   }
}

void HDC1000Start()
{
   uint8_t config = HDC1000_BOTH_TEMP_HUMI | HDC1000_TEMP_HUMI_14BIT | HDC1000_HEAT_ON;

    I2C_start(I2C1, HDC1000_ADDR, I2C_Direction_Transmitter);
    I2C_write(I2C1, HDC1000_CONFIG);
    I2C_write(I2C1, config);
    I2C_write(I2C1, 0x00);
    I2C_stop(I2C1);
    Delay(20);
}

void HDC1000DataRequest(uint8_t reg)
{
   if((HDC1000_FLAG == reg) && HDC1000_SYNC){
      HDC1000_SYNC = false;
      I2C_start(I2C1, HDC1000_ADDR, I2C_Direction_Transmitter);
      I2C_write(I2C1, reg);
      I2C_stop(I2C1);
   }
   else if((HDC1000_FLAG == reg) && HDC1000_SYNC){
      HDC1000_SYNC = false;
      I2C_start(I2C1, HDC1000_ADDR, I2C_Direction_Transmitter);
      I2C_write(I2C1, reg);
      I2C_stop(I2C1);
   }
}

double HDC1000GetTemp()
{
    double temp = 0;

    I2C_start(I2C1, HDC1000_ADDR, I2C_Direction_Receiver);

    temp = I2C_read_ack(I2C1) << 8;
    temp += I2C_read_nack(I2C1);

    return temp / 65536.0 * 165.0 - 40.0;

}

double HDC1000GetHumi()
{
    double humi = 0;

    I2C_start(I2C1, HDC1000_ADDR, I2C_Direction_Receiver);

    humi = I2C_read_ack(I2C1) << 8;
    humi += I2C_read_nack(I2C1);

    return humi / 65536.0 * 100.0;

}

void HDC1000EXTI15()
{
   GPIO_InitTypeDef GPIO_InitStructure;
   NVIC_InitTypeDef NVIC_InitStructure;
   EXTI_InitTypeDef EXTI_InitStructure;

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);

   GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_15;
   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

   GPIO_Init(GPIOB, &GPIO_InitStructure);

   GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource15);

   EXTI_InitStructure.EXTI_Line = EXTI_Line15;
   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
   EXTI_InitStructure.EXTI_LineCmd = ENABLE;
   EXTI_Init(&EXTI_InitStructure);

   NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);
}

int main(){
    Init_I2C();
    Init_BT();

    SystemInit();
    if(SysTick_Config(SystemCoreClock / 1000)){
       while(1);
    }

    HDC1000Start();
    HDC1000EXTI15();

    while(true){
       if(HDC1000_FLAG == HDC1000_TEMP){
 HDC1000DataRequest(HDC1000_TEMP);
       }
       else if(HDC1000_FLAG == HDC1000_HUMI){
 HDC1000DataRequest(HDC1000_HUMI);
       }
    }
}

void SysTick_Handler(void)
{
   if(delay != 0){
      delay--;
   }
}

void EXTI15_10_IRQHandler(void) {
   if(EXTI_GetITStatus(EXTI_Line15) != RESET) {
      if(HDC1000_FLAG == HDC1000_TEMP){
HDC1000_FLAG = HDC1000_HUMI;
temperature = HDC1000GetTemp();
      }
      else if(HDC1000_FLAG == HDC1000_HUMI){
HDC1000_FLAG = HDC1000_TEMP;
humidity = HDC1000GetHumi();
      }

      char str[256];
      sprintf(str, "temperature:%.2f humidity:%.2f%%\n",temperature,humidity);
      BT_Send_String(str);

      HDC1000_SYNC = true;
   }
   EXTI_ClearITPendingBit(EXTI_Line15);
}


 Download: