|
SAM7 ADC. не запускается прерывание по окончании преобразования, AT91SAM7S256, надо запустить прерывание по окончанию преобразования AD |
|
|
|
Nov 23 2007, 14:51
|

Группа: Новичок
Сообщений: 8
Регистрация: 30-10-07
Из: Петрозаводск
Пользователь №: 31 873

|
Поскольку опыт программирования МК-ров у меня на данный момент очень мал, и никакой сверхзадачи данная проблема не представляет - почти уверен, что я не учел какую-то банальную вещь. Итак, не удается запустить на плате с at91sam7s256 прерывание по окончанию преобразования ADC. Везде в сети встречаю примеры наподобие такой работы с АЦП: Код AT91F_ADC_StartConversion (AT91C_BASE_ADC); //старт преобразования while (!((AT91F_ADC_GetStatus (AT91C_BASE_ADC)) & (1<<AT91C_ADC_CH0))); //подождать, пока преобразуется AT91F_ADC_GetConvertedDataCH0; //закончилось преобразование - получить данные в таком варианте работает - стартует, преобразует, получает данные. Но, надо по нормальному сделать так: Код .... AT91F_ADC_StartConversion (AT91C_BASE_ADC); // вызов преобразования откуда-то из глубин кода .... void ADC_interrupt_handler(void){ //прерывание, вызываемое по окончанию преобразования АЦП var = AT91F_ADC_GetConvertedDataCH4 (pADC); } мой код: Код void Init_ADC(){ //Инициализация Ацп pADC= AT91C_BASE_ADC; AT91F_ADC_SoftReset(pADC); //AT91F_ADC_CfgPIO(); //может это и не надо? - с ним, без него пробовал AT91F_ADC_CfgPMC();// это то же, что и AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_ADC ); //заводим АЦП AT91F_ADC_CfgModeReg(AT91C_BASE_ADC,ADC_Mode); //с этими установками AT91F_ADC_DisableChannel(pADC, 255); //деактивация всех каналов ADC AT91F_ADC_EnableChannel(pADC, ADCCH_Use); //активация нужных нам каналов ADC
AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_ADC, ADC_INTERRUPT_LEVEL, AT91C_AIC_SRCTYPE_POSITIVE_EDGE, ADC_interrupt_handler); AT91F_ADC_EnableIt(pADC,ADCCH_Use); //активизируем прерывание по окончании преобразования нужных каналов каналов AT91F_ADC_StartConversion(pADC); } /* примечание - ADC_Mode определяется так: TRGEN (0x0) // Software triggering TRGSEL (0x0) // Without effect LOWRES (0x0) // 10-bit result output SLEEP (0x0) // Normal Mode mck_clock 48 // in MHz adc_clock 5 // in MHz startup_time 21 // in us sample_and_hold_time 800 //700 in ns PRESCAL ((unsigned int) mck_clock/(2*adc_clock) - 1) STARTUP ((unsigned int) adc_clock*startup_time/8 - 1) SHTIM ((unsigned int) adc_clock*sample_and_hold_time/1000 - 1) //(0x3)
ADC_Mode ((SHTIM << 24) | (STARTUP << 16) | (PRESCAL << 8) | (SLEEP << 5) | (LOWRES <<4) | (TRGSEL << 1) | (TRGEN )) */
void ADC_interrupt_handler(void){ //не вызывается!!! //здесь некоторые действия, кои должен совершить, и я сразу увидеть, что попалъ сюда } пробую пока только на одном ADC (4)
--------------------
~Venerium Rerum Omnium~
|
|
|
|
|
 |
Ответов
(1 - 5)
|
Nov 23 2007, 18:23
|

Группа: Новичок
Сообщений: 8
Регистрация: 30-10-07
Из: Петрозаводск
Пользователь №: 31 873

|
Цитата(Сергей Борщ @ Nov 23 2007, 17:59)  Глобально прерывания разрешаете? другие прерывания происходят (usart, timer), значит глобально разрешено. ... или тут есть другое глобальное разрешение?)) **чесстно, даже не удобно спрашивать такую банальщину на форуме, где все реально продвинутей меня по теме
--------------------
~Venerium Rerum Omnium~
|
|
|
|
|
Nov 29 2007, 06:40
|

Группа: Новичок
Сообщений: 8
Регистрация: 30-10-07
Из: Петрозаводск
Пользователь №: 31 873

