В PIC12F675 не работают аналоговые операции с данными, нет даже реакции на выводах GPIO

Эти аналоговые данные считываются, и на 7-сегментном дисплее с общим анодом отображается число 1–5 с числом 7447, но я не могу установить это число для аналогового значения, потому что не могу отображать аналоговые значения или выходные данные. Я написал этот код в MPLAB. Х IDE.

#include <xc.h>

#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // GP3/MCLR pin function select (GP3/MCLR pin function is MCLR)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF   

#define _XTAL_FREQ 4000000
#define HIGH 1
#define LOW 0

unsigned int adc_value=0;

void main(void) {
    TRISIObits.TRISIO0 = 1;
    TRISIObits.TRISIO1 = 0;
    TRISIObits.TRISIO2 = 0;
    TRISIObits.TRISIO4 = 0;
    TRISIObits.TRISIO5 = 0;
    
    ANSELbits.ADCS2 = 0;
    ANSELbits.ADCS1 = 0;
    ANSELbits.ADCS0 = 0;
    ANSELbits.ANS0 = 1;
    
    ADCON0bits.CHS0 = 0;
    ADCON0bits.CHS1 = 0;
    ADCON0bits.ADON = 1;
    ADCON0bits.GO = 1;
    ADCON0bits.ADFM = 1;

    while(1) {
        ADON = 1;
        GO_DONE = 1;
        while(GO_DONE);
        adc_value = (((unsigned int) ADRESH << 8) + ADRESL);
        ADON = 0;
        if (adc_value >= 0 && adc_value <= 200) {
            GP4 = 0;
            GP5 = 0;
            GP2 = 0;
            GP1 = 0;
        } else if (adc_value > 200 && adc_value <= 400) {
            GP4 = 0;
            GP5 = 0;
            GP2 = 0;
            GP1 = 1;
        } else if (adc_value > 400 && adc_value <= 600) {
            TRISIObits.TRISIO4 = 0;
            TRISIObits.TRISIO5 = 0;
            TRISIObits.TRISIO2 = 1;
            TRISIObits.TRISIO1 = 0;
        } else if (adc_value > 600 && adc_value <= 800) {
            TRISIObits.TRISIO4 = 0;
            TRISIObits.TRISIO5 = 0;
            TRISIObits.TRISIO2 = 1;
            TRISIObits.TRISIO1 = 1;
        } else if (adc_value > 800 && adc_value <= 1023) {
            TRISIObits.TRISIO4 = 0;
            TRISIObits.TRISIO5 = 1;
            TRISIObits.TRISIO2 = 0;
            TRISIObits.TRISIO1 = 0;
        } else {
            TRISIObits.TRISIO4 = 1;
            TRISIObits.TRISIO5 = 1;
            TRISIObits.TRISIO2 = 1;
            TRISIObits.TRISIO1 = 1;
        }
        __delay_ms(100);
    }
    return;
}

Моя цель в этом проекте — напечатать число от 0 до 5 на 7-сегментном дисплее с общим анодом в соответствии с аналоговыми данными от 0 до 1023, но я не смог решить эту проблему.

Вы утверждаете, что аналоговые операции не работают. Как вы убедились, что ваша проблема не в части GPIO, связанной со светодиодами? Вы делали какую-нибудь отладку? Вы когда-нибудь переступали эту черту while(GO_DONE);? Предположим, что GO_DONE — это какой-то аппаратный флаг, который меняется в какой-то момент времени. Если заменить adcres на простой счётчик, отображение изменится корректно?

Gerhardh 24.07.2024 18:26

Я не знаю, что микро, но использование разных методов (GP4 = 0; и TRISIObits.TRISIO4 = 0;) для доступа к контактам вашего чипа U2 выглядит очень странно.

Gerhardh 24.07.2024 18:28

«пока (GO_DONE);» Даже когда удаляю эту строку, ситуация та же самая, добавлял и удалял, пробовал много функций, ситуация та же самая

CrazyProgrammer 24.07.2024 18:30

@Gerhardh Я попробовал, чтобы посмотреть, какой метод активирует эти контакты.

CrazyProgrammer 24.07.2024 18:31

Это означает, что вы не знаете, можете ли вы получить доступ к контактам? Итак, вы не знаете, есть ли у вас проблемы с чтением аналоговых данных или с настройкой пинов, верно? Опять же, что будет, если убрать while(GO_DONE) и просто посчитать adc_value. Не пытайтесь решить две разные задачи одновременно. Прежде чем пытаться считать значения, убедитесь, что ваш дисплей находится под контролем.

Gerhardh 24.07.2024 19:54

