Atmel SAM4S开发套件体验3之IO1 Xplained Pro

作者: renegade
上传时间为: 2014-12-04 10:44 PM
2014-12-04
阅读:

Atmel IO1 Xplained Pro这块板子也是套件中的一部分,今天就让我们一起来领略一下其中的魅力吧

老样子,使用一款陌生的开发板最好的办法就是阅读这个商家的用户指南了,我们阅读技术文档可以看到这个板子是一个拓展版,上面集成了SD卡,温度传感器,光学传感器


idchip:就是之前说的开发板身份证,通过这个可以读出开发板的信息

 light senor:光传感器

lowpass filter:低通滤波器

下面一行依次是串口接头,gpio接头,电源接头,sd卡卡槽

然后我们看一下引脚接口定义

下面我们通过一段结合了我的中文注释的程序来认识一下这块开发板:

#include <asf.h>//头文件
#include <string.h>
//配置sd卡,各模式开关
volatile uint32_t app_mode = 2;
volatile uint32_t app_mode_switch = 1;

volatile uint32_t sd_update = 0;
volatile uint32_t sd_fs_found = 0;
volatile uint32_t sd_listing_pos = 0;
volatile uint32_t sd_num_files = 0;

FATFS fs;


static void ProcessButtonEvt(uint8_t uc_button)
{
	/* 转换三种模式:温度,光,sd卡*/
	if (uc_button == 1)
	{
		app_mode_switch = 1;
	}
	/* 翻向上页键 */
	else if ((uc_button == 2) &&
				(app_mode == 2) &&
				(sd_fs_found == 1) &&
				(sd_update == 0))
	{
		if (sd_listing_pos > 0)
		{
			sd_listing_pos -= 1;
			sd_update = 1;
		}
	}
	/* 向下页码键 */
	else if ((uc_button == 3) &&
				(app_mode == 2) &&
				(sd_fs_found == 1) &&
				(sd_update == 0))
	{
		/* 当显示最后一页时停住 */
		if (sd_listing_pos < sd_num_files)
		{
			sd_listing_pos += 1;
			sd_update = 1;
		}
	}
}



static void configure_adc(void)
{
	/* 配置ADC采样光学传感器. */
	gpio_configure_pin(LIGHT_SENSOR_GPIO, LIGHT_SENSOR_FLAGS);

	/* 使能 ADC 时钟. */
	pmc_enable_periph_clk(ID_ADC);

	/* 配置 ADC. */
	adc_init(ADC, sysclk_get_cpu_hz(), 1000000, ADC_MR_STARTUP_SUT0);
	adc_enable_channel(ADC, ADC_CHANNEL_4);
	adc_configure_trigger(ADC, ADC_TRIG_SW, 1);
}

static void get_num_files_on_sd(void)
{
	FRESULT res;
	FILINFO fno;
	DIR dir;
	char *pc_fn;
	const char *path = "0:";
#if _USE_LFN
	char c_lfn[_MAX_LFN + 1];
	fno.lfname = c_lfn;
	fno.lfsize = sizeof(c_lfn);
#endif

	sd_num_files = 0;

	/*打开目录 */
	res = f_opendir(&dir, path);
	if (res == FR_OK)
	{
		for (;;)
		{
			res = f_readdir(&dir, &fno);
			if (res != FR_OK || fno.fname[0] == 0)
			{
				break;
			}

#if _USE_LFN
			pc_fn = *fno.lfname ? fno.lfname : fno.fname;
#else
			pc_fn = fno.fname;
#endif
			if (*pc_fn == '.')
			{
				continue;
			}

			sd_num_files += 1;
		}
	}
}
//显示SD卡内信息
static void display_sd_info(void)
{
	FRESULT res;
	uint8_t card_check;
	uint8_t sd_card_type;
	uint32_t sd_card_size;
	char size[64];
//如果检测不到SD卡,显示请插入SD卡
	if (gpio_pin_is_low(SD_MMC_0_CD_GPIO) == false)
	{
		ssd1306_write_text("Please insert SD card...");
	}
	else
	{
		ssd1306_write_text("SD card information:");

		sd_mmc_init();
		card_check = sd_mmc_check(0);
		while (card_check != SD_MMC_OK)
		{
			card_check = sd_mmc_check(0);
			delay_ms(1);
		}
                //校准SD卡
		if (card_check == SD_MMC_OK)
		{
			sd_card_type = sd_mmc_get_type(0);
			sd_card_size = sd_mmc_get_capacity(0);

			ssd1306_set_page_address(1);

			ssd1306_set_page_address(2);
			ssd1306_set_column_address(0);

			sprintf(size, "- Total size: %lu KB", sd_card_size);
			ssd1306_write_text(size);

			ssd1306_set_page_address(3);
			ssd1306_set_column_address(0);

			// Try to mount file system.
			memset(&fs, 0, sizeof(FATFS));
			res = f_mount(LUN_ID_SD_MMC_0_MEM, &fs);
			if (FR_INVALID_DRIVE == res)
			{
				ssd1306_write_text("   <No FAT FS found on SD>");
				sd_fs_found = 0;
			}
			else
			{
				get_num_files_on_sd();
				if (sd_num_files == 0)
				{
					ssd1306_write_text("         <no content>");
					sd_fs_found = 1;
				}
				else
				{
					ssd1306_write_text("  <Press B2-3 to browse SD>");
					sd_fs_found = 1;
				}
			}
		}
	}
}

