FPGAの内蔵温度センサーから値を得るMAX 10 FPGAで学ぶFPGA開発入門(13)(5/6 ページ)

» 2016年08月10日 09時00分 公開
[大原雄介MONOist]

Eclipseでのプログラミング

 次はEclipseを利用してのプログラミングである。こちらも従来と同じく“File” → “New” → “Nios II Application and BSP from Template”でHello Worldを指定してダミーのソースを生成、それを書き換える形となる。書き換えたソースが以下のList3となる。基本は前回のソースを流用している。

 仕様上の変更点としては以下の2点となる。LEDへの表示などはそのままで、選択したほうの温度を表示するようになっている。

  • ADC経由でのTSDでの温度取り込みに対応
  • これに対応してスイッチをOn/OffからADC経由温度/I2C経由温度/Offの3種類に変更
  1. /*
  2. * "Hello World" example.
  3. *
  4. * This example prints 'Hello from Nios II' to the STDOUT stream. It runs on
  5. * the Nios II 'standard', 'full_featured', 'fast', and 'low_cost' example
  6. * designs. It runs with or without the MicroC/OS-II RTOS and requires a STDOUT
  7. * device in your system's hardware.
  8. * The memory footprint of this hosted application is ~69 kbytes by default
  9. * using the standard reference design.
  10. *
  11. * For a reduced footprint version of this template, and an explanation of how
  12. * to reduce the memory footprint for a given application, see the
  13. * "small_hello_world" template.
  14. *
  15. */
  16. #include <stdio.h>
  17. #include "system.h"
  18. #include "altera_avalon_pio_regs.h"
  19. #include "altera_modular_adc.h"
  20. #include "altera_modular_adc_sequencer_regs.h"
  21. #include "terasic_includes.h"
  22. #include "I2C.h"
  23. #define R_TEMPERATURE 0x00
  24. #define R_HUMIDITY 0x01
  25. #define R_CONFIGURATION 0x02
  26. #define R_MANUFACTURER_ID 0xFE
  27. #define R_DEVICE_ID 0xFF
  28. #define HDC1000_I2C_ADRESS 0x80 // 1000_000 + Write bit 0
  29. long HEXtable[11] = {0x40, // 0:1000000
  30. 0x79, // 1:1111001
  31. 0x24, // 2:0100100
  32. 0x30, // 3:0110000
  33. 0x19, // 4:0011001
  34. 0x12, // 5:0010010
  35. 0x02, // 6:0000010
  36. 0x78, // 7:1111000
  37. 0x00, // 8:0000000
  38. 0x10, // 9:0010000
  39. 0x7F // Blank
  40. };
  41. #define KEY_ONDIE 0x01
  42. #define KEY_I2C 0x02
  43. #define KEY_STOP 0x04
  44. void LEDR_out(int num)
  45. {
  46. if(num > 9) return;
  47. if(num < 0)
  48. {
  49. IOWR_ALTERA_AVALON_PIO_DATA(LEDR_BASE, 0x0); // -の値がきたらBlankにする
  50. }
  51. else
  52. {
  53. IOWR_ALTERA_AVALON_PIO_DATA(LEDR_BASE, 1 << num);
  54. }
  55. }
  56. void HEX_out(int digit, int num)
  57. {
  58. if(num > 9) return;
  59. if(num < 0) num=10; // -の値がきたらBlankにする
  60. if((digit < 0)||(digit > 2)) return;
  61. if(digit)
  62. IOWR_ALTERA_AVALON_PIO_DATA(HEX1_BASE, HEXtable[num]);
  63. else
  64. IOWR_ALTERA_AVALON_PIO_DATA(HEX0_BASE, HEXtable[num]);
  65. }
  66. bool Read_Configuration(void)
  67. {
  68. bool bPass;
  69. alt_u16 data;
  70. bPass = I2C_Read16(RH_TEMP_I2C_SCL_BASE,RH_TEMP_I2C_SDA_BASE,HDC1000_I2C_ADRESS,R_CONFIGURATION,&data);
  71. if(bPass){
  72. printf("Read Configuration Data = 0x%x \r\n",data);
  73. if(((data>>12)&0x0001) == 0) printf("Acquisition mode:Temperature or Humidity is acquired.\r\n ");
  74. else printf("Acquisition mode:Temperature and Humidity are acquired in sequence,Temperature first.\r\n ");
  75. if(((data>>10)&0x0001) == 0) printf("Temperature Measurement Resolution: 14 bit.\r\n ");
  76. else printf("Temperature Measurement Resolution: 11 bit.\r\n ");
  77. if(((data>> 8)&0x0003) == 0) printf("Humidity Measurement Resolution: 14 bit.\r\n ");
  78. else if(((data>> 8)&0x0003) == 1) printf("Humidity Measurement Resolution: 11 bit.\r\n ");
  79. else printf("Humidity Measurement Resolution: 8 bit.\r\n ");
  80. }
  81. return bPass;
  82. }
  83. bool Write_Configuration(alt_u8 acquisition_mode , alt_u8 temp_resolution,alt_u8 humidity_resolution)
  84. {
  85. bool bPass;
  86. alt_u16 data;
  87. data = ((acquisition_mode&0x0001) <<12) + ((temp_resolution&0x0001)<<10) + ((humidity_resolution&0x0003)<<8);
  88. //printf("Write Configuration Data = 0x%x \r\n",data);
  89. bPass = I2C_Write16(RH_TEMP_I2C_SCL_BASE,RH_TEMP_I2C_SDA_BASE,HDC1000_I2C_ADRESS,R_CONFIGURATION,data);
  90. return bPass;
  91. }
  92. bool RH_Temp_Sensor_init(void)
  93. {
  94. bool bPass;
  95. alt_u16 data;
  96. bPass = I2C_Read16(RH_TEMP_I2C_SCL_BASE,RH_TEMP_I2C_SDA_BASE,HDC1000_I2C_ADRESS,R_MANUFACTURER_ID,&data);
  97. if(bPass){
  98. printf("Manufacturer ID is %x\r\n",data);// 0x5449 expected
  99. }else{
  100. printf("I2C MultipleRead Failed!\r\n");
  101. }
  102. bPass = I2C_Read16(RH_TEMP_I2C_SCL_BASE,RH_TEMP_I2C_SDA_BASE,HDC1000_I2C_ADRESS,R_DEVICE_ID,&data);
  103. if(bPass){
  104. printf("Device ID is %x\r\n",data); // 0x1000 expected
  105. }else{
  106. printf("I2C Read16 Failed!\r\n");
  107. }
  108. bPass = Read_Configuration();
  109. if(!bPass){
  110. printf("I2C Read_Configuration Failed!\r\n");
  111. }
  112. bPass = Write_Configuration(1,0,0);
  113. if(!bPass){
  114. printf("[Note] Set Configuration Failed!\r\n");
  115. }
  116. return bPass;
  117. }
  118. int main()
  119. {
  120. alt_u8 KeyStatus, FLAG=0; // 0:Stop 1:Running
  121. bool bPass;
  122. alt_u8 rh_temp[4];
  123. alt_u16 data;
  124. int temp_sum;
  125. int temp_adc;
  126. int temp_int;
  127. int lpCnt;
  128. // Initial Display
  129. HEX_out(0, -1);
  130. HEX_out(1, -1);
  131. LEDR_out(-1);
  132. // Sensor Initialize
  133. RH_Temp_Sensor_init();
  134. // ADC Initialize and Start ADC sequencer
  135. IOWR(ADC_SEQUENCER_CSR_BASE, 0, 0); // Stop ADC
  136. usleep(1000);
  137. IOWR(ADC_SAMPLE_STORE_CSR_BASE, 64, 0); // Disable Interrupt
  138. IOWR(ADC_SEQUENCER_CSR_BASE, 0, 1); // Enable ADC
  139. while(1)
  140. {
  141. // Wait 0.5sec
  142. usleep(500000);
  143. // Examine KEY_STOP & KEY_I2C/KEY_ONDIE
  144. KeyStatus = IORD_ALTERA_AVALON_PIO_DATA(KEY_BASE);
  145. if(( KeyStatus & KEY_STOP ) == 0 )
  146. {
  147. FLAG = 0;
  148. HEX_out(0, -1);
  149. HEX_out(1, -1);
  150. LEDR_out(-1);
  151. }
  152. else if (( KeyStatus & KEY_ONDIE ) == 0 )
  153. {
  154. FLAG = 1;
  155. }
  156. else if (( KeyStatus & KEY_I2C ) == 0 )
  157. {
  158. FLAG = 2;
  159. }
  160. switch( FLAG )
  161. {
  162. case 1:
  163. // Read Temperature from ADC
  164. for(lpCnt=0, temp_sum=0; lpCnt<64; lpCnt++)
  165. {
  166. temp_adc=IORD(ADC_SAMPLE_STORE_CSR_BASE,lpCnt);
  167. temp_sum+=temp_adc;
  168. }
  169. temp_sum /= 64;
  170. temp = (double)temp_sum*(double)temp_sum*-0.0003054+(double)temp_sum*1.7626-2325;
  171. break;
  172. case 2:
  173. // Read Temperature via I2C
  174. bPass = I2C_MultipleRead(RH_TEMP_I2C_SCL_BASE,
  175. RH_TEMP_I2C_SDA_BASE,
  176. HDC1000_I2C_ADRESS,
  177. R_TEMPERATURE,
  178. rh_temp,4);
  179. if(bPass)
  180. {
  181. data = (rh_temp[0] << 8) | rh_temp[1] ;
  182. data = (rh_temp[0] << 8) | rh_temp[1] ;
  183. temp = (double)data/397.188 -40.0;
  184. }
  185. else
  186. {
  187. FLAG = 0; // Failed to read via I2C
  188. }
  189. }
  190. if ( FLAG )
  191. {
  192. temp_int = (int)(temp*10.0);
  193. HEX_out(1,temp_int/100);
  194. HEX_out(0,(temp_int%100)/10);
  195. LEDR_out(temp_int%10);
  196. printf("Temperature: %.1f \n",temp);
  197. }
  198. }
  199. return 0;
  200. }
List3

関連キーワード

アルテラ | FPGA関連 | FPGA

Copyright © ITmedia, Inc. All Rights Reserved.