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

 
 
 
Reply to this topicStart new topic
> Пожалуйста. найдите ошибку!
Timofey
сообщение Aug 2 2006, 04:16
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Здраствуйте.
У меня вобщем такая проблема: мне нужно опрашивать АЦП (АЦП цифрует сигнал синусоидальный частотой предпологается 50 Гц) каждые 100 мкс (такие требования). Там используются 8 сигналов, то есть за 100 мкс я должен оцифровать по одному значению из кадждого канала. Я использую периодический таймер, выставил при конфигурировании 12.5 мкс на один канал. На АЦП посылается запрос из массива SPI_SEND одно 16-битное значение с указаниями АЦП а возвращается: перве четыре бита - адрес канала. остальные 12 - значение. Причем там хитро все сделано, поэтому я посылаю одно и то же значение 3 раза. чтобы получить значение канала адрес которого отсылаю сейчас. Получив из принимающего регистра значение. я избавляюсь от адреса канала и потом анализирую его. Мне нужно найти максимальное значения положительного полупериода и отрицательного а потом из них найти большее и записать в регистр (ну массив данных). Так вот, проблема такая: Поначалу у меня не проверялось условие shet_i>255. то есть вобще не заходилось в это условие. А сейчас в течении долей секунд лампочка мигает на проверке rt==7 и перетает, повисает видимо где то ... но она тухнет. Подскажет пожалуйста где у меня корявость. а то всю ночь уже гружусь ...
З.Ы. И просьба, проверьте пожалуйста, правильно ли я инициализировал SPI и таймер. На SPI сейчас висит только АЦП но предполагается еще и наличие флэшки, возможно даже двух.





Сама программа:

#define RTTC_INTERRUPT_LEVEL 0
#define PIV_2_MS 37 //примерно 12.5 мкс
max_data[8]; // массив максимальных значений для 8-ми каналов
shet_i=0; // счетчик данных для массива DATA, если счетчик равен 255 то выполняться должно преобразование фурье и потом четчик сбрасывается на ноль, чтобы заполнять массв новыми данными

//массив регистров
char BUFF_STATUS[200]={0x00,0x01, 0x00,0xFF, 0x00,0x00, 0x00,0x00, 0x00,0x00, //Область А и B
0x05,0x01, 0x05,0x01, 0x00,0x00, 0x06,0x07, 0x08,0x09,
0x00,0x01, 0x02,0x03, 0x04,0x05, 0x06,0x07, 0x08,0x09,
0x00,0x01, 0x02,0x03, 0x04,0x05, 0x06,0x07, 0x08,0x09,
0x00,0x01, 0x02,0x03, 0x04,0x05, 0x06,0x07, 0x08,0x09,
0x00,0x01, 0x02,0x03, 0x04,0x05, 0x06,0x07, 0x08,0x09,
0x00,0x01, 0x02,0x03,

0x17,0x22, 0x12,0x02, 0x44,0x44, 0x44,0x44, 0x08,0x09, //C & D
0x00,0x01, 0x02,0x03, 0x04,0x05, 0x06,0x07, 0x08,0x09,
0x00,0x01, 0x02,0x03, 0x04,0x05, 0x06,0x07, 0x08,0x09,
0x00,0x01, 0x02,0x03, 0x04,0x05, 0x06,0x07, 0x08,0x09,
0x00,0x01, 0x02,0x03, 0x04,0x05, 0x06,0x07, 0x08,0x09,
0x00,0x01, 0x02,0x03, 0x04,0x05, 0x06,0x07, 0x08,0x09,
0x00,0x01, 0x02,0x03 };

int DATA[512][8]; //массив принятых данных, сюда предполагается запись значений принятых независимо от найденнного максимума, чтобы потом работать с преобразованием Фурье
int SPI_SEND[16]=0x8350,0x8750,0x8850,0x8F50,0x9350,0x9750,0x9B50,0x9F50,0xA350,0xA7
50,0xAB50,0xAF50};