|
нашел ошибку, но что-то забыл отписаться здесь, а вдруг кто еще такое будет искать  ? вот моя .. кажется конечная организация работы с АЦП на AT91SAM7S256 *да, до этого упустил "AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_ADC)" Код void Init_ADC(){ //Инициализация АЦП pADC= AT91C_BASE_ADC; //используемый adc AT91F_ADC_SoftReset(pADC); AT91F_ADC_CfgPMC();//AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_ADC ); //заводим АЦП AT91F_ADC_CfgModeReg(AT91C_BASE_ADC,ADC_Mode); //с этими установками AT91F_ADC_DisableChannel(pADC, 0xff); //деактивация всех каналов ADC AT91F_ADC_EnableChannel(pADC, ADCCH_Use); //активация нужных нам каналов ADC AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_ADC, ADC_INTERRUPT_LEVEL, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, ADC_interrupt_handler); AT91F_ADC_EnableIt(pADC,ADCCH_Use); //активизируем прерывание по окончании преобразования нужных каналов AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_ADC); //теперь АЦП готов, для запуска преобразования вызвать AT91F_ADC_StartConversion(pADC); } void ADC_interrupt_handler(void){ //обработка прерывания, вызываемая по окончанию преобразования АЦП myvar = AT91F_ADC_GetConvertedDataCH4(pADC); //AT91F_ADC_StartConversion(pADC); //постоянно преобразовывать, зациклить } только вот, появлялась еще такая проблема - если запускать преобразование сразу после завершения (зациклить), то это видимо занимает много машинного времени)): если приоритет таймера ниже ацп - таймер "медленнее" работает, если же наоборот или равны - ацп не работает почти --- решил это только тем, что стартую преобразование ацп из таймера, из расчета примерно каждую 1мс, и приоритет ацп выше .... странно, как это у меня на ATMega8 получалось без таких заморочек?  ) .. здесь вроде МК сильнее).
--------------------
~Venerium Rerum Omnium~
|
|
|
|
|
Nov 29 2007, 12:06
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(vdik @ Nov 29 2007, 08:40)  если запускать преобразование сразу после завершения (зациклить), то это видимо занимает много машинного времени)): Приводите код. Откуда там затраты времени возьмутся? Цитата(vdik @ Nov 29 2007, 08:40)  если приоритет таймера ниже ацп - таймер "медленнее" работает, если же наоборот или равны - ацп не работает почти Брр... Показывайте оба обработчика - где-то намудрили. А еще запускать АЦП можно прямо выходом таймера TC, а данные от него принимать через PDC - будет вообще без прерываний (ну или одно прерывание PDC - подсунуть новый буфер).
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 30 2007, 07:28
|

Группа: Новичок
Сообщений: 8
Регистрация: 30-10-07
Из: Петрозаводск
Пользователь №: 31 873

|
Цитата(Сергей Борщ @ Nov 29 2007, 15:06)  Приводите код. Откуда там затраты времени возьмутся? Брр... Показывайте оба обработчика - где-то намудрили. и это не мудрено что намудрил))) ... надо б мне теорию МК чтоль серьезно поучить. Присоединяю модуль с таймером, как он есть. Взял его из проекта "AT91SAM7S-Interrupt_SAM7S" с сайта at91.com; своего добалено в нем совсем чуть-чуть, изменен приоритет таймера, отключен таймер1. Обработчик ацп .. впринципе, он уже в предыдущих сообщениях, но ладно, тоже присоединю, но там уже больше отсебятины)) *** таймер реально работает медленнее (реже выполняются действия) -- если включено "ADC_StartConversion" не в таймере, а в прерывании ацп. ..... вот ... подумал тут))) .. в том же проекте есть пример организации других прерываний, заложены в модуле "main.c" (тоже прикреплю его, только не свой, а с оригинального объекта) -- там они с начала main до вызова "timer_init" - без этого всё работает, я у себя сие отключил, решив, что там лишь настраиваются дополнительные прерывания, которые мне не нужны. Вот здесь быть может я ошибся! (строчку ниже "AT91F_AIC_Trig(pAic,AT91C_ID_SYS);// generate software interrupt" -- тоже отключил) **мда .. получается, что сейчас я предлагаю копаться в чужом коде,,, мрак Цитата(Сергей Борщ @ Nov 29 2007, 15:06)  А еще запускать АЦП можно прямо выходом таймера TC, а данные от него принимать через PDC - будет вообще без прерываний (ну или одно прерывание PDC - подсунуть новый буфер). вот это сейчас я вобще слабо представляю как))
--------------------
~Venerium Rerum Omnium~
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|