Compartir tecnología

Renesas R7FA8D1BH (Cortex®-M85) controla DS18B20

2024-07-12

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

Tabla de contenido

Descripción general

1 Software y hardware

1.1 Información del entorno de software y hardware

1.2 Información de la placa de desarrollo

1.3 Información del depurador

Configuración de 2 FSP y KEIL

2.1 Circuito de interfaz de hardware

2.2 FSB configura el IO de DS18B20

2.3 Generar archivos de proyecto Keil

3 código de controlador DS18B20

3.1 Introducción a DS18B20

3.2 Implementación del controlador DS18B20

3.2.1 Definición del estado de IO

3.2.2 Función de lectura de estado de IO

3.2.3 Otras funciones

4 procedimientos de prueba

4.1 Diseño de aplicaciones

4.2 Pruebas

5 accesorios


Renesas R7FA8D1BH (Cortex®-M85) controla DS18B20 y ADC para lograr la función de salto de dos páginas

Descripción general

Este artículo presenta principalmente un caso de aplicación integral diseñado para Renesas R7FA8D1BH (Cortex®-M85): aplicar el IO de R7FA8D1BH para implementar un protocolo de bus único y realizar la función de controlar ds18b20. Principalmente completa la lectura del valor de temperatura y el formato del valor. visualización en el OLED de la pantalla. Los datos de temperatura también se envían al terminal del puerto serie a través del terminal del puerto serie.

1 Software y hardware

1.1 Información del entorno de software y hardware

Información de software y hardwareInformación de versión
MCU de RenesasR7FA8D1BH
QuillARM MDK 5.38
versión FSP5.3.0
Herramienta de depuración: N32G45XVL-STBEnlace DAP

1.2 Información de la placa de desarrollo

El autor optó por utilizar la placa de desarrollo Wildfire Yaoyang_Renesas RA8. La MCU de control principal de esta placa es R7FA8D1BHECBD, y el núcleo de 7FA8D1BHECBD es ARM Contex-M85.

1.3 Información del depurador

Para el chip R7FA8D1BHECBD, el núcleo utilizado es Cortex®-M85 Core, ST-LINK-V2 o J-LINK-V9 no admite funciones de descarga y depuración.Después de muchos intentos, el autor descubrió queN32G45XVL-STBEl DAP-LINK que viene con la placa puede descargar y depurar R7FA8D1BHECBD.

La siguiente imagen es una imagen física de la placa de desarrollo N32G45XVL-STB:

Configuración de 2 FSP y KEIL

2.1 Circuito de interfaz de hardware

El circuito de interfaz de DS18B20 ha sido diseñado en la placa de desarrollo Yaoyang_Renesas RA8, que utiliza la interfaz P809 como señal de control DQ de DS18B20.

2.2 FSB configura el IO de DS18B20

Configure P809 como una interfaz IO común y luego configure dinámicamente la salida o el estado de salida de IO en el código

2.3 Generar archivos de proyecto Keil

Después de completar la configuración de parámetros de FSP, puede Generar proyecto. Abra el archivo del proyecto, su estructura es la siguiente:

Cree el archivo ds18b20.c para implementar el código del controlador

3 código de controlador DS18B20

3.1 Introducción a DS18B20

El autor ya analizó en detalle el tiempo y la lógica de implementación de DS18B20 en su artículo anterior, por lo que no lo presentaré aquí.

Nota de aplicación DS18B20_Forma de onda de ds18b20 leyendo datos-CSDN Blog

3.2 Implementación del controlador DS18B20

3.2.1 Definición del estado de IO

Línea 14 del código: Defínenos la función de retardo de paso

Línea 15 del código: Definir la función de retardo de paso en ms

Línea 18 del código: Defina el PIN IO de DS18B20

Línea 21 de código: Configuración del puerto de entrada

Línea 22 de código: Configuración del puerto de salida

Línea 24 de código: Establecer nivel bajo de IO

Línea 25 de código: Establecer nivel alto de IO

3.2.2 Función de lectura de estado de IO

Línea 47 de código: leer el estado de IO en modo de entrada

3.2.3 Otras funciones

Función: ds18b20Init, detecta si DS18B20 está en línea

Función: ds18b20BlockModeProcess. Lea el valor de 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 procedimientos de prueba

4.1 Diseño de aplicaciones

Línea 113 de código: Lea el valor de ds18b20

Línea 130 de código: Obtenga los datos del resultado de ds18b20

Línea 131 de código: datos de visualización formateados

Línea 132 de código: Mostrar datos en OLED

4.2 Pruebas

Compile el código y descárguelo en la placa. Los resultados de la ejecución son los siguientes:

5 accesorios

Código del controlador DS18B20

1) Cree el archivo ds18b20.c y escriba el siguiente código

  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) Cree el archivo ds18b20.h y escriba el siguiente código

  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 */