///////////////////////////////////////////
////////Прерывание таймераTC1///////////
///////////////////////////////////////////
void Periodic_Interval_Timer_handler (void)
{
unsigned int status;


status = AT91C_BASE_PITC->PITC_PIVR;
status =status;

spiflag=1;

//AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, LED1);
//AT91F_PIO_SetOutput(AT91C_BASE_PIOA, LED1);

}


/////////////////////////////////////////////
////////Конфигурирование Timer TC1///////////
/////////////////////////////////////////////
void CnfTime1 (void)
{
//AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA ) ;
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC,
AT91C_ID_SYS,
RTTC_INTERRUPT_LEVEL,
AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE,
Periodic_Interval_Timer_handler);
AT91C_BASE_PITC->PITC_PIMR = AT91C_PITC_PITEN | AT91C_PITC_PITIEN | PIV_2_MS;
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_SYS);


}



///////////////////////////////////////
///////Конфигурирование SPI///////////
//////////////////////////////////////
void SPI(void)
{
AT91F_PIO_CfgPeriph( AT91C_BASE_PIOA,
((unsigned int)AT91C_PA11_NPCS0 ) |
((unsigned int)AT91C_PA12_MISO ) |
((unsigned int)AT91C_PA13_MOSI ) |
((unsigned int)AT91C_PA14_SPCK ) |
((unsigned int)AT91C_PA9_NPCS1 ),
((unsigned int)AT91C_PA3_NPCS3 ) |
((unsigned int)AT91C_PA30_NPCS2 ) );


AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_SPI ) ;
AT91F_SPI_Reset(AT91C_BASE_SPI);

//определяет регистр SPI_MR
AT91F_SPI_CfgMode(AT91C_BASE_SPI,
AT91C_SPI_MSTR | //мастер
AT91C_SPI_PS_FIXED | //фиксирования периферия
AT91C_SPI_MODFDIS | //Mode fault detection is disabled.
((0x00 << 24) & AT91C_SPI_DLYBCS)
);

AT91C_BASE_SPI->SPI_CR = AT91C_SPI_LASTXFER | AT91C_SPI_SPIEN;
AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER;


for(i=0;i<4;i++){
//определяет регистры SPI_CSR0... SPI_CSR3
AT91F_SPI_CfgCs(AT91C_BASE_SPI,
i,//номер регистра
AT91C_SPI_BITS_16 |//Передаем по 16 бит
((0x04 << 8) & AT91C_SPI_SCBR) | //Serial Clock Baud Rate (делитель мастер клока)
((0x01 << 24) & AT91C_SPI_DLYBCT)|
((0x10 << 16) & AT91C_SPI_DLYBS)
);
}



}



main (void)
{
*AT91C_RTTC_RTMR = BUTTON_SAMPLING;


//конфигурируем кнопки и светодиоды, порты
AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC,((unsigned int) 1 << AT91C_ID_PIOA));
AT91F_PIO_CfgInput(AT91C_BASE_PIOA, (SW1|SW2|SW3|SW4));
AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, LED_MASK);
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, LED_MASK);

CnfTime1 ();

SPI();
shet_i=0; rt=0; max_data[0]=2047;

