помогите плиз с adc в dma режиме

Учебный лабораторный комплекс SDK-1.1 на базе микроконтроллера ADuC812 с ядром MCS51 # RS-232C, I2C

помогите плиз с adc в dma режиме

Сообщение AnopT » 25 ноя 2009, 19:02

Собственно, сабж. Проблема в том, что после установки указателя DMAL, DMAH, DMAP на нужный участок памяти, конфигурирования памяти и установке в ADCCON2 бита DMA, стенд перезагружается. Чем лечить?

Примеры приветствуются.
AnopT
 
Сообщения: 5
Зарегистрирован: 25 ноя 2009, 18:55

Re: помогите плиз с adc в dma режиме

Сообщение DinKa » 26 ноя 2009, 00:20

Ваша программа располагается во внешней памяти программ и данных (SRAM) + АЦП в режиме ПДП использует ту же память для складирования своих замеров, при этом АЦП захватывает шину адреса и данных (порты P0 и P2) в режиме DMA (см. ADuC812 datasheet). Таким образом, во время A/D-преобразования вычислительному ядру ADuC812 недоступны ни данные, ни инструкции, хранящиеся во внешней памяти. Выборка команд, конечно же, не останавливается, но что в таком случае выбирается - неизвестно. Видимо, выбирается что-то некорректное с точки зрения процессора, поэтому он перезагружается и стартует опять выполнение загрузчика (из Flash-памяти). Проверкой является то, что без ПДП всё OK (см. пример).
Лечение предлагаю следующее: программу загружайте во Flash (вместо загрузчика UL3/HEX-202) и работайте с АЦП в режиме ПДП. В таком случае битвы за системную шину не будет. Для написания программы для FLash посмотрите исходники загрузчика тут. Особое внимание следует уделить настройкам компилятора, линкера в makefile.
DinKa
 
Сообщения: 247
Зарегистрирован: 23 апр 2008, 18:01

Re: помогите плиз с adc в dma режиме

Сообщение kluchev » 26 ноя 2009, 11:58

На официальном сайте есть примерчик для аналогичного процессора.

Application Note: UC-019: DMA To XRAM on the ADuC831/832
В споре рождается коллективное заблуждение, а истиной мы его называем для краткости
Аватара пользователя
kluchev
 
Сообщения: 995
Зарегистрирован: 04 апр 2008, 13:31
Откуда: SPb

Re: помогите плиз с adc в dma режиме

Сообщение AnopT » 28 ноя 2009, 09:04

2 Kluchev:
Странно, вроде почти все делаю по примеру. Не могли бы вы взглянуть, что не так? Вот код:
#include <ADuC812.h>
#include "max.h"
#include "vect.h"
#include "dac.h"
int flag=0;
xdata unsigned int *xdatPtr;
void ADC() interrupt 6
{
ADCCON1=0x00;
flag=1;
WriteMax(0x7,2);
return;
}
void main(void)
{

SetVect(6,ADC);
SwitchDAC(1,1);
InitDAC(0);
SetVoltage(1,1);

ADCCON1=0x00;
DMAL=0;
DMAH=0;
DMAP=0;

for(xdatPtr=0;xdatPtr<=0x000d;xdatPtr++)
{
*xdatPtr=0x0000;
}
xdatPtr=0x000e;*xdatPtr=0xf000;
WriteMax(0x7,4);
ADCCON2=0x40; //как только запускаем ПДП, сразу происходит перезагрузка. Если команду убрать, все нормально работает
ADCCON1=0x64;
EA=1;
EADC=1;
CCONV=1;
WriteMax(0x7,3);

while (1)
{
if (flag!=0) {WriteMax(0x7,1);}
}

}
AnopT
 
Сообщения: 5
Зарегистрирован: 25 ноя 2009, 18:55

Re: помогите плиз с adc в dma режиме

Сообщение DinKa » 28 ноя 2009, 21:51

Не так скорее всего то, что Вы загружаете свою программу во внешнюю память SRAM. Как уже было написано ранее, так работать не будет, а будет перезагружаться - это Вы и видите. Может быть я ошибаюсь, но никаких данных помимо кода Вы не предоставили: куда Вы шьете свою программу, при помощи чего, какие настройки компилятора, линкера используете и т.д. Вот тут подготовился пример по работе АЦП в режиме ПДП, но он не совсем проверен, так как под рукой стенда SDK-1.1 не оказалось, а был только Keil с симулятором. Поэтому могут быть ошибки. Получаемый в результате сборки проекта загрузочный модуль необходимо шить во Flash микроконтроллера ADuC812 при помощи программатора dl.exe. Для этого Вам понадобится джампер, com-порт и коммуникационный кабель RS-232 (инструкция по использованию dl.exe в архиве).
TEST_ADC_DMA_SDK_1_1-1.0.0-0-w.tar.gz
Пример работы АЦП в режиме ПДП + ЦАП
(43.29 Кб) Скачиваний: 528
DinKa
 
Сообщения: 247
Зарегистрирован: 23 апр 2008, 18:01

Re: помогите плиз с adc в dma режиме

Сообщение AnopT » 29 ноя 2009, 11:44

