検索
連載

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

アルテラのFPGA「MAX 10」には温度センサーが内蔵されており、自身の温度を測定可能だ。メガファンクション「ALTPLL」を使い、内蔵センサーからの値を得るまでを試みる。

Share
Tweet
LINE
Hatena

Eclipseでのプログラミング

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

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

  • ADC経由でのTSDでの温度取り込みに対応
  • これに対応してスイッチをOn/OffからADC経由温度/I2C経由温度/Offの3種類に変更
/*
 * "Hello World" example.
 *
 * This example prints 'Hello from Nios II' to the STDOUT stream. It runs on
 * the Nios II 'standard', 'full_featured', 'fast', and 'low_cost' example
 * designs. It runs with or without the MicroC/OS-II RTOS and requires a STDOUT
 * device in your system's hardware.
 * The memory footprint of this hosted application is ~69 kbytes by default
 * using the standard reference design.
 *
 * For a reduced footprint version of this template, and an explanation of how
 * to reduce the memory footprint for a given application, see the
 * "small_hello_world" template.
 *
 */
#include <stdio.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "altera_modular_adc.h"
#include "altera_modular_adc_sequencer_regs.h"
#include "terasic_includes.h"
#include "I2C.h"
#define R_TEMPERATURE      0x00
#define R_HUMIDITY         0x01
#define R_CONFIGURATION    0x02
#define R_MANUFACTURER_ID  0xFE
#define R_DEVICE_ID        0xFF
#define HDC1000_I2C_ADRESS 0x80 // 1000_000 + Write bit 0
long	HEXtable[11] = {0x40,	// 0:1000000
						0x79,	// 1:1111001
						0x24,	// 2:0100100
						0x30,	// 3:0110000
						0x19,	// 4:0011001
						0x12,	// 5:0010010
						0x02,	// 6:0000010
						0x78,	// 7:1111000
						0x00,	// 8:0000000
						0x10,	// 9:0010000
						0x7F	// Blank
};
#define	KEY_ONDIE	0x01
#define	KEY_I2C		0x02
#define	KEY_STOP	0x04
void LEDR_out(int num)
{
	if(num > 9)	return;
	if(num < 0)
	{
		IOWR_ALTERA_AVALON_PIO_DATA(LEDR_BASE, 0x0);	// -の値がきたらBlankにする
	}
	else
	{
		IOWR_ALTERA_AVALON_PIO_DATA(LEDR_BASE, 1 << num);
	}
}
void HEX_out(int digit, int num)
{
	if(num > 9)	return;
	if(num < 0)	num=10;	// -の値がきたらBlankにする
	if((digit < 0)||(digit > 2))	return;
	if(digit)
		IOWR_ALTERA_AVALON_PIO_DATA(HEX1_BASE, HEXtable[num]);
	else
		IOWR_ALTERA_AVALON_PIO_DATA(HEX0_BASE, HEXtable[num]);
}
bool Read_Configuration(void)
{
	bool bPass;
	alt_u16 data;
	bPass = I2C_Read16(RH_TEMP_I2C_SCL_BASE,RH_TEMP_I2C_SDA_BASE,HDC1000_I2C_ADRESS,R_CONFIGURATION,&data);
	if(bPass){
		printf("Read Configuration Data = 0x%x \r\n",data);
		if(((data>>12)&0x0001) == 0) printf("Acquisition mode:Temperature or Humidity is acquired.\r\n ");
		else printf("Acquisition mode:Temperature and Humidity are acquired in sequence,Temperature first.\r\n ");
		if(((data>>10)&0x0001) == 0) printf("Temperature Measurement Resolution: 14 bit.\r\n ");
		else  printf("Temperature Measurement Resolution: 11 bit.\r\n ");
		if(((data>> 8)&0x0003) == 0) printf("Humidity Measurement Resolution: 14 bit.\r\n ");
		else if(((data>> 8)&0x0003) == 1) printf("Humidity Measurement Resolution: 11 bit.\r\n ");
		else  printf("Humidity Measurement Resolution: 8 bit.\r\n ");
	}
	return bPass;
}
bool Write_Configuration(alt_u8 acquisition_mode , alt_u8 temp_resolution,alt_u8 humidity_resolution)
{
	bool bPass;
	alt_u16 data;
	data = ((acquisition_mode&0x0001) <<12) + ((temp_resolution&0x0001)<<10) + ((humidity_resolution&0x0003)<<8);
	//printf("Write Configuration Data = 0x%x \r\n",data);
	bPass = I2C_Write16(RH_TEMP_I2C_SCL_BASE,RH_TEMP_I2C_SDA_BASE,HDC1000_I2C_ADRESS,R_CONFIGURATION,data);
	return bPass;
}
bool RH_Temp_Sensor_init(void)
{
	bool bPass;
    alt_u16 data;
	bPass = I2C_Read16(RH_TEMP_I2C_SCL_BASE,RH_TEMP_I2C_SDA_BASE,HDC1000_I2C_ADRESS,R_MANUFACTURER_ID,&data);
    if(bPass){
		printf("Manufacturer ID is %x\r\n",data);// 0x5449 expected
    }else{
	    printf("I2C MultipleRead Failed!\r\n");
    }
    bPass = I2C_Read16(RH_TEMP_I2C_SCL_BASE,RH_TEMP_I2C_SDA_BASE,HDC1000_I2C_ADRESS,R_DEVICE_ID,&data);
    if(bPass){
	    printf("Device ID is %x\r\n",data); // 0x1000 expected
    }else{
	    printf("I2C Read16 Failed!\r\n");
    }
    bPass =  Read_Configuration();
    if(!bPass){
		printf("I2C Read_Configuration Failed!\r\n");
	}
	bPass =  Write_Configuration(1,0,0);
    if(!bPass){
		printf("[Note] Set Configuration Failed!\r\n");
	}
	return bPass;
}
int main()
{
	alt_u8 KeyStatus, FLAG=0;	// 0:Stop 1:Running
	bool    bPass;
	alt_u8  rh_temp[4];
	alt_u16 data;
	int		temp_sum;
	int		temp_adc;
	int		temp_int;
	int		lpCnt;
	// Initial Display
	HEX_out(0, -1);
	HEX_out(1, -1);
	LEDR_out(-1);
	// Sensor Initialize
	RH_Temp_Sensor_init();
	// ADC Initialize and Start ADC sequencer
    IOWR(ADC_SEQUENCER_CSR_BASE, 0, 0);		// Stop ADC
    usleep(1000);
    IOWR(ADC_SAMPLE_STORE_CSR_BASE, 64, 0);	// Disable Interrupt
    IOWR(ADC_SEQUENCER_CSR_BASE, 0, 1);		// Enable ADC
	while(1)
	{
		// Wait 0.5sec
		usleep(500000);
		// Examine KEY_STOP & KEY_I2C/KEY_ONDIE
		KeyStatus = IORD_ALTERA_AVALON_PIO_DATA(KEY_BASE);
		if(( KeyStatus & KEY_STOP ) == 0 )
		{
			FLAG = 0;
			HEX_out(0, -1);
			HEX_out(1, -1);
			LEDR_out(-1);
		}
		else if (( KeyStatus & KEY_ONDIE ) == 0 )
		{
			FLAG = 1;
		}
		else if (( KeyStatus & KEY_I2C ) == 0 )
		{
			FLAG = 2;
		}
		switch( FLAG )
		{
			case 1:
				// Read Temperature from ADC
				for(lpCnt=0, temp_sum=0; lpCnt<64; lpCnt++)
				{
					temp_adc=IORD(ADC_SAMPLE_STORE_CSR_BASE,lpCnt);
					temp_sum+=temp_adc;
				}
				temp_sum /= 64;
				temp = (double)temp_sum*(double)temp_sum*-0.0003054+(double)temp_sum*1.7626-2325;
				break;
			case 2:
				// Read Temperature via I2C
				bPass =  I2C_MultipleRead(RH_TEMP_I2C_SCL_BASE,
										  RH_TEMP_I2C_SDA_BASE,
										  HDC1000_I2C_ADRESS,
										  R_TEMPERATURE,
										  rh_temp,4);
				if(bPass)
				{
					data = (rh_temp[0] << 8) | rh_temp[1] ;
					data = (rh_temp[0] << 8) | rh_temp[1] ;
					temp = (double)data/397.188 -40.0;
				}
				else
				{
					FLAG = 0;	// Failed to read via I2C
				}
		}
		if ( FLAG )
		{
			temp_int = (int)(temp*10.0);
			HEX_out(1,temp_int/100);
			HEX_out(0,(temp_int%100)/10);
			LEDR_out(temp_int%10);
			printf("Temperature: %.1f \n",temp);
		}
	}
  return 0;
}
List3

関連キーワード

アルテラ | FPGA関連 | FPGA


Copyright © ITmedia, Inc. All Rights Reserved.

ページトップに戻る