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

 
 
 
Reply to this topicStart new topic
> ADC в PIC16F887 (HiTech C), Не могу получить результаты АЦП
dccharacter
сообщение Jul 3 2009, 11:38
Сообщение #1





Группа: Участник
Сообщений: 6
Регистрация: 23-06-09
Пользователь №: 50 568



Пытаюсь портировать простенький урок из набора "44-pin demoboard" на С, ничегошеньки не получается. Пытаюсь отлаживать - и Proteus и MPLab SIM после возникновения первого прерывания по таймеру0 уходят в обработчик прерывания и там и сидят (в тело main не возвращаются). Байты результатов преобразования - пустые. Сломал голову, научите, пожалуйста. Листинг:

Код
#include <pic.h>
#define _XTAL_FREQ 20000000

__CONFIG (INTIO & WDTDIS & PWRTEN & MCLRDIS & BOREN & LVPDIS & UNPROTECT);

struct adc_result
    {
    int value;         // ADC built-in functions default to 8 bit result.
    int new_flag;      // 1-bit falg to indicate a new (fresh) value
    } adc_conversion;

void init_io()
{
    // set up PORTA so RA0 is an input for the ADC, RA1-RA7 are outputs
    TRISA = 0xFF;   // bit 0 = output, 1 = input
    
    // set up PORTB so RB0 is an input for the switch SW1, RB1-RB7 are outputs
    TRISB = 0x00;   // bit 0 = output, 1 = input

    // set up remaining ports to be all outputs
    PORTC = 0x00;
    PORTD = 0x00;
    PORTE = 0x00;
    ANSEL = 0xFF;

    T0CS = 0;
    PSA = 0;
    PS0 = PS1 = PS2 = 1;
    T0IE = 1;    //enable timer0 int
    GIE  = 1;    //enable ints (global)
}

void init_adc()
{

//ADC setup
ADCON1 = 0b10000000; // bit7 = ADFM, set to 0 - left justified;
//bit 4-5 - reference voltage select, 00s are VDD and VSS

ADCON0 = 0b01000001; //ADCS1:0 = 01, Fosc/8; CHS5:2 = 0000, select AN0; GO = 1; ADON = 1;


GODONE = 1;    
}


// This function will be called on a Timer0 interrupt
void interrupt int_rtcc ()
{
    // channel is always set to AN0.  Otherwise we might change
    // it here
    
    // Get last conversion result.
    adc_conversion.value = ADRESH;
    adc_conversion.new_flag = 1;    // new value
    
    // start next conversion
    GODONE= 1;
/*PORTD = ~PORTD;
__delay_ms(150);*/
}

void main (void)
{
    int led_bar_right = 0; // default is led bar graph starting on the left (DS0)  
    int switch_count = 0;   // used for debouncing the switch
    int bars = 0;           // used to compute the number of LED "bars" to display
    int temp1 = 0;          // temporary working variable
    int led_display = 0;    // led display value

    // initialize global variables
    adc_conversion.value = 0;
    adc_conversion.new_flag = 0;


    // Set up MCU
    init_io();
    init_adc();
        // Timer 0 runs off internal clock with 1:256 prescaler
        // This means it should run over every ((256*256)/(4MHz/4)) = 65.5ms
        // It will be used to start an ADC conversion.
    
while(1)
    {
        // look for a new conversion result
        __delay_us(5);
        if (1)
        {
            bars = adc_conversion.value;
            adc_conversion.new_flag = 0;        // reset flag
            // We'll use the 3 most significant bits of the conversion result
            // to determine whether to display 1 to 8 "bars" on the LED display
            bars = (bars >> 5) + 1; // add one to make it 1 to 8 (vs 0 to 7)
            led_display = 0; // clear display variable
            for (temp1 = 0; temp1 < bars; temp1++)
            {
                // shift in a '1' for each bar
                led_display = (led_display << 1) + 1;
            }
        }

        // check for a switch press & debounce
        if (RB0 == 0)
        { // switch is low when pressed
            if (switch_count < 8)
            { // increment the count on all consecutive checks where switch is pressed
              // to a max of 8
                switch_count ++;
                // if we've seen 8 consecutive checks where the switch is pressed
                // it's considered a valid switch press.  Reverse the bar graph
                if (switch_count == 8)
                {
                    led_bar_right = ~led_bar_right;
                }
            }
        }
        else
        { // anytime switch is detected as not pressed, reset the count
            switch_count = 0;
        }


        // update display
        if (led_bar_right == 0)
        {  // from left
           PORTD = led_display;
        }
        else
        { // from right
            // we have to shift it so it displays 1-8 bars.  Just complementing
            // would display 0-7.
            PORTD =  ~(led_display >> 1);
        }

    }

/*

while (1)
    {
    if (GODONE == 0)
        {
        PORTD = 0;
        for ( int i=0; i= (ADRESH >> 5); i++)
            {
            PORTD = ( PORTD << 1 ) + 1;
            }
        GODONE = 1;
        }
    } */

}