Ладно, хорошо. Спасибо за ответ. Проверю...
AnopT
 
Сообщения: 5
Зарегистрирован: 25 ноя 2009, 18:55

Re: помогите плиз с adc в dma режиме

Сообщение DinKa » 30 ноя 2009, 16:35

Исправленная версия теста АЦП в режиме ПДП + ЦАП.
TEST_ADC_DMA_SDK_1_1-1.0.1-0-w.tar.gz
Пример работы АЦП в режиме ПДП + ЦАП (версия 1.0.1)
(43.16 Кб) Скачиваний: 528
DinKa
 
Сообщения: 247
Зарегистрирован: 23 апр 2008, 18:01

Re: помогите плиз с adc в dma режиме

Сообщение AnopT » 02 дек 2009, 19:26

возникла новая проблема: результат ПДП преобразования не корректный.

Алгоритм действий таков:
Сперва включаем перемычку для замыкания каналов ЦАП и АЦП.
Инициализируем нулевой канал ЦАП(с выбором диапазона ЦАП0 до 2.5В, т.е. DACCON = 0x00) и подаем на него некое значение:
znach=0;
SwitchDAC(0,1);
InitDAC(0);
while (1)
{
SetVoltage(znach,0);
...
}

АЦП инициализируется следующим образом:
void InitADC(void)
{
unsigned int *xdatPtr;
ADCCON1=0x00;
DMAL=0;
DMAH=0;
DMAP=0;

for(xdatPtr=0x0000;xdatPtr<=0x0009;xdatPtr++)
{
*xdatPtr=0x0000;
}
xdatPtr=0x000A;*xdatPtr=0x0f000;
ADCCON2=0x40;
ADCCON1=0xA4;
EA=1;
EADC=1;
CCONV=1;
}

После срабатывания прерывания, сбрасываем флаг ADCI и обрабатываем результат(с использованием стандартных примеров от ЛМТ):
xdata unsigned char *point_L=0x0001;
xdata unsigned char *point_H=0x0000;
...
DPP=0;
znach_ADC_H=*point_H;
znach_ADC_L=*point_H;
v = ((unsigned short)(znach_ADC_H & 0xF) << 8) | znach_ADC_L; //преобразование напряжения по типу функции GetVoltage
v = v * 5.0 / 0xFFF;
LCD_Clear(); //очистка ЖКИ
zzz=(int)(v*200);
LCD_Putch(zzz/100+48); //вывод на экран ЖКИ с учетом таблицы символов
zzz=zzz%100;
LCD_Putch('.');
LCD_Putch(zzz/10+48);
zzz=zzz%10;
LCD_Putch(zzz+48);

В итоге, если мы изменяем значение устанавливаемое на ЦАП (в пределах 2.5), то в качестве преобразования АЦП мы получаем разные значения (порядка 3-х или 4-х разных значений). Причем пугает то, что изменяются в произвольном порядке старшие 4 бита по адресу 0x0000, хотя в описании aduc812 написано, что биты во внешней памяти отвечающие за выбор каналов не меняются. Еще странно то, что если прочитать адреса 0x0002 и 0x0003 и сравнить их соответственно с адресами 0x0000 и 0x0001, то они будут разные.
AnopT
 
Сообщения: 5
Зарегистрирован: 25 ноя 2009, 18:55

Re: помогите плиз с adc в dma режиме

Сообщение DinKa » 03 дек 2009, 01:14

AnopT писал(а):возникла новая проблема: результат ПДП преобразования не корректный.

После срабатывания прерывания, сбрасываем флаг ADCI и обрабатываем результат(с использованием стандартных примеров от ЛМТ):
xdata unsigned char *point_L=0x0001;
xdata unsigned char *point_H=0x0000;
...
DPP=0;
znach_ADC_H=*point_H;
znach_ADC_L=*point_H;

v = ((unsigned short)(znach_ADC_H & 0xF) << 8) | znach_ADC_L; //преобразование напряжения по типу функции GetVoltage

В выделенной части кода опечатка, т.е. должно быть, наверное:
Код: Выделить всё
znach_ADC_H=*point_H;
znach_ADC_L=*point_L;

Какой тип данных у znach_ADC_L и znach_ADC_H? Если int/short, то порядок байтов несколько иной, поэтому старший и младший байт нужно поменять местами, тогда все получится.
Приведенный выше пример работает? Посмотрите, как там сделано.

AnopT писал(а):v = v * 5.0 / 0xFFF;

Наверное, нужно умножать на 2.5 В, а не на 5 В.

Пожалуйста, в случае приведения исходного кода используйте теги [сode]Ваш код[/сode] и выравнивание, а то сложно читать. :)
DinKa
 
Сообщения: 247
Зарегистрирован: 23 апр 2008, 18:01

Re: помогите плиз с adc в dma режиме

Сообщение AnopT » 03 дек 2009, 16:36

Вопросов больше не имею.
Спасибо большое за ответы и рабочий пример.
AnopT
 
Сообщения: 5
Зарегистрирован: 25 ноя 2009, 18:55


Вернуться в SDK 1.1

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

cron