Κοινή χρήση τεχνολογίας

Το 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 διαμορφώνει το IO του DS18B20

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): εφαρμόζοντας το IO του R7FA8D1BH για την υλοποίηση ενός πρωτοκόλλου διαύλου και πραγματοποιώντας τη λειτουργία οδήγησης ds18b20 Ολοκληρώνει κυρίως την ανάγνωση της τιμής θερμοκρασίας και τη μορφοποίηση της τιμής εμφάνιση στο OLED στην οθόνη. Τα δεδομένα θερμοκρασίας αποστέλλονται επίσης στο τερματικό της σειριακής θύρας μέσω του τερματικού της σειριακής θύρας.

1 Λογισμικό και υλικό

1.1 Πληροφορίες περιβάλλοντος λογισμικού και υλικού

Πληροφορίες λογισμικού και υλικούΠληροφορίες έκδοσης
Renesas MCUR7FA8D1BH
KeilMDK ARM 5.38
Έκδοση FSP5.3.0
Εργαλείο εντοπισμού σφαλμάτων: N32G45XVL-STBDAP-LINK

1.2 Πληροφορίες πίνακα ανάπτυξης

Ο συγγραφέας επέλεξε να χρησιμοποιήσει την Wildfire Yaoyang board_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 έχει σχεδιαστεί στο Yaoyang Development Board_Renesas RA8, το οποίο χρησιμοποιεί τη διεπαφή P809 ως σήμα ελέγχου DQ του DS18B20.

2.2 Το FSB διαμορφώνει το IO του DS18B20

Διαμορφώστε το 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 του κωδικού: Ορίστε το IO PIN του DS18B20

Γραμμή 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 */