//бесконечный цикл
while(1)
{


if (spiflag==1)
{

while (!((AT91C_BASE_SPI->SPI_SR) & AT91C_SPI_TXEMPTY));
AT91F_SPI_CfgPCS(AT91C_BASE_SPI,0);
AT91F_SPI_PutChar (AT91C_BASE_SPI, SPI_SEND[rt],0 );
while (!((AT91C_BASE_SPI->SPI_SR) & AT91C_SPI_TXEMPTY));
AT91F_SPI_CfgPCS(AT91C_BASE_SPI,0);
AT91F_SPI_PutChar (AT91C_BASE_SPI, SPI_SEND[rt],0 );
while (!((AT91C_BASE_SPI->SPI_SR) & AT91C_SPI_TXEMPTY));
AT91F_SPI_CfgPCS(AT91C_BASE_SPI,0);
AT91F_SPI_PutChar (AT91C_BASE_SPI, SPI_SEND[rt],0 );
while (!((AT91C_BASE_SPI->SPI_SR) & AT91C_SPI_TXEMPTY));
tin=AT91F_SPI_GetChar(AT91C_BASE_SPI);
DATA[shet_i][rt]=tin & 0x0FFF;
if (DATA[shet_i][rt]>max_data[rt]) max_data[rt]=DATA[shet_i][rt];
if (DATA[shet_i][rt]<min_data[rt]) min_data[rt]=DATA[shet_i][rt];
max_data[rt]=max_data[rt]-2047;
min_data[rt]=2047-min_data[rt];

if (shet_i>254) { // в это условие ну не под каким видом почему то не заходит.

AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, LED3);
if ((max_data[rt])<(min_data[rt])) max_data[rt]=min_data[rt];
BUFF_STATUS[(rt+7)*2]=max_data[rt];
BUFF_STATUS[(rt+7)*2+1]=max_data[rt] >> 8;


AT91F_PIO_SetOutput(AT91C_BASE_PIOA, LED3);
max_data[rt]=2047;
min_data[rt]=2047;
shet_i=0;}

if (rt==7){ // а здесь стал почему то очень быстро повисать, хотя раньше без проблем было
shet_i++;
rt=-1;
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, LED2);
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, LED2);
}

rt++;
spiflag=0;


}

}

}
Go to the top of the page
 
+Quote Post
Timofey
сообщение Aug 2 2006, 09:23
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Исправил программу вот так:

if (spiflag==1)
{
spiflag=0;
while (!((AT91C_BASE_SPI->SPI_SR) & AT91C_SPI_TXEMPTY));
AT91F_SPI_CfgPCS(AT91C_BASE_SPI,0);
AT91F_SPI_PutChar (AT91C_BASE_SPI, SPI_SEND[rt],0 );
while (!((AT91C_BASE_SPI->SPI_SR) & AT91C_SPI_TXEMPTY));
AT91F_SPI_CfgPCS(AT91C_BASE_SPI,0);
AT91F_SPI_PutChar (AT91C_BASE_SPI, SPI_SEND[rt],0 );
while (!((AT91C_BASE_SPI->SPI_SR) & AT91C_SPI_TXEMPTY));
AT91F_SPI_CfgPCS(AT91C_BASE_SPI,0);
AT91F_SPI_PutChar (AT91C_BASE_SPI, SPI_SEND[rt],0 );
while (!((AT91C_BASE_SPI->SPI_SR) & AT91C_SPI_TXEMPTY));
tin=AT91F_SPI_GetChar(AT91C_BASE_SPI);
DATA[shet_i][rt]=tin & 0x0FFF;
if (DATA[shet_i][rt]>max_data[rt]) max_data[rt]=DATA[shet_i][rt];
if (DATA[shet_i][rt]<min_data[rt]) min_data[rt]=DATA[shet_i][rt];
//max_data[rt]=max_data[rt]-2047; //эту и следующую строку загнал в проверку shet_i>254
//min_data[rt]=2047-min_data[rt];

if (shet_i>254) { // в это условие ну не под каким видом почему то не заходит.

AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, LED3);
max_data[rt]=max_data[rt]-2047;
min_data[rt]=2047-min_data[rt];
if ((max_data[rt])<(min_data[rt])) max_data[rt]=min_data[rt];
BUFF_STATUS[(rt+7)*2]=max_data[rt];
BUFF_STATUS[(rt+7)*2+1]=max_data[rt] >> 8;
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, LED3);
max_data[rt]=2047;
min_data[rt]=2047;
//тут я исправляю следующую строчку (потому как требуется находить максимум у 8 каналов, забыл про эту провперку)
if (rt==7) shet_i=0; // об этой строчке чуть ниже
}

if (rt==7){
shet_i++;
rt=-1;
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, LED2);
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, LED2);
}

rt++;



}

}

}


spiflag=0 я переместил вверх, теперь она стала работаь без проблем, НО! если ставлю вот это условие if (rt==7) shet_i=0; начинает как то странно мигать лампочками, глючить и тп ... убирая эту строчку - все нормально .. то есть просто отсавляю shet_i=0;
Даже модбас без этой строчки работает, то есть опрашивает ....
Вобщем запутался я ... Что не так??
Go to the top of the page
 
