SAMD21板子上有一片SPI接口的EEPROM,不错,今天驱动它。
首先在前一个工程基础上添加EEPROM模块。
再打开ASF EXPLOER 找到快速开始说明文档。
编译时提示少了管脚定义,这时可以增加一个.h文件。
#ifndef CONF_AT25DFX_H_INCLUDED
#define CONF_AT25DFX_H_INCLUDED
#include <board.h>
#include "at25dfx.h"
//! Select the SPI module AT25DFx is connected to
#define AT25DFX_SPI SERIALFLASH_SPI_MODULE
/** AT25DFx device type */
#define AT25DFX_MEM_TYPE AT25DFX_081A
#define AT25DFX_SPI_PINMUX_SETTING SERIALFLASH_SPI_MUX_SETTING
#define AT25DFX_SPI_PINMUX_PAD0 SERIALFLASH_SPI_PINMUX_PAD0
#define AT25DFX_SPI_PINMUX_PAD1 SERIALFLASH_SPI_PINMUX_PAD1
#define AT25DFX_SPI_PINMUX_PAD2 SERIALFLASH_SPI_PINMUX_PAD2
#define AT25DFX_SPI_PINMUX_PAD3 SERIALFLASH_SPI_PINMUX_PAD3
#define AT25DFX_CS SERIALFLASH_SPI_CS
//! SPI master speed in Hz.
#define AT25DFX_CLOCK_SPEED 120000
#endif /* CONF_AT25DFX_H_INCLUDED */
这时再编译则编译通过。时钟配置不用改变。但写EEPROM顺序注意一下。有时写保护打开时才可写入,读出是在保护加上时才可读出。
结果我用两种方式,一个是灯亮一下,写完灯灭,再有一种是通过串口输出信息结果如下:
程序清单列出:
/**
* \file
*
* \brief Empty user application template
*
*/
/**
* \mainpage User Application template doxygen documentation
*
* \par Empty user application template
*
* This is a bare minimum user application template.
*
* For documentation of the board, go \ref group_common_boards "here" for a link
* to the board-specific documentation.
*
* \par Content
*
* -# Include the ASF header files (through asf.h)
* -# Minimal main function that starts with a call to system_init()
* -# Basic usage of on-board LED and button
* -# "Insert application code here" comment
*
*/
/*
* Include header files for all drivers that have been imported from
* Atmel Software Framework (ASF).
*/
#include <asf.h>
#include <stdio_serial.h>
#include "conf_at25dfx.h"
bool volatile callback_status = false;
void configure_usart(void);
struct usart_module usart_instance;
void configure_usart(void)
{
struct usart_config config_usart;
usart_get_config_defaults(&config_usart);
config_usart.baudrate = 9600;
config_usart.mux_setting = EXT3_UART_SERCOM_MUX_SETTING;
config_usart.pinmux_pad0 = EXT3_UART_SERCOM_PINMUX_PAD0;
config_usart.pinmux_pad1 = EXT3_UART_SERCOM_PINMUX_PAD1;
config_usart.pinmux_pad2 = EXT3_UART_SERCOM_PINMUX_PAD2;
config_usart.pinmux_pad3 = EXT3_UART_SERCOM_PINMUX_PAD3;
while (usart_init(&usart_instance, EXT3_UART_MODULE, &config_usart) != STATUS_OK)
{ }
stdio_serial_init(&usart_instance, EXT3_UART_MODULE, &config_usart);
usart_enable(&usart_instance);
}
#define AT25DFX_BUFFER_SIZE (10)
static uint8_t read_buffer[AT25DFX_BUFFER_SIZE];
static uint8_t write_buffer[AT25DFX_BUFFER_SIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
struct spi_module at25dfx_spi;
struct at25dfx_chip_module at25dfx_chip;
static void at25dfx_init(void)
{
struct at25dfx_chip_config at25dfx_chip_config;
struct spi_config at25dfx_spi_config;
at25dfx_spi_get_config_defaults(&at25dfx_spi_config);
at25dfx_spi_config.mode_specific.master.baudrate = AT25DFX_CLOCK_SPEED;
at25dfx_spi_config.mux_setting = AT25DFX_SPI_PINMUX_SETTING;
at25dfx_spi_config.pinmux_pad0 = AT25DFX_SPI_PINMUX_PAD0;
at25dfx_spi_config.pinmux_pad1 = AT25DFX_SPI_PINMUX_PAD1;
at25dfx_spi_config.pinmux_pad2 = AT25DFX_SPI_PINMUX_PAD2;
at25dfx_spi_config.pinmux_pad3 = AT25DFX_SPI_PINMUX_PAD3;
spi_init(&at25dfx_spi, AT25DFX_SPI, &at25dfx_spi_config);
spi_enable(&at25dfx_spi);
at25dfx_chip_config.type = AT25DFX_MEM_TYPE;
at25dfx_chip_config.cs_pin = AT25DFX_CS;
at25dfx_chip_init(&at25dfx_chip, &at25dfx_spi, &at25dfx_chip_config);
}
uint8_t i;
int main (void)
{
system_init();
configure_usart();
at25dfx_init();
uint8_t string[] = "This is AT25DFX test!\r\n";
uint8_t string2[] = "This is AT25DFX test Good,Very Happy!\r\n";
usart_write_buffer_wait(&usart_instance, string, sizeof(string));
system_interrupt_enable_global();
at25dfx_chip_wake(&at25dfx_chip);
port_pin_set_output_level(LED_0_PIN, false);
if (at25dfx_chip_check_presence(&at25dfx_chip) != STATUS_OK)
{ // Handle missing or non-responsive device
}
at25dfx_chip_read_buffer(&at25dfx_chip, 0x0000, read_buffer, AT25DFX_BUFFER_SIZE);
at25dfx_chip_set_sector_protect(&at25dfx_chip, 0x10000, false);
at25dfx_chip_erase_block(&at25dfx_chip, 0x10000, AT25DFX_BLOCK_SIZE_4KB);
at25dfx_chip_write_buffer(&at25dfx_chip, 0x10000, write_buffer, AT25DFX_BUFFER_SIZE);
at25dfx_chip_set_global_sector_protect(&at25dfx_chip, true);
at25dfx_chip_read_buffer(&at25dfx_chip, 0x10000, read_buffer, AT25DFX_BUFFER_SIZE);
for(i=0;i<=11;i++)
{
if(read_buffer[i]!= write_buffer[i])
{
break;
}
}
if (i<= 11)
{
printf("the test is good!!!");
}
at25dfx_chip_sleep(&at25dfx_chip);
port_pin_set_output_level(LED_0_PIN, true);
while (true)
{
;
}
}
运行时截图:
|