реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Использование USB снижает количество отсчётов АЦП, В большинстве случаев до нуля
budda
сообщение Jun 6 2014, 14:47
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 6-09-12
Из: Челябинск
Пользователь №: 73 412



Здравствуйте!

Я использую USB как отладочный интерфейс на плате с ATXmega32a4u. В основном цикле программы я опрашиваю АЦП и подсчитываю количество выборок. Раз в 20 мс срабатывает внешнее прерывание на одном из портов общего назначения. По прерыванию я провожу вычисления, а результаты вычислений и количество отсчётов я помещаю в строку, которую затем буду передавать по USB. Проблема: если отключить модуль USB совсем, я успеваю получить около 900 отсчётов, как и было задумано, но с USB в большинстве случаев 0, иногда около 450. Такие значения оказываются в строке, да и отладка светодиодом показывает то же самое. В прерывании включаю светодиод, если отсчётов > 800, выключаю, если меньше. Если USB-кабель подключен - не горит, отключаю - горит.

Функция main:
CODE
box#include <asf.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#include "main.h"

volatile uint64_t g_squared_sum;
volatile uint16_t g_samples;
volatile uint8_t g_signal_phase;
volatile uint8_t g_duty_cycle = 50;
volatile char g_usb_string[81];
volatile bool g_usb_timeout_is_counted = false;

ISR(PORTD_INT0_vect);
ISR(BADISR_vect);
ISR(TCC0_OVF_vect);
ISR(TCC0_CCA_vect);
ISR(TCC0_CCB_vect);
ISR(TCC1_OVF_vect);
void vbus_event(bool vbus);
uint32_t get_RMS(void);
uint32_t average(uint32_t new_RMS);

int main (void)
{
int32_t adc_result;

irq_initialize_vectors(); // enable all irq priorities
sei();
sysclk_init(); // turns off all peripheral. It reduces noise to ADC
sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_ADC); // turn on ADC on port A
sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC0); // turn on TC0 clock
sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC1); // turn on TC1 clock

#ifdef DEBUG2
stdio_usb_init(); // enables and attaches USB, readdress std streams to USB
#endif

board_init(); // LEDs,buttons, ADC, TC0 settings

while(1)
{
if(ADCA.CH0.INTFLAGS)
{
adc_result = (int32_t)ADCA.CH0.RES - ADC_OFFSET - BOARD_OFFSET;
cli(); // need cli and sei to avoid executing irq
g_samples += 1; // between changing g_samples and g_squared_sum
g_squared_sum += (uint64_t) (adc_result * adc_result);
sei(); // now irq enabled
ADCA.CH0.INTFLAGS = 1; // clean flag
}
}
}


Вот прерывание:
Код
ISR(PORTD_INT0_vect)
{
    average(get_RMS());
    tcc0_restart();
    PORTB.OUTCLR = PIN3_bm;
    g_signal_phase = 0;
}


Формирование строки для USB происходит в функции get_RMS()
CODE
uint32_t get_RMS(void)
{ // count RMS based on global variables g_squared_sum, g_samples,
// that are accumulated in a main loop

uint32_t result = 0;

if(g_samples)
result = (uint32_t) sqrt(g_squared_sum/g_samples);// to avoid dividing by zero

#ifdef DEBUG2
sprintf(g_usb_string, "result= %lu, sq_sum = 0x%lX%lX, samples = %u\r\n",
result, (uint32_t)(g_squared_sum>>32), (uint32_t)g_squared_sum, g_samples);
#endif

g_samples = g_squared_sum = 0; // reset accumulated sum and samples counter


return result;
}


Для работы с USB использую библиотеку ASF. Устройство нормально подключается, опознаётся. Чтобы получить строку, я отправляю через Putty символ, на что мне оно отвечает заранее подготовленной строкой из функции обратного вызова от драйвера интерфейса по получении данных в USB.
Код
void my_callback_rx_notify(uint8_t port)
{
    char c;
    
    stdio_usb_getchar(0, &c);
    stdio_usb_write(g_usb_string, strlen(g_usb_string));
}


Может ли USB так влиять? Опять же отладка светодиодами показала, что большую часть времени процессор проводит всё же в цикле main, а не в прерываниях USB. Может, я как-то не так передаю значение счётчика? Объявлен глобальной переменной со спецификатором volatile.

Помогите, пожалуйста!

Сообщение отредактировал IgorKossak - Jun 6 2014, 15:23
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 22:07
Рейтинг@Mail.ru


Страница сгенерированна за 0.01341 секунд с 7
ELECTRONIX ©2004-2016