И "заодно" вопросик - какой смысл в этом примере использовать прерывание? Почему не запускать новое преобразование по окончанию предыдущего (ну понятно, со всеми задержками необходимыми)?
Go to the top of the page
 
+Quote Post
asp
сообщение Jul 3 2009, 15:58
Сообщение #2


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

Группа: Validating
Сообщений: 103
Регистрация: 4-07-05
Пользователь №: 6 490



У Вас не получается в эмуляторах или железе?
В железе все прекрасно работает, дорабатывал вывод через usart, проблем небыло.
Go to the top of the page
 
+Quote Post
dccharacter
сообщение Jul 3 2009, 17:58
Сообщение #3





Группа: Участник
Сообщений: 6
Регистрация: 23-06-09
Пользователь №: 50 568



Цитата(asp @ Jul 3 2009, 19:58) *
У Вас не получается в эмуляторах или железе?
В железе все прекрасно работает, дорабатывал вывод через usart, проблем небыло.

Хм, ни там ни там не выходит. Причем прерывание срабатывает ОК, а вот такое чувство что я неправильно включаю АЦП. Еще смущает то, что в русском даташите на 887 нет такой вещи как ANSEL совсем - но я на всякий случай добавил, все равно не помогло. Сейчас попробую тоже через УАРТ посмотреть что там.

Цитата(dccharacter @ Jul 3 2009, 20:52) *
Хм, ни там ни там не выходит. Причем прерывание срабатывает ОК, а вот такое чувство что я неправильно включаю АЦП. Еще смущает то, что в русском даташите на 887 нет такой вещи как ANSEL совсем - но я на всякий случай добавил, все равно не помогло. Сейчас попробую тоже через УАРТ посмотреть что там.

Хм, похоже у меня вотчдог стреляет. Странно, он отключен. Пошел опять даташит курить.

Цитата(dccharacter @ Jul 3 2009, 21:00) *
Хм, ни там ни там не выходит. Причем прерывание срабатывает ОК, а вот такое чувство что я неправильно включаю АЦП. Еще смущает то, что в русском даташите на 887 нет такой вещи как ANSEL совсем - но я на всякий случай добавил, все равно не помогло. Сейчас попробую тоже через УАРТ посмотреть что там.


Хм, похоже у меня вотчдог стреляет. Странно, он отключен. Пошел опять даташит курить.

Не понимаю В симуляции МК ресеттится вотчдогом. Вотчдого отключен в конфиге. SWDTEN нигде не установлен. Бред.
Go to the top of the page
 
+Quote Post
Herz
сообщение Jul 3 2009, 19:50
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 10 983
Регистрация: 23-11-05
Пользователь №: 11 287



Тихо сам с собою...
Go to the top of the page
 
+Quote Post
testerplus
сообщение Jul 3 2009, 20:38
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 54
Регистрация: 7-08-08
Из: SPb
Пользователь №: 39 471



Цитата(dccharacter @ Jul 3 2009, 15:38) *
Пытаюсь портировать простенький урок из набора "44-pin demoboard" на С, ничегошеньки не получается. Пытаюсь отлаживать - и Proteus и MPLab SIM после возникновения первого прерывания по таймеру0 уходят в обработчик прерывания и там и сидят (в тело main не возвращаются).


Добавь в прерывание:
Код
   T0IF = 0;
Go to the top of the page
 
+Quote Post
dccharacter
сообщение Jul 3 2009, 20:53
Сообщение #6





Группа: Участник
Сообщений: 6
Регистрация: 23-06-09
Пользователь №: 50 568



Цитата(testerplus @ Jul 4 2009, 00:38) *
Добавь в прерывание:
Код
   T0IF = 0;

Нет, не помогло. Причем в какой-то момент у меня железный сетап перестал в прерывание входить.

йолки, тот же алгоритм на CCS - работает. А на хи-тек не допру как сделать.
Go to the top of the page
 
+Quote Post
xemul
сообщение Jul 3 2009, 21:27
Сообщение #7



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(dccharacter @ Jul 4 2009, 00:53) *
йолки, тот же алгоритм на CCS - работает. А на хи-тек не допру как сделать.

Видимо, пользуете ломаную ПРО версию. Попробуйте СТД или займитесь проверкой ассемблерного листинга на соответствие сишному коду.
Go to the top of the page
 
+Quote Post
dccharacter
сообщение Jul 3 2009, 22:22
Сообщение #8





Группа: Участник
Сообщений: 6
Регистрация: 23-06-09
Пользователь №: 50 568



Цитата(xemul @ Jul 4 2009, 01:27) *
Видимо, пользуете ломаную ПРО версию. Попробуйте СТД или займитесь проверкой ассемблерного листинга на соответствие сишному коду.

Переписал с нуля по-своему, заработало. Так и не понял, что это было.
Всем спасибо.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st June 2025 - 19:59
Рейтинг@Mail.ru


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