@Gerhard Теперь я могу получить доступ к контактам, но он не дает правильный номер, что бы я ни делал, он дает номера 6 и 7.

CrazyProgrammer 25.07.2024 08:30
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
67
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы не настроили GPIO<1:5> как цифровые вводы-выводы. Вот почему вы не можете их контролировать. Согласно паспорту устройства, их необходимо настроить с помощью регистров CMCON и ANSEL.

Отключите аналоговые компараторы

Регистр CMCON управляет встроенными аналоговыми компараторами, которые используют несколько контактов, которые соединяют внутреннее оборудование с внешним миром через контакты GP0 (CIN+), GP1 (CIN-) и GP2 (COUT) соответственно. Поэтому вам необходимо сначала отключить аппаратное обеспечение компараторов, установив биты CM2:CM0 на 7 (111 в двоичном формате).

CMCON = 7;

Настройка аналоговых и цифровых выходов

Регистр ANSEL — это место, где вы можете указать микросхеме, какие контакты вы хотите использовать для работы АЦП. В вашем случае, поскольку вы используете только AN0 (GP0), а все остальное должно быть настроено как цифровое. Что вам нужно сделать, так это установить соответствующий бит ANSx для контакта, который вы хотите использовать в качестве аналогового входа (вы используете AN0, поэтому вы должны установить ANS0), а остальные биты ANSx должны быть установлены в 0, чтобы использовать другие контакты в качестве цифрового ввода-вывода. .

ANSEL = 1;

Давайте наведем порядок в вашем коде

Итак, если мы завершим приведенную выше информацию и объединим ее с вашим кодом, а также приведем в порядок ваш код, окончательный код должен выглядеть следующим образом:

#include <xc.h>

#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // GP3/MCLR pin function select (GP3/MCLR pin function is MCLR)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF

#define _XTAL_FREQ 4000000
#define HIGH 1
#define LOW 0


void setupInputs() {
    GPIO = 0; // Clear output latches
    CMCON = 7; // Turn off analog comparators
    TRISIO = 1; // GP0 and GP3 (GP3 is an only input pin) are input and other pins are output
}

void setupADC() {
    ANSEL = 0x21; // Set the GP0 pin as analog input and the rest is digital IO
                  // and use the internal RC osc for ADC
    ADCON0 = 0x81; // Right justify, sample CH0, ADC turn on
}

unsigned int getAnalogValueOnCh0() {
    ADCON0bits.GO = 1;
    while(ADCON0bits.GO)
        ;                // Wait for the ADC conversion to complete
    return (unsigned int) ( ADRESH << 8) + ADRESL;
}

void setDisplay(char value) {
    GP1 = value & 1;
    GP2 = (value & 2) >> 1;
    GP4 = (value & 4) >> 2;
    GP5 = (value & 8) >> 3;
}

void main(void) {

    setupInputs();
    setupADC();
    setDisplay(0);
    __delay_us(20); // See datasheet 7.2 A/D ACquisition Requirements

    while(1) {
        unsigned int adc_value = getAnalogValueOnCh0();
        if (adc_value >= 0 && adc_value <= 200) {
            setDisplay(0);
        } else if (adc_value > 200 && adc_value <= 400) {
            setDisplay(1);
        } else if (adc_value > 400 && adc_value <= 600) {
            setDisplay(2);
        } else if (adc_value > 600 && adc_value <= 800) {
            setDisplay(3);
        } else if (adc_value > 800 && adc_value <= 1023) {
            setDisplay(4);
        } else {
            setDisplay(5);
        }
        __delay_ms(100);
    }
}

PS: Вам следовало расположить значения в диапазоне 1024/6 = 170 примерно. Но вы разделили ценность ADC на куски по 200. Выбирайте сами.

В решении при выключенном MCLRE показывает 0 и 1 вольт правильно, но 2,3,4,5 не выводит, при включенном MCLRE не выводит с пинов. ) – CrazyProgrammer Комментарий: 12 минут назад

CrazyProgrammer 25.07.2024 09:32

Когда я активировал вывод MCLRE и подключил его к плюсовой линии с 10К, та же ситуация повторилась.

CrazyProgrammer 25.07.2024 09:35

Проблема была в функции setDisplay. Я исправил это, проверьте это.

Kozmotronik 25.07.2024 10:48
Ответ принят как подходящий

В качестве решения, согласно коду, предоставленному @Kozmotronik, проблема была решена при использовании 74hc595 вместо 7447.

Не могли бы вы объяснить свой ответ?

Mike 29.07.2024 07:25

Где какой-либо намек на использование какого-то другого оборудования, скрытого в этом коде или во всем ответе?

Gerhardh 30.07.2024 12:46

Другие вопросы по теме