打印
[Atmel]

用SAM-BA或JLINK跑ATSAM4E16的程序(10)ADC

[复制链接]
1251|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ddllxxrr|  楼主 | 2015-11-12 21:19 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

本程序,有两种ADC模式可选择,一种 正常模式,一种 增加模式,本例可通过串口显示结果,也可通过串口切换ADC模式。

而ADC是通过不断查询ADC中断来完成的。然后把结果显示到串口。

以下是运行的截图:


以下是运行的程序:

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "asf.h"

/** Reference voltage for AFEC in mv. */
#define VOLT_REF        (3300)

/** The maximal digital value */
#define MAX_DIGITAL_12_BIT     (4095UL)

#define STRING_EOL    "\r"
#define STRING_HEADER "-- AFEC Enhanced Resolution Example --\r\n" \
                "-- "BOARD_NAME" --\r\n" \
                "-- Compiled: "__DATE__" "__TIME__" --"STRING_EOL

#define MENU_HEADER "\n\r-- press a key to change the resolution mode--\n\r" \
                "-- n: Normal Resolution Mode--\n\r" \
                "-- e: Enhanced Resolution Mode--\n\r" \
                "-- q: Quit Configuration--\n\r"

/** AFEC sample data */
struct {
        uint32_t value;
        bool is_done;
} g_afec_sample_data;

/** The maximal digital value */
static uint32_t g_max_digital;

/**
* \brief Configure UART console.
*/
static void configure_console(void)
{
        const usart_serial_options_t uart_serial_options = {
                .baudrate = CONF_UART_BAUDRATE,
                .paritytype = CONF_UART_PARITY
        };

        /* Configure console UART. */
        sysclk_enable_peripheral_clock(CONSOLE_UART_ID);
        stdio_serial_init(CONF_UART, &uart_serial_options);
}

/**
* \brief Display main menu.
*/
static void display_menu(void)
{
        puts(MENU_HEADER);
}

/**
* \brief Set AFEC resolution mode.
*/
static void set_afec_resolution(void)
{
        uint8_t uc_key;
        uint8_t uc_done = 0;

        display_menu();

        while (!uc_done) {
                while (uart_read(CONF_UART, &uc_key));

                switch (uc_key) {
                case 'n':
                        g_max_digital = MAX_DIGITAL_12_BIT;
                        afec_set_resolution(AFEC0, AFEC_12_BITS);
                        puts(" Set Resolution to Normal \n\r");
                        break;
                case 'e':
                        g_max_digital = MAX_DIGITAL_12_BIT * 16;
                        afec_set_resolution(AFEC0, AFEC_16_BITS);
                        puts(" Set Resolution to Enhanced \n\r");
                        break;
                case 'q':
                        uc_done = 1;
                        puts(" Quit Configuration \n\r");
                        break;
                default:
                        break;
                }
        }
}

/**
* \brief AFEC interrupt callback function.
*/
static void afec_data_ready(void)
{
        g_afec_sample_data.value = afec_get_latest_value(AFEC0);
        g_afec_sample_data.is_done = true;
}

/**
* \brief Application entry point.
*
* \return Unused (ANSI-C compatibility).
*/
int main(void)
{
        uint8_t uc_key;

        /* Initialize the SAM system. */
        sysclk_init();
        board_init();

        configure_console();

        /* Output example information. */
        puts(STRING_HEADER);

        g_afec_sample_data.value = 0;
        g_afec_sample_data.is_done = false;
        g_max_digital = MAX_DIGITAL_12_BIT;

        afec_enable(AFEC0);

        struct afec_config afec_cfg;

        afec_get_config_defaults(&afec_cfg);
        afec_init(AFEC0, &afec_cfg);

        struct afec_ch_config afec_ch_cfg;
        afec_ch_get_config_defaults(&afec_ch_cfg);
        afec_ch_set_config(AFEC0, AFEC_CHANNEL_POTENTIOMETER, &afec_ch_cfg);

        /*
         * Because the internal ADC offset is 0x800, it should cancel it and shift
         * down to 0.
         */
        afec_channel_set_analog_offset(AFEC0, AFEC_CHANNEL_POTENTIOMETER, 0x800);

        afec_set_trigger(AFEC0, AFEC_TRIG_SW);

        /* Enable channel for potentiometer. */
        afec_channel_enable(AFEC0, AFEC_CHANNEL_POTENTIOMETER);

        afec_set_callback(AFEC0, AFEC_INTERRUPT_DATA_READY, afec_data_ready, 1);

        display_menu();

        afec_start_calibration(AFEC0);
        while((afec_get_interrupt_status(AFEC0) & AFEC_ISR_EOCAL) != AFEC_ISR_EOCAL);

        while (1) {
                afec_start_software_conversion(AFEC0);
                delay_ms(1000);

                /* Check if AFEC sample is done. */
                if (g_afec_sample_data.is_done == true) {
                        printf("Potentiometer Voltage: %4d mv.",
                                        (int)(g_afec_sample_data.value * VOLT_REF
                                        / g_max_digital));
                        puts("\r");
                        g_afec_sample_data.is_done = false;
                }

                /* Check if the user enters a key. */
                if (!uart_read(CONF_UART, &uc_key)) {
                        /* Disable all afec interrupt. */
                        afec_disable_interrupt(AFEC0, AFEC_INTERRUPT_ALL);
                        set_afec_resolution();
                        afec_enable_interrupt(AFEC0, AFEC_INTERRUPT_DATA_READY);
                }
        }
}



相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:http://shop34182318.taobao.com/ http://shop562064536.taobao.com

2398

主题

6945

帖子

66

粉丝