/**
显示sd卡的内容在oled 上
 */
static void display_sd_files(void)
{
	FRESULT res;
	FILINFO fno;
	DIR dir;
	uint32_t line;
	uint32_t pos;
	char *pc_fn;
	const char *path = "0:";
#if _USE_LFN
	char c_lfn[_MAX_LFN + 1];
	fno.lfname = c_lfn;
	fno.lfsize = sizeof(c_lfn);
#endif

	line = 0;
	pos = 1;

	/* 打开目录*/
	res = f_opendir(&dir, path);
	if (res == FR_OK)
	{
		for (;;)
		{
			res = f_readdir(&dir, &fno);
			if (res != FR_OK || fno.fname[0] == 0)
			{
				break;
			}

#if _USE_LFN
			pc_fn = *fno.lfname ? fno.lfname : fno.fname;
#else
			pc_fn = fno.fname;
#endif
			if (*pc_fn == '.')
			{
				continue;
			}

			if ((pos >= sd_listing_pos) && (line < 4))
			{
				ssd1306_set_page_address(line++);
				ssd1306_set_column_address(0);
				ssd1306_write_text("/");
				ssd1306_write_text(pc_fn);
			}

			pos += 1;
		}
	}
}

//SD卡画图函数
static void ssd1306_draw_graph(uint8_t col, uint8_t page, uint8_t width, uint8_t height, uint8_t *tab)
{
	uint8_t page_start;
	uint8_t i, j, k, s;
	uint8_t scale;

	for (i = col; i < width; ++i) {
		for (page_start = page; page_start <= height; ++page_start) {
			ssd1306_write_command(SSD1306_CMD_SET_PAGE_START_ADDRESS(page_start));
			ssd1306_set_column_address(i);
			j = tab[i];
			scale = 8 * (height - page_start + 1);
			if (j > scale)
				j = 8;
			else
				j -= (scale - 8);

			for (k = 0, s = j; j > 0; --j)
				k = (k << 1) + 1;
			for (s = 8 - s; s > 0; --s)
				k <<= 1;
			ssd1306_write_data(k);
		}
	}
}

/**
清除屏幕
 */
static void ssd1306_clear_char(void)
{
	ssd1306_write_data(0x00);
	ssd1306_write_data(0x00);
	ssd1306_write_data(0x00);
	ssd1306_write_data(0x00);
	ssd1306_write_data(0x00);
	ssd1306_write_data(0x00);
}

#define BUFFER_SIZE 128