+Quote Post
gmax
сообщение Aug 3 2006, 07:21
Сообщение #3


Участник
*

Группа: Свой
Сообщений: 55
Регистрация: 25-08-05
Из: Украина, Харьков
Пользователь №: 7 954



Вы сами пробовали прочитать, то что написали?
С удовольствием помог бы разобраться, если бы понял, что вам нужно делать!

Попробуйте (без лишней информации) ответить на следующие вопросы:
1. Что нужно (например: оцифровывать 8 фаналоговых сигналов с помощью внешнего АЦП, который висит на SPI. После получения n отсчетов всех 8 сигналов нужно сделать то-то и то-то. И т.д.)?
2. Что вы пытаетесь сделать (сначала я инициализирую SPI, таймер и т.д. Потом в цикле опрашиваю...)?
3. Что не получается?

И дайте переменным нормальные осмысленные названия
Go to the top of the page
 
+Quote Post
Timofey
сообщение Aug 4 2006, 10:10
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Цитата(gmax @ Aug 3 2006, 13:21) *
Вы сами пробовали прочитать, то что написали?
С удовольствием помог бы разобраться, если бы понял, что вам нужно делать!

Попробуйте (без лишней информации) ответить на следующие вопросы:
1. Что нужно (например: оцифровывать 8 фаналоговых сигналов с помощью внешнего АЦП, который висит на SPI. После получения n отсчетов всех 8 сигналов нужно сделать то-то и то-то. И т.д.)?
2. Что вы пытаетесь сделать (сначала я инициализирую SPI, таймер и т.д. Потом в цикле опрашиваю...)?
3. Что не получается?

И дайте переменным нормальные осмысленные названия

Да все уже. спасибо, разобрался сам. Но попробую сформулировать ))

1. Нужно оцифровывать 8 аналоговых сигналов с помощью внешнего АЦП, висящего на SPI/ После получения всех 8 точек (по точке с канала) нужно проверить, не превышают ли они определенного максимаьного значения. После накопления 256 точек на каждый канал, нужно провести преобразование фурье по каждому каналу. Накопление одной партии (по одной точки со всех каналов) должно происходить 1 раз в 100 мкс.
2. Нуууу .....
- инициализирую кнопки на плате и диоды, диоды тушу;
- конфигурирую переодический таймер и включаю его на прерывание (каждые 12,5 мкс устанавливается флаг spiflag=1)$
-конфигурирую SPI и запускаю его, без прерываний.

- ухожу в бесконечный цикл, где
проверяю не выставлен ли флаг spiflag, если да, то провожу опрос АЦП и обработку данных, если нет, то просто продолжаю дальше вертется в бесконечном цикле

Обработка происходит следующим образом: Сначала сбрасываю флаг spiflag в ноль.
Чтобы получить результат с нужного канала АЦП, мне необходимо отправить трижды запрос с номером канала и определенными там параметрами (геморойно, но АЦП выбирал не я, а более простое решение у меня не получается). Проверяю не выходит ли полученное значение за максимальные рамки (max_data[rt]) сделанно как массив, потому что нужно проверять у каждого канала. Затем увеличиваю rt и выхожу изз проверки. При достижении rt=7 должно получится, что у меня опрошены все 8 каналов и в условии я сбрасываю rt на начальный канал и увеличиваю счетчик данных. Этот счетчки (shet_i) должен увеличиваться 1 раз в 100 мксек. При накоплении 256 точек со всех каналов, я записываю полученные максимальные значения со всех 8 каналов в обпределенные места массива и сбрасиываю счетчик данных (shet_i) на ноль.

Вроде бы все ....
Я извиняюсь, но так уж получилось, я привык к этим и если заменю, начну сам путаться. Прошу прощения. Понимаю что не красиво, но мне так удобнее. sad.gif


3. Не получалось то, что он зависал и все .... причем непонятно где: диод, показывающий что программа заходит в тело условия rt==7 не горел, а диод условия rt>254 горит, причем не ярко так, слегка тускло, как будто только то условие обходится стороной и все.
Go to the top of the page
 
+Quote Post

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

 


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


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