시작하기
이번에는 nRF52832 내부에 있는 온도센서의 값을 읽어오는 temperature 예제에 대해서 알아보자.
\examples\peripheral\temperature\pca10040\blank\ses 폴더에서 프로젝트를 실행시킨다.
예제는 500ms 마다 온도를 측정해서 문자열로 출력해주는 간단한 구성이다.
저번 글에서 다뤘던 NRF_LOG_INFO 출력 설정을 해주고 main 함수를 살펴보도록 하자.
int main(void)
{
// This function contains workaround for PAN_028 rev2.0A anomalies 28, 29,30 and 31.
int32_t volatile temp;
nrf_temp_init();
APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
NRF_LOG_DEFAULT_BACKENDS_INIT();
NRF_LOG_INFO("Temperature example started.");
while (true)
{
NRF_TEMP->TASKS_START = 1; /** Start the temperature measurement. */
/* Busy wait while temperature measurement is not finished, you can skip waiting if you enable interrupt for DATARDY event and read the result in the interrupt. */
/*lint -e{845} // A zero has been given as right argument to operator '|'" */
while (NRF_TEMP->EVENTS_DATARDY == 0)
{
// Do nothing.
}
NRF_TEMP->EVENTS_DATARDY = 0;
/**@note Workaround for PAN_028 rev2.0A anomaly 29 - TEMP: Stop task clears the TEMP register. */
temp = (nrf_temp_read() / 4);
/**@note Workaround for PAN_028 rev2.0A anomaly 30 - TEMP: Temp module analog front end does not power down when DATARDY event occurs. */
NRF_TEMP->TASKS_STOP = 1; /** Stop the temperature measurement. */
NRF_LOG_INFO("Actual temperature: %d", (int)temp);
nrf_delay_ms(500);
NRF_LOG_FLUSH();
}
}
nrf_temp_init 함수를 호출해 내부 온도센서를 읽기 전용으로 설정해준다.
/**
* @brief Function for preparing the TEMP module for temperature measurement.
*
* This function initializes the TEMP module and writes to the hidden configuration register.
*/
static __INLINE void nrf_temp_init(void)
{
/**@note Workaround for PAN_028 rev2.0A anomaly 31 - TEMP: Temperature offset value has to be manually loaded to the TEMP module */
*(uint32_t *) 0x4000C504 = 0;
}
/**
* @brief Temperature Sensor (TEMP)
*/
typedef struct { /*!< (@ 0x4000C000) TEMP Structure */
__OM uint32_t TASKS_START; /*!< (@ 0x00000000) Start temperature measurement */
__OM uint32_t TASKS_STOP; /*!< (@ 0x00000004) Stop temperature measurement */
__IM uint32_t RESERVED[62];
__IOM uint32_t EVENTS_DATARDY; /*!< (@ 0x00000100) Temperature measurement complete, data ready */
__IM uint32_t RESERVED1[128];
__IOM uint32_t INTENSET; /*!< (@ 0x00000304) Enable interrupt */
__IOM uint32_t INTENCLR; /*!< (@ 0x00000308) Disable interrupt */
__IM uint32_t RESERVED2[127];
__IM int32_t TEMP; /*!< (@ 0x00000508) Temperature in degC (0.25deg steps) */
__IM uint32_t RESERVED3[5];
__IOM uint32_t A0; /*!< (@ 0x00000520) Slope of 1st piece wise linear function */
__IOM uint32_t A1; /*!< (@ 0x00000524) Slope of 2nd piece wise linear function */
__IOM uint32_t A2; /*!< (@ 0x00000528) Slope of 3rd piece wise linear function */
__IOM uint32_t A3; /*!< (@ 0x0000052C) Slope of 4th piece wise linear function */
__IOM uint32_t A4; /*!< (@ 0x00000530) Slope of 5th piece wise linear function */
__IOM uint32_t A5; /*!< (@ 0x00000534) Slope of 6th piece wise linear function */
__IM uint32_t RESERVED4[2];
__IOM uint32_t B0; /*!< (@ 0x00000540) y-intercept of 1st piece wise linear function */
__IOM uint32_t B1; /*!< (@ 0x00000544) y-intercept of 2nd piece wise linear function */
__IOM uint32_t B2; /*!< (@ 0x00000548) y-intercept of 3rd piece wise linear function */
__IOM uint32_t B3; /*!< (@ 0x0000054C) y-intercept of 4th piece wise linear function */
__IOM uint32_t B4; /*!< (@ 0x00000550) y-intercept of 5th piece wise linear function */
__IOM uint32_t B5; /*!< (@ 0x00000554) y-intercept of 6th piece wise linear function */
__IM uint32_t RESERVED5[2];
__IOM uint32_t T0; /*!< (@ 0x00000560) End point of 1st piece wise linear function */
__IOM uint32_t T1; /*!< (@ 0x00000564) End point of 2nd piece wise linear function */
__IOM uint32_t T2; /*!< (@ 0x00000568) End point of 3rd piece wise linear function */
__IOM uint32_t T3; /*!< (@ 0x0000056C) End point of 4th piece wise linear function */
__IOM uint32_t T4; /*!< (@ 0x00000570) End point of 5th piece wise linear function */
} NRF_TEMP_Type; /*!< Size = 1396 (0x574)
내부 온도센서 기본 레지스터 주소는 0x4000C000이며 온도 센서를 읽기 위해 NRF_TEMP->TASKS_START 값을 1로 설정해준다.
NRF_TEMP->EVENTS_DATARDY 레지스터로 온도 측정이 완료되었는지 확인한다.
내부 온도센서의 온도가 측정되었다면 해당 레지스터는 값이 1로 설정되어 있다.
nrf_temp_read 함수를 호출해 내부 온도센서의 값을 읽는다.
NRF_TEMP->TEMP 값에 MASK_SIGN(0x200)을 AND 연산하는데 읽어온 값이 양수라면 연산 결과는 0이 돼서 그대로 값을 전달해준다.
만약 음수일 경우 읽어온 값에 MASK_SIGN_EXTENSION을 OR 연산한 후 값을 전달해준다.
전달받은 값에 4를 나누어 주면 내부 온도센서에서 읽은 온도 값으로 변환된다.
마지막으로 NRF_TEMP->TASKS_STOP 값을 1로 설정해줌으로써 내부 온도센서 동작을 중지한다.
/**
* @brief Function for reading temperature measurement.
*
* The function reads the 10-bit 2's complement value and transforms it to a 32-bit 2's complement value.
*/
static __INLINE int32_t nrf_temp_read(void)
{
/**@note Workaround for PAN_028 rev2.0A anomaly 28 - TEMP: Negative measured values are not represented correctly */
return ((NRF_TEMP->TEMP & MASK_SIGN) != 0) ?
(int32_t)(NRF_TEMP->TEMP | MASK_SIGN_EXTENSION) : (NRF_TEMP->TEMP);
}
내부 온도센서는 0.25℃의 해상도를 가지고 있는데 예제에서는 소수점은 빼고 출력하고 있어 이 부분만 수정하면 다음과 같다.
int main(void)
{
// This function contains workaround for PAN_028 rev2.0A anomalies 28, 29,30 and 31.
float volatile temp;
nrf_temp_init();
APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
NRF_LOG_DEFAULT_BACKENDS_INIT();
NRF_LOG_INFO("Temperature example started.");
while (true)
{
NRF_TEMP->TASKS_START = 1; /** Start the temperature measurement. */
/* Busy wait while temperature measurement is not finished, you can skip waiting if you enable interrupt for DATARDY event and read the result in the interrupt. */
/*lint -e{845} // A zero has been given as right argument to operator '|'" */
while (NRF_TEMP->EVENTS_DATARDY == 0)
{
// Do nothing.
}
NRF_TEMP->EVENTS_DATARDY = 0;
/**@note Workaround for PAN_028 rev2.0A anomaly 29 - TEMP: Stop task clears the TEMP register. */
temp = (nrf_temp_read() / 4.0);
/**@note Workaround for PAN_028 rev2.0A anomaly 30 - TEMP: Temp module analog front end does not power down when DATARDY event occurs. */
NRF_TEMP->TASKS_STOP = 1; /** Stop the temperature measurement. */
NRF_LOG_INFO("Actual temperature: "NRF_LOG_FLOAT_MARKER"", NRF_LOG_FLOAT(temp));
nrf_delay_ms(500);
NRF_LOG_FLUSH();
}
}
앞으로
nRF52832 내부 온도센서를 읽어오는 예제를 통해 온도 값을 확인해보았다.
지금부터는 nRF52832 DK에 주변기기를 연결하여 센서와의 통신을 하는 예제에 대해서 알아보자.
'Embedded > nRF52 BLE 개발 안내서' 카테고리의 다른 글
nRF52 BLE 개발하기 - twi_sensor(I2C) (8) | 2021.01.22 |
---|---|
nRF52 BLE 개발하기 - twi_scanner(I2C) (0) | 2021.01.21 |
nRF52 BLE 개발하기 - NRF_LOG_INFO (0) | 2021.01.19 |
nRF52 BLE 개발하기 - wdt (0) | 2021.01.18 |
nRF52 BLE 개발하기 - rtc (8) | 2021.01.15 |
댓글