int main(void)
{//程序初始化
	uint8_t i;
	uint8_t temperature[BUFFER_SIZE];
	uint8_t light[BUFFER_SIZE];
	char value_disp[5];
	uint32_t adc_value;
	uint32_t light_value;
	double temp;

	// Initialize clocks.
	sysclk_init();

	// Initialize GPIO states.
	board_init();

	// Configure ADC for light sensor.
	configure_adc();

	// Initialize at30tse.
	at30tse_init();

	// Configure IO1 buttons.
	configure_buttons();

	// Initialize SPI and SSD1306 controller.
	ssd1306_init();
	ssd1306_clear();

	// Clear internal buffers.
	for (i = 0; i < BUFFER_SIZE; ++i)
	{
		temperature[i] = 0;
		light[i] = 0;
	}

	while (true)
	{
		/* Refresh page title only if necessary. */
		if (app_mode_switch > 0)
		{
			app_mode = (app_mode + 1) % 3;

			// Clear screen.
			ssd1306_clear();
			ssd1306_set_page_address(0);
			ssd1306_set_column_address(0);

			/* 温度模式*/
			if (app_mode == 0)
			{
				ioport_set_pin_level(IO1_LED1_PIN, IO1_LED1_ACTIVE);
				ioport_set_pin_level(IO1_LED2_PIN, !IO1_LED2_ACTIVE);
				ioport_set_pin_level(IO1_LED3_PIN, !IO1_LED3_ACTIVE);
				ssd1306_write_text("Temperature sensor:");
			}
			/* 光感模式 */
			else if (app_mode == 1)
			{
				ioport_set_pin_level(IO1_LED2_PIN, IO1_LED2_ACTIVE);
				ioport_set_pin_level(IO1_LED1_PIN, !IO1_LED1_ACTIVE);
				ioport_set_pin_level(IO1_LED3_PIN, !IO1_LED3_ACTIVE);
				ssd1306_write_text("Light sensor:");
			}
			/* SD 模式 */
			else
			{
				ioport_set_pin_level(IO1_LED3_PIN, IO1_LED3_ACTIVE);
				ioport_set_pin_level(IO1_LED1_PIN, !IO1_LED1_ACTIVE);
				ioport_set_pin_level(IO1_LED2_PIN, !IO1_LED2_ACTIVE);

				sd_listing_pos = 0;
				display_sd_info();
			}

			app_mode_switch = 0;
		}

		转换图像
		for (i = 0; i < BUFFER_SIZE - 1; ++i)
		{
			temperature[i] = temperature[i + 1];
			light[i] = light[i + 1];
		}

		温度范围是0-40
		if (at30tse_read_temperature(&temp) == TWI_SUCCESS)
		{
			// Don't care about negative temperature.
			if (temp < 0)
				temp = 0;

			// Update temperature for display.
			// Note: -12 in order to rescale for better rendering.
			if (temp < 12)
				temperature[BUFFER_SIZE - 1] = 0;
			else
				temperature[BUFFER_SIZE - 1] = temp - 12;
		}
		else
		{
			// 错误输出0
			temperature[BUFFER_SIZE - 1] = 0;
		}

		// 得到光传感器信息
		adc_start(ADC);
		adc_value = adc_get_channel_value(ADC, ADC_CHANNEL_4);
		light[BUFFER_SIZE - 1] = 24 - adc_value * 24 / 4096;

		// Print temperature in text format.
		if (app_mode == 0)
		{
			sprintf(value_disp, "%d", (uint8_t)temp);
			ssd1306_set_column_address(95);
			ssd1306_write_command(SSD1306_CMD_SET_PAGE_START_ADDRESS(0));
			ssd1306_write_text(" ");
			// Avoid character overlapping.
			if (temp < 10)
				ssd1306_clear_char();
			ssd1306_write_text(value_disp);
			// Display degree symbol.
			ssd1306_write_data(0x06);
			ssd1306_write_data(0x06);
			ssd1306_write_text("c");

			// Refresh graph.
			ssd1306_draw_graph(0, 1, BUFFER_SIZE, 3, temperature);
		}
		else if (app_mode == 1)
		{
			light_value = 100 - (adc_value * 100 / 4096);
			sprintf(value_disp, "%lu", light_value);
			ssd1306_set_column_address(98);
			ssd1306_write_command(SSD1306_CMD_SET_PAGE_START_ADDRESS(0));
			ssd1306_write_text(" ");
			// Avoid character overlapping.
			if (light_value < 10)
				ssd1306_clear_char();
			ssd1306_write_text(value_disp);
			ssd1306_write_text("%");
			// Avoid character overlapping.
			if (light_value < 100)
				ssd1306_clear_char();

			// Refresh graph.
			ssd1306_draw_graph(0, 1, BUFFER_SIZE, 3, light);
		}
		else
		{
			//如果shanchu
			if (sd_update == 1)
			{
				//清屏
				ssd1306_clear();
				ssd1306_set_page_address(0);
				ssd1306_set_column_address(0);

				if (sd_listing_pos == 0)
				{
					// 显示SD卡信息
					display_sd_info();
				}
				else
				{
					// List SD card files.
					display_sd_files();
				}

				sd_update = 0;
			}

		}

		delay_ms(50);
	}
}
全部评论 ()
条评论
写评论

创建讨论帖子

登录 后参与评论
系统提示