기술나눔

Renesas R7FA8D1BH(Cortex®-M85)는 DS18B20을 제어합니다.

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

목차

개요

1 소프트웨어 및 하드웨어

1.1 소프트웨어 및 하드웨어 환경 정보

1.2 개발 보드 정보

1.3 디버거 정보

2 FSP 및 KEIL 구성

2.1 하드웨어 인터페이스 회로

2.2 FSB는 DS18B20의 IO를 구성합니다.

2.3 Keil 프로젝트 파일 생성

3 DS18B20 드라이버 코드

3.1 DS18B20 소개

3.2 DS18B20 드라이버 구현

3.2.1 IO 상태 정의

3.2.2 IO 상태 읽기 기능

3.2.3 기타 기능

4 테스트 절차

4.1 애플리케이션 디자인

4.2 테스트

액세서리 5개


Renesas R7FA8D1BH(Cortex®-M85)는 DS18B20 및 ADC를 제어하여 두 페이지의 점프 기능을 달성합니다.

개요

이 기사에서는 주로 Renesas R7FA8D1BH(Cortex®-M85)용으로 설계된 포괄적인 응용 사례를 소개합니다. R7FA8D1BH의 IO를 적용하여 단일 버스 프로토콜을 구현하고 ds18b20을 구동하는 기능을 실현합니다. 주로 온도 값을 읽고 값을 형식화하는 작업을 완료합니다. 화면의 OLED에 표시됩니다. 온도 데이터도 직렬 포트 터미널을 통해 직렬 포트 터미널로 전송됩니다.

1 소프트웨어 및 하드웨어

1.1 소프트웨어 및 하드웨어 환경 정보

소프트웨어 및 하드웨어 정보버전 정보
르네사스 MCUR7FA8D1BH
케일ARM 5.38 버전
FSP 버전5.3.0
디버깅 도구: N32G45XVL-STBDAP-링크

1.2 개발 보드 정보

저자는 Wildfire Yaoyang 개발 보드_Renesas RA8을 사용하기로 결정했습니다. 이 보드의 주요 제어 MCU는 R7FA8D1BHECBD이고, 7FA8D1BHECBD의 핵심은 ARM Contex-M85입니다.

1.3 디버거 정보

R7FA8D1BHECBD 칩의 경우 사용되는 코어는 Cortex®-M85 Core, ST-LINK-V2 또는 J-LINK-V9는 다운로드 및 디버깅 기능을 지원하지 않습니다.여러번 시도한 끝에 저자는 그 사실을 깨달았다.N32G45XVL-STB보드와 함께 제공되는 DAP-LINK는 R7FA8D1BHECBD를 다운로드하고 디버깅할 수 있습니다.

아래 그림은 N32G45XVL-STB 개발 보드의 실제 사진입니다.

2 FSP 및 KEIL 구성

2.1 하드웨어 인터페이스 회로

DS18B20의 인터페이스 회로는 P809 인터페이스를 DS18B20의 DQ 제어 신호로 사용하는 Yaoyang Development Board_Renesas RA8에 설계되었습니다.

2.2 FSB는 DS18B20의 IO를 구성합니다.

P809를 공통 IO 인터페이스로 구성한 다음 코드에서 IO의 출력 또는 출력 상태를 동적으로 구성합니다.

2.3 Keil 프로젝트 파일 생성

FSP의 매개변수 구성을 완료한 후 프로젝트 생성을 할 수 있습니다. 프로젝트 파일을 열면 그 구조는 다음과 같습니다.

드라이버 코드를 구현하기 위해 ds18b20.c 파일을 생성합니다.

3 DS18B20 드라이버 코드

3.1 DS18B20 소개

저자는 이미 이전 글에서 DS18B20의 타이밍과 구현 로직을 자세히 분석한 바 있으므로 여기서는 소개하지 않겠다.

DS18B20 애플리케이션 노트_ds18b20 읽기 데이터의 파형-CSDN 블로그

3.2 DS18B20 드라이버 구현

3.2.1 IO 상태 정의

코드 14행: 단계 지연 함수 정의

코드 15행: ms 단계 지연 함수 정의

코드 18행: DS18B20의 IO PIN을 정의합니다.

코드 21번째 줄: 입력 포트 구성

코드 22번째 줄: 출력 포트 구성

