LPC1778与AM2302的通信

2019-04-15 16:46发布

typedef enum {INPUT, OUTPUT}PortDir;
typedef struct
{
    uint8 humiInt;
 uint8 humiFra;
 int8 tempInt;
 uint8 tempFra;
 uint8 checkSum;
} AM2302Data;/*********************************************************************************************************** function Name: BSP_AM2302_HW_INIT(void)
**  hard ware initial
*********************************************************************************************************/
void BSP_AM2302_HW_INIT(void)
{


PINSEL_ConfigPin (3, 7, 0); //P3.7

GPIO_SetDir(3, (1<<7), GPIO_DIRECTION_OUTPUT);


}


void BSP_AM2302_SetPinDir(PortDir dir)
{
    if(dir == INPUT)
    GPIO_SetDir(3, (1<<7), GPIO_DIRECTION_INPUT);
  else
 GPIO_SetDir(3, (1<<7), GPIO_DIRECTION_OUTPUT);
}
/*********************************************************************************************************
** function Name: BSP_AM2302_SetPinValue(uint8 val)
** parameter[in]: val; the value of it is LOW or HIGH
** return: none
*********************************************************************************************************/


void BSP_AM2302_SetPinValue(uint8 val)
{
 GPIO_OutputValue(3, (1 << 7),(uint8)val);
}
/*********************************************************************************************************
** function Name: BSP_AM2302_ReadPinLever(void)
** parameter: none
**return: the lever of p3.7(HIGH or LOW)
*********************************************************************************************************/

uint8 BSP_AM2302_ReadPinLever()
{
 uint32 tmp;
  
 tmp = GPIO_ReadValue(3);


 if(tmp&0x80)
return HIGH;
else
return LOW;
 
}
void TIM_Waitus1(uint32 time)
{
 TIM_TIMERCFG_Type TIM_ConfigStruct;
 TIM_MATCHCFG_Type MatchConfigStruct;

 TIM_ConfigStruct.PrescaleOption = TIM_PRESCALE_USVAL;
 TIM_ConfigStruct.PrescaleValue = 1; //Init timer 0, prescale count time of 1000uS

 //LPC_TIM2->IR = 0xFFFFFFFF; //clear Interupt

 MatchConfigStruct.MatchChannel = 0;
 MatchConfigStruct.IntOnMatch = ENABLE;
 MatchConfigStruct.ResetOnMatch = ENABLE;
 MatchConfigStruct.StopOnMatch = ENABLE;
 MatchConfigStruct.ExtMatchOutputType = 0;
 MatchConfigStruct.MatchValue = time;
    
 TIM_Init(LPC_TIM2, TIM_TIMER_MODE, &TIM_ConfigStruct); // Set configuration for Tim_config 
 TIM_ConfigMatch(LPC_TIM2, &MatchConfigStruct);
 TIM_Cmd(LPC_TIM2,ENABLE);
 //wait until interrupt flag occur
 while(!(LPC_TIM2->IR & 0x01));
 TIM_ResetCounter(LPC_TIM2);
}

uint8 BSP_AM2302_ReadByte()
{
    uint8 tmp = 0, i;

        for(i = 0; i < 8; i++)
{
//every bit start with LOW lever for 50us; here we wait for this end
   while( LOW == BSP_AM2302_ReadPinLever());
 
//then real bit value begin; The HIGH lever lasting 68~75us represents 1, 
//while lasting 22~30us represents 0.
TIM_Waitus1(50);

if( HIGH == BSP_AM2302_ReadPinLever())
{        //if it was still HIGH lever after 50us, then 1 is reserved; 
      //otherwise, 0 is reserved.

  //wait for the end of the transmission
    while( HIGH == BSP_AM2302_ReadPinLever());
  
  tmp |= (uint8)(1<<(7-i));
}
else
   tmp &= (uint8)~(1<<(7-i));
}
 
 return tmp;
}
/*********************************************************************************************************
** Function Name: BSP_AM2302_ReadPinLever(void)
**  paramater: dataOut is the output parameter containning the expectation data
**  return: 0£orepresent right
**         -1: represent crc error
**         -2: No response from AM2302
*********************************************************************************************************/


int8 BSP_AM2302_ReadData(AM2302Data* dataOut)
{
 int8 ret =0;
 int16 tmp = 0;
/*request data*/
         BSP_AM2302_SetPinDir(OUTPUT);

 BSP_AM2302_SetPinValue(LOW);

 TIM_Waitus1( 2000); // delay 2ms
 
 BSP_AM2302_SetPinValue(HIGH);
  
         TIM_Waitus1( 30); // delay 30us

 BSP_AM2302_SetPinDir(INPUT);

 /*discover the response from slave*/
 if( LOW == BSP_AM2302_ReadPinLever())
{
   /*wait for the end of the response from slave,*/ 
 
 //it may last 80us
 while(LOW == BSP_AM2302_ReadPinLever());
 //it may takes 80us
 while(HIGH == BSP_AM2302_ReadPinLever());

 /*begin to receive data*/
 dataOut->humiInt  = BSP_AM2302_ReadByte();
 dataOut->humiFra  = BSP_AM2302_ReadByte();
 dataOut->tempInt  = BSP_AM2302_ReadByte();
 dataOut->tempFra  = BSP_AM2302_ReadByte();
 dataOut->checkSum = BSP_AM2302_ReadByte();

 if(dataOut->checkSum != (uint8)(dataOut->humiInt+dataOut->humiFra+  (uint8)dataOut->tempInt+dataOut->tempFra))  ret = -1;
}
else
ret = -2;

BSP_AM2302_SetPinDir(OUTPUT);
BSP_AM2302_SetPinValue(HIGH);

/*dataOut convert*/
if(ret == 0)
{
   tmp = (dataOut->humiInt&0xf)*256 + (dataOut->humiFra>>4)*16+(dataOut->humiFra&0xf);
 dataOut->humiInt = tmp/10;
 dataOut->humiFra = tmp%10;

 tmp = (dataOut->tempInt&0xf)*256 + (dataOut->tempFra>>4)*16+(dataOut->tempFra&0xf);
 //if the high bit is 1, then the temperature is negative
 dataOut->tempInt = dataOut->tempInt&0x80? -(tmp/10) : (tmp/10);
 dataOut->tempFra = tmp%10;
}
else
{
          dataOut->humiInt  = 0;
 dataOut->humiFra  = 0;
 dataOut->tempInt  = 0;
 dataOut->tempFra  = 0;
 dataOut->checkSum = 0;
}
return ret;
}