코드 24번째 줄: IO 낮은 수준 설정

코드 25번째 줄: IO를 높은 수준으로 설정

3.2.2 IO 상태 읽기 기능

코드 47행: 입력 모드에서 IO 상태를 읽습니다.

3.2.3 기타 기능

기능: ds18b20Init, DS18B20이 온라인인지 감지

기능: ds18b20BlockModeProcess. DS18B20의 가치 읽기

  1. /**
  2. * @brief reset DS18B20
  3. * @note if reset ds18b20 sucess, the return value is TRUE
  4. * @param None
  5. * @retval True or Flalse
  6. */
  7. static uint8_t ds18b20Init( void )
  8. {
  9. uint16_t tempCnt = 0;
  10. bsp_io_level_t status;
  11. // Set PIN mode output
  12. DS_Mode_Out_PP();
  13. // Master pin is high
  14. DQ_SET_HIGH;
  15. timeDelayUS(10);
  16. // Master pin is low
  17. DQ_SET_LOW;
  18. // wait for 600 us
  19. timeDelayUS(750);
  20. // Set PIN mode input
  21. DS_Mode_IN_PUT();
  22. while(1)
  23. {
  24. status = DQ_RAD_PIN();
  25. if( status == 0)
  26. {
  27. tempCnt = 0;
  28. return TRUE;
  29. }
  30. else
  31. {
  32. timeDelayUS(1);
  33. tempCnt++;
  34. if( tempCnt > 480 )
  35. return FALSE;
  36. }
  37. }
  38. }
  39. static uint8_t readBit( void )
  40. {
  41. uint8_t readCnt = 2;
  42. uint8_t bitVal = 1;
  43. DQ_SET_LOW;
  44. timeDelayUS(3);
  45. DQ_SET_HIGH;
  46. timeDelayUS(5); // 15 us
  47. while(readCnt-- )
  48. {
  49. //read DQ value
  50. if( DQ_RAD_PIN() == 0)
  51. {
  52. bitVal = 0;
  53. }
  54. timeDelayUS(2); // 15 us
  55. }
  56. timeDelayUS(30); // 15 us
  57. return bitVal;
  58. }
  59. static uint8_t ds18b20ReadByte( void )
  60. {
  61. uint8_t byteVal = 0;
  62. for ( uint8_t i = 0; i < 8; i++ )
  63. {
  64. byteVal >>= 1;
  65. uint8_t bitVal = readBit();
  66. if( bitVal > 0)
  67. {
  68. byteVal |= 0x80;
  69. }
  70. }
  71. return byteVal;
  72. }
  73. /**
  74. * @brief write one byte to DS18B20
  75. * @note
  76. * @param byte: the data that is sended to ds18b20
  77. * @retval None
  78. */
  79. void ds18b20WriteByte( uint8_t byte)
  80. {
  81. unsigned char k;
  82. // Set PIN mode output
  83. DS_Mode_Out_PP();
  84. for ( k = 0; k < 8; k++ )
  85. {
  86. if (byte & (1<<k))
  87. {
  88. DQ_SET_LOW;
  89. timeDelayUS(2);
  90. DQ_SET_HIGH;
  91. timeDelayUS(65);
  92. }
  93. else
  94. {
  95. DQ_SET_LOW;
  96. timeDelayUS(65);
  97. DQ_SET_HIGH;
  98. timeDelayUS(2);
  99. }
  100. }
  101. }
  102. uint8_t ds18b20BlockModeProcess( void )
  103. {
  104. uint16_t tempValue;
  105. uint8_t tempL, tempH;
  106. if (ds18b20Init() == FALSE)
  107. {
  108. return FALSE;
  109. }
  110. // wait for 600 us
  111. timeDelayUS(600);
  112. ds18b20WriteByte(0xcc);
  113. ds18b20WriteByte(0x44); // start convert temperature
  114. if (ds18b20Init() == FALSE)
  115. {
  116. return FALSE;
  117. }
  118. // wait for 600 us
  119. timeDelayUS(600);
  120. ds18b20WriteByte(0xcc);
  121. ds18b20WriteByte(0xbe); // read temperature data register
  122. tempL = ds18b20ReadByte();
  123. tempH = ds18b20ReadByte();
  124. if (tempH > 0x7f)
  125. {
  126. tempL = ~tempL;
  127. tempH = ~tempH+1;
  128. st_ds1b20val.sign = 1;
  129. }
  130. tempValue = (uint16_t)((tempH << 8) | tempL);
  131. st_ds1b20val.temperatureVal = (float)(tempValue * 0.0625);
  132. return TRUE;
  133. }
  134. // NO blocking mode operate ds18b20
  135. uint8_t ds18b20NoBlockingProcess( void )
  136. {
  137. uint16_t tempValue;
  138. static uint16_t waitCnt = 0;
  139. uint8_t tempL, tempH;
  140. static uint8_t runState = 0;
  141. switch( runState )
  142. {
  143. default:
  144. case INIT_DQ:
  145. if (ds18b20Init() == FALSE)
  146. {
  147. return FALSE;
  148. }
  149. runState = WAIT_READY;
  150. break;
  151. case WAIT_READY:
  152. timeDelayUS(2); // IDEL
  153. runState = SKIDROM_CMD;
  154. break;
  155. case SKIDROM_CMD:
  156. ds18b20WriteByte(0xcc);
  157. ds18b20WriteByte(0x44); // begin to convert temperature data
  158. waitCnt = 0;
  159. runState = WAIT_CONVERT;
  160. break;
  161. case WAIT_CONVERT:
  162. waitCnt++;
  163. if( waitCnt > WAIT_CNT_CONVERT)
  164. {
  165. waitCnt = 0;
  166. runState = RESET_CMD;
  167. }
  168. break;
  169. case RESET_CMD:
  170. if (ds18b20Init() == FALSE)
  171. {
  172. return FALSE;
  173. }
  174. runState = WAIT_DATA_READY;
  175. break;
  176. case WAIT_DATA_READY:
  177. timeDelayUS(2); // IDEL
  178. runState = READ_CMD;
  179. break;
  180. case READ_CMD:
  181. ds18b20WriteByte(0xcc);
  182. ds18b20WriteByte(0xbe); // read temperature data register
  183. runState = GET_VALUE;
  184. break;
  185. case GET_VALUE:
  186. tempL = ds18b20ReadByte();
  187. tempH = ds18b20ReadByte();
  188. if (tempH > 0x7f)
  189. {
  190. tempL = ~tempL;
  191. tempH = ~tempH+1;
  192. st_ds1b20val.sign = 1;
  193. }
  194. tempValue = (uint16_t)((tempH << 8) | tempL);
  195. st_ds1b20val.temperatureVal = (float)(tempValue * 0.0625);
  196. runState = INIT_DQ;
  197. return TRUE;
  198. }
  199. return FALSE;
  200. }

4 테스트 절차

4.1 애플리케이션 디자인

코드 113행: ds18b20의 값을 읽습니다.

코드 130번째 줄: ds18b20의 결과 데이터를 얻습니다.

코드 131번째 줄: 형식화된 표시 데이터

코드 132번째 줄: OLED에 데이터 표시

4.2 테스트

코드를 컴파일하고 보드에 다운로드하면 실행 결과는 다음과 같습니다.

액세서리 5개

DS18B20 드라이버 코드

1) ds18b20.c 파일을 생성하고 다음 코드를 작성합니다.

  1. /*
  2. FILE NAME : ds18b20.c
  3. Description: user ds18b20 interface
  4. Date : 2024/06/03
  5. */
  6. #include "ds18b20.h"
  7. #include "hal_data.h"
  8. typedef enum{
  9. INPUT = 0,
  10. OUTPUT = 1,
  11. }IO_TYPE;
  12. typedef enum{
  13. FALSE = 0,
  14. TRUE = 1,
  15. }RETURN_RESULT;
  16. typedef enum{
  17. INIT_DQ = 0,
  18. WAIT_READY,
  19. SKIDROM_CMD,
  20. WAIT_CONVERT,
  21. RESET_CMD,
  22. READ_CMD,
  23. WAIT_DATA_READY,
  24. GET_VALUE,
  25. IDLE_NULL
  26. }RUN_STATE;
  27. ds18b20Struc st_ds1b20val;
  28. ds18b20Struc get_ds18b20_value( void )
  29. {
  30. return st_ds1b20val;
  31. }
  32. static bsp_io_level_t DQ_RAD_PIN(void)
  33. {
  34. bsp_io_level_t state;
  35. // READ io
  36. R_IOPORT_PinRead(&g_ioport_ctrl, DS_IO_PORT_PIN, &state);
  37. return state;
  38. }
  39. /**
  40. * @brief reset DS18B20
  41. * @note if reset ds18b20 sucess, the return value is TRUE
  42. * @param None
  43. * @retval True or Flalse
  44. */
  45. static uint8_t ds18b20Init( void )
  46. {
  47. uint16_t tempCnt = 0;
  48. bsp_io_level_t status;
  49. // Set PIN mode output
  50. DS_Mode_Out_PP();
  51. // Master pin is high
  52. DQ_SET_HIGH;
  53. timeDelayUS(10);
  54. // Master pin is low
  55. DQ_SET_LOW;
  56. // wait for 600 us
  57. timeDelayUS(750);
  58. // Set PIN mode input
  59. DS_Mode_IN_PUT();
  60. while(1)
  61. {
  62. status = DQ_RAD_PIN();
  63. if( status == 0)
  64. {
  65. tempCnt = 0;
  66. return TRUE;
  67. }
  68. else
  69. {
  70. timeDelayUS(1);
  71. tempCnt++;
  72. if( tempCnt > 480 )
  73. return FALSE;
  74. }
  75. }
  76. }
  77. static uint8_t readBit( void )
  78. {
  79. uint8_t readCnt = 2;
  80. uint8_t bitVal = 1;
  81. DQ_SET_LOW;
  82. timeDelayUS(3);
  83. DQ_SET_HIGH;
  84. timeDelayUS(5); // 15 us
  85. while(readCnt-- )
  86. {
  87. //read DQ value
  88. if( DQ_RAD_PIN() == 0)
  89. {
  90. bitVal = 0;
  91. }
  92. timeDelayUS(2); // 15 us
  93. }
  94. timeDelayUS(30); // 15 us
  95. return bitVal;
  96. }
  97. static uint8_t ds18b20ReadByte( void )
  98. {
  99. uint8_t byteVal = 0;
  100. for ( uint8_t i = 0; i < 8; i++ )
  101. {
  102. byteVal >>= 1;
  103. uint8_t bitVal = readBit();
  104. if( bitVal > 0)
  105. {
  106. byteVal |= 0x80;
  107. }
  108. }
  109. return byteVal;
  110. }
  111. /**
  112. * @brief write one byte to DS18B20
  113. * @note
  114. * @param byte: the data that is sended to ds18b20
  115. * @retval None
  116. */
  117. void ds18b20WriteByte( uint8_t byte)
  118. {
  119. unsigned char k;
  120. // Set PIN mode output
  121. DS_Mode_Out_PP();
  122. for ( k = 0; k < 8; k++ )
  123. {
  124. if (byte & (1<<k))
  125. {
  126. DQ_SET_LOW;
  127. timeDelayUS(2);
  128. DQ_SET_HIGH;
  129. timeDelayUS(65);
  130. }
  131. else
  132. {
  133. DQ_SET_LOW;
  134. timeDelayUS(65);
  135. DQ_SET_HIGH;
  136. timeDelayUS(2);
  137. }
  138. }
  139. }
  140. uint8_t ds18b20BlockModeProcess( void )
  141. {
  142. uint16_t tempValue;
  143. uint8_t tempL, tempH;
  144. if (ds18b20Init() == FALSE)
  145. {
  146. return FALSE;
  147. }
  148. // wait for 600 us
  149. timeDelayUS(600);
  150. ds18b20WriteByte(0xcc);
  151. ds18b20WriteByte(0x44); // start convert temperature
  152. if (ds18b20Init() == FALSE)
  153. {
  154. return FALSE;
  155. }
  156. // wait for 600 us
  157. timeDelayUS(600);
  158. ds18b20WriteByte(0xcc);
  159. ds18b20WriteByte(0xbe); // read temperature data register
  160. tempL = ds18b20ReadByte();
  161. tempH = ds18b20ReadByte();
  162. if (tempH > 0x7f)
  163. {
  164. tempL = ~tempL;
  165. tempH = ~tempH+1;
  166. st_ds1b20val.sign = 1;
  167. }
  168. tempValue = (uint16_t)((tempH << 8) | tempL);
  169. st_ds1b20val.temperatureVal = (float)(tempValue * 0.0625);
  170. return TRUE;
  171. }
  172. // NO blocking mode operate ds18b20
  173. uint8_t ds18b20NoBlockingProcess( void )
  174. {
  175. uint16_t tempValue;
  176. static uint16_t waitCnt = 0;
  177. uint8_t tempL, tempH;
  178. static uint8_t runState = 0;
  179. switch( runState )
  180. {
  181. default:
  182. case INIT_DQ:
  183. if (ds18b20Init() == FALSE)
  184. {
  185. return FALSE;
  186. }
  187. runState = WAIT_READY;
  188. break;
  189. case WAIT_READY:
  190. timeDelayUS(2); // IDEL
  191. runState = SKIDROM_CMD;
  192. break;
  193. case SKIDROM_CMD:
  194. ds18b20WriteByte(0xcc);
  195. ds18b20WriteByte(0x44); // begin to convert temperature data
  196. waitCnt = 0;
  197. runState = WAIT_CONVERT;
  198. break;
  199. case WAIT_CONVERT:
  200. waitCnt++;
  201. if( waitCnt > WAIT_CNT_CONVERT)
  202. {
  203. waitCnt = 0;
  204. runState = RESET_CMD;
  205. }
  206. break;
  207. case RESET_CMD:
  208. if (ds18b20Init() == FALSE)
  209. {
  210. return FALSE;
  211. }
  212. runState = WAIT_DATA_READY;
  213. break;
  214. case WAIT_DATA_READY:
  215. timeDelayUS(2); // IDEL
  216. runState = READ_CMD;
  217. break;
  218. case READ_CMD:
  219. ds18b20WriteByte(0xcc);
  220. ds18b20WriteByte(0xbe); // read temperature data register
  221. runState = GET_VALUE;
  222. break;
  223. case GET_VALUE:
  224. tempL = ds18b20ReadByte();
  225. tempH = ds18b20ReadByte();
  226. if (tempH > 0x7f)
  227. {
  228. tempL = ~tempL;
  229. tempH = ~tempH+1;
  230. st_ds1b20val.sign = 1;
  231. }
  232. tempValue = (uint16_t)((tempH << 8) | tempL);
  233. st_ds1b20val.temperatureVal = (float)(tempValue * 0.0625);
  234. runState = INIT_DQ;
  235. return TRUE;
  236. }
  237. return FALSE;
  238. }
  239. /* End of this file */

2) ds18b20.h 파일을 생성하고 다음 코드를 작성합니다.

  1. /*
  2. FILE NAME : ds18b20.h
  3. Description: user ds18b20 interface
  4. Date : 2024/06/03
  5. */
  6. #ifndef DS18B20_H
  7. #define DS18B20_H
  8. #include "hal_data.h"
  9. #define WAIT_CNT_CONVERT 500
  10. #define timeDelayUS(us) R_BSP_SoftwareDelay(us, BSP_DELAY_UNITS_MICROSECONDS);
  11. #define DS_DELAY_MS(ms) R_BSP_SoftwareDelay(ms, BSP_DELAY_UNITS_MILLISECONDS);
  12. #define DS_IO_PORT_PIN BSP_IO_PORT_08_PIN_09
  13. #define DS_Mode_IN_PUT() R_IOPORT_PinCfg(&g_ioport_ctrl, DS_IO_PORT_PIN, IOPORT_CFG_PORT_DIRECTION_INPUT)
  14. #define DS_Mode_Out_PP() R_IOPORT_PinCfg(&g_ioport_ctrl, DS_IO_PORT_PIN, IOPORT_CFG_PORT_DIRECTION_OUTPUT)
  15. #define DQ_SET_LOW R_IOPORT_PinWrite(&g_ioport_ctrl, DS_IO_PORT_PIN, BSP_IO_LEVEL_LOW)
  16. #define DQ_SET_HIGH R_IOPORT_PinWrite(&g_ioport_ctrl, DS_IO_PORT_PIN, BSP_IO_LEVEL_HIGH)
  17. typedef struct{
  18. float temperatureVal;
  19. bool sign;
  20. }ds18b20Struc;
  21. uint8_t ds18b20BlockModeProcess( void );
  22. ds18b20Struc get_ds18b20_value( void );
  23. #endif /* DS18B20_H */