Как я могу превратить этот 8-битный AD C в 10-битный AD C с PIC16F684 и светодиодной гистограммой - PullRequest
1 голос
/ 13 июля 2020

Вот код, я не понимаю, как изменить его на 10-битный AD C.

я предполагаю, что это что-то вроде 16-битной строки и просто игнорирую последние 6, но Понятия не имею.

Если кто-то может посоветовать, как это изменить, отлично. Я действительно потерялся. Я кое-что читал об этом, но чем больше читаю, тем больше запутываюсь.

Вот расположение светодиодов

Любая другая необходимая информация, просто спросите

#include <xc.h>

/* Configuration Word */

#pragma config FOSC = INTOSCIO// Clock
#pragma config WDTE = OFF   //
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown Out Detect (BOR disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)

// CONFIG --- Configuration Word --- END


void PORTA_init(void);
void ADC_Disp(void);
void Delay_LED_On(void);

int ADC_Value = 0;

const char PORTA_Value[8] = {
    0b010000,   // D0
    0b100000,   // D1
    0b010000,   // D2
    0b000100,   // D3
        0b100000,   // D4
        0b000100,   // D5
        0b000100,   // D6
        0b000010};  // D7
    
const char TRISA_Value[8] = {
    0b001111,   // D0
    0b001111,   // D1
    0b101011,   // D2
    0b101011,   // D3
        0b011011,   // D4
        0b011011,   // D5
        0b111001,   // D6
        0b111001};  // D7
    
main()
{

    PORTA_init();

    ANSEL = 1;                  //  Just RA0 is an Analog Input
    TRISA0 = 1;                 //  Corresponding TRIS bit is set as input

    ADCON0 = 0b00000001;        //  Turn on the ADC
                                //   Bit 7      - Left Justified Sample
                                //   Bit 6      - Use VDD
                                //   Bit 4:2    - Channel 0
                                //   Bit 1      - Do not Start
                                //   Bit 0      - Turn on ADC
                                
    ADCON1 = 0b00010000;        //  Select the Clock as Fosc/8


    ADC_Disp();
    GO_DONE = 1;            // Start A/D Conversion


    while(1 == 1)               //  Loop Forever
    {
       
        if (GO_DONE == 0)           // Is A/D Conversion complete?
            {   ADC_Disp();     // Display A/D Conversion Results
                ADC_Value = ADRESH; // Get new A/D value
                GO_DONE = 1;        // Start the next A/D Conversion
            }
        else                // A/D Conversion still in progress
                ADC_Disp();

    } 
}

/******** END OF main ROUTINE ***************************/

void PORTA_init(void)
{
    PORTA = 0;                  //  All PORTA Pins are low
    CMCON0 = 7;                 //  Turn off Comparators
    ANSEL = 0;                  //  Turn off ADC

    return;

}
/******** END OF PORTA_init ****************************/



/********************************************************
* Function: ADC_Disp
*
* Description:  Displays the value of A/D Conversion on D0 - D7
*
* Notes:
*
* 
*
* Returns:  None
*
********************************************************/
void ADC_Disp(void)
{

    int i;

    for (i = 0; i < 8; i++ )
        {                                   // Loop through Each of the 8 LEDS

        Delay_LED_On();             // Allows time for individual LEDs to light
            
            if ((ADC_Value & (1 << i)) == 0)
                PORTA = 0;
            else
                PORTA = PORTA_Value[i];
                TRISA = TRISA_Value[i];
        }  //  
        
    return;

}
/******** END OF ADC_Disp *************************/

void Delay_LED_On(void)
{
    int j;
    
    for (j = 0; j < 60; j++);       //  Display "On" Loop 
                
    return;

}
/******** END OF Delay_LED_On *************************/

Ответы [ 4 ]

0 голосов
/ 18 июля 2020

Этот код отобразит 10-битное значение AD C на 10 светодиодах Charlieplexed:

/*
 * File:   main.c
 * Author: dan1138
 * Target: PIC16F684
 * Compiler: XC8 v2.20
 * IDE: MPLABX v5.25
 * 
 * Description:
 * 
 *  Display the upper 10-bits of the ADC conversion 
 *  from analog input from RA0 on 12 charlieplexed 
 *  LEDs connected to outputs RA1,RA2,RA4,RA5.
 *
 *                       PIC16F684
 *             +------------:_:------------+
 *    GND -> 1 : VDD                   VSS : 14 <- 5v0
 *   DRV5 <> 2 : RA5/T1CKI     PGD/AN0/RA0 : 13 <> POT
 *   DRV4 <> 3 : RA4/AN3       PGC/AN1/RA1 : 12 <> DRV1
 *    VPP -> 4 : RA3/VPP           AN2/RA2 : 11 <> DRV2
 *        <> 5 : RC5/CPP1          AN4/RC0 : 10 <> 
 *        <> 6 : RC4/C2OUT         AN5/RC1 : 9  <> 
 *        <> 7 : RC3/AN7           AN6 RC2 : 8  <> 
 *             +---------------------------:
 *                        DIP-14
 * 
 *           150 OHM
 *  DRV4 ----/\/\/\-------+---------+---------+---------+-----------------------------+---------+
 *                        :         :         :         :                             :         :
 *                        :         :         :         :                             :         :
 *                       ---       ---       ---       ---                            :         :
 *                  LED1 / \  LED0 \ /  LED3 / \  LED2 \ /                            :         :
 *                       ---       ---       ---       ---                            :         :  
 *                        :         :         :         :                             :         :
 *           150 OHM      :         :         :         :                             :         :
 *  DRV5 ----/\/\/\-------+---------+-------- : ------- : --------+---------+         :         :
 *                        :         :         :         :         :         :         :         :
 *                        :         :         :         :         :         :         :         :
 *                       ---       ---        :         :         :         :        ---       --- 
 *                  LED5 / \  LED4 \ /        :         :         :         :  LED11 / \ LED10 \ /
 *                       ---       ---        :         :         :         :        ---       --- 
 *                        :         :         :         :         :         :         :         :
 *           150 OHM      :         :         :         :         :         :         :         :
 *  DRV2 ----/\/\/\-------+---------+---------+---------+         :         :         :         :
 *                        :         :                             :         :         :         :
 *                        :         :                             :         :         :         :
 *                       ---       ---                           ---       ---        :         :
 *                  LED7 / \  LED6 \ /                      LED9 / \  LED8 \ /        :         :
 *                       ---       ---                           ---       ---        :         :
 *                        :         :                             :         :         :         :
 *           150 OHM      :         :                             :         :         :         :
 *  DRV1 ----/\/\/\-------+---------+-----------------------------+---------+---------+---------+
 *  
 * 
 *  POT -----/\/\/\--+-------+
 *             1K    :       :
 *                   :      --- 1nF
 *                   :      ---
 *                   v       :
 *  5v0 ----------/\/\/\-----+---- GND
 *                  10K
 * 
 *
 * Notes:
 *  Charlieplexing, see https://en.wikipedia.org/wiki/Charlieplexing
 * 
 * Created on July 13, 2019, 6:09 PM
 */

#pragma config FOSC = INTOSCIO
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = OFF
#pragma config IESO = OFF
#pragma config FCMEN = OFF

#include <xc.h>
#include <stdint.h>

#define _XTAL_FREQ (8000000ul)
/*
 * Global data
 */
volatile uint8_t gLEDs_0_to_7;
volatile uint8_t gLEDs_8_to_11;
volatile uint8_t gTicks;

void main(void) 
{
    /*
     * Initialize this PIC
     */
    INTCON = 0;
    OSCCON = 0x70;      /* Select 8MHz system oscillator */
    __delay_ms(500);    /* Give ISCP device programming tool a chance to get the PICs attention */

    TRISA = 0xFF;
    TRISC = 0x00;
    ANSEL  = 0;
    OPTION_REG = 0b11000010; /* TIMER0 clock = FOSC/4, prescale 1:8 */
    PORTA = 0;
    PORTC = 0;
    CMCON0 = 7;
    TMR0 = 0;
    TMR0IF = 0;
    TMR0IE = 1;
    gLEDs_0_to_7  = 0b00000000;
    gLEDs_8_to_11 = 0b00000000;
    gTicks = 0;
    GIE = 1;
    /*
     * Initialize ADC on channel 0
     */
    ADCON0 = 0;
    ADCON1 = 0;
    TRISAbits.TRISA0 = 1;       /* Make RA0 an input */
    ANSELbits.ANS0   = 1;       /* Enable AN0 on the RA0 input */
    ADCON1bits.ADCS  = 0b101;   /* Select FOSC/16 as ADC clock source */
    ADCON0bits.CHS   = 0;       /* Select AN0 as ADC input */
    ADCON0bits.ADFM  = 0;       /* Select left justified data */
    ADCON0bits.VCFG  = 0;       /* Select VDD as VREF source */
    ADCON0bits.ADON  = 1;       /* Turn on ADC */
    /*
     * This is the application loop.
     * 
     * Display 8-bit ADC value in charlieplexed LEDs
     */
    while(1)
    {
        ADCON0bits.GO = 1;      /* Start an ADC conversion */
        while(ADCON0bits.GO);   /* Wait for ADC conversion to finish */
        gLEDs_0_to_7  = ADRESH; /* Put High 8-bits of ADC value in LED7 to LED0 */
        /* Put Low 2-bits of ADC value in LED8 to LED9 */
        gLEDs_8_to_11 = (gLEDs_8_to_11 & ~3) | (ADRESL >> 6);

        /* Flash LED D11 to show application is running */
        if(!gTicks)
        {
            gTicks = 250;
            gLEDs_8_to_11 ^= 0x08;
        }
    }
}
/*
 * Interrupt handlers
 */
void __interrupt() ISR_handler(void)
{
    static uint8_t Timer0Ticks = 0;
    static uint8_t State = 8;
    uint8_t OutBits, HighBits;

    if (TMR0IE && TMR0IF) {  /* TIMER0 asserts and interrupt every 1.024 milliseconds */
        TMR0IF=0;
        if(gTicks != 0) gTicks--;
        if (Timer0Ticks == 0) { /* Select another LED every second TIMER0 interrupt */
            Timer0Ticks = 1;    /* to make LEDs a little brighter make this number larger until you don't like the flickering */

            OutBits  =  0b00000000;
            HighBits =  0b00000000;

            switch (--State)
            {
            case 11:
                if (gLEDs_8_to_11 & 0x08)
                {
                    HighBits |= (1 << 1); /* Drive LED11, DRV4=L DRV1=H */
                    OutBits = ~((1<<1)|(1<<4));
                }
                break;

            case 10:
                if (gLEDs_8_to_11 & 0x04)
                {
                    HighBits |= (1 << 4); /* Drive LED10, DRV4=H DRV1=L */
                    OutBits = ~((1<<1)|(1<<4));
                }
                break;

            case 9:
                if (gLEDs_8_to_11 & 0x02)
                {
                    HighBits |= (1 << 1); /* Drive LED9, DRV1=H DRV5=L */
                    OutBits = ~((1<<1)|(1<<5));
                }
                break;

            case 8:
                if (gLEDs_8_to_11 & 0x01)
                {
                    HighBits |= (1 << 5); /* Drive LED8, DRV1=L DRV5=H */
                    OutBits = ~((1<<1)|(1<<5));
                }
                break;

            case 7:
                if (gLEDs_0_to_7 & 0x80)
                {
                    HighBits |= (1 << 1); /* Drive LED7, DRV1=H DRV2=L */
                    OutBits = ~((1<<1)|(1<<2));
                }
                break;

            case 6:
                if (gLEDs_0_to_7 & 0x40)
                {
                    HighBits |= (1 << 2); /* Drive LED6, DRV1=L DRV2=H */
                    OutBits = ~((1<<1)|(1<<2));
                }
                break;

            case 5:
                if (gLEDs_0_to_7 & 0x20)
                {
                    HighBits |= (1 << 2); /* Drive LED5, DRV5=L DRV2=H */
                    OutBits = ~((1<<5)|(1<<2));
                }
                break;

            case 4:
                if (gLEDs_0_to_7 & 0x10)
                {
                    HighBits |= (1 << 5); /* Drive LED4, DRV5=H DRV2=L */
                    OutBits = ~((1<<5)|(1<<2));
                }
                break;

            case 3:
                if (gLEDs_0_to_7 & 0x08)
                {
                    HighBits |= (1 << 2); /* Drive LED3, DRV4=L DRV2=H */
                    OutBits = ~((1<<4)|(1<<2));
                }
                break;

            case 2:
                if (gLEDs_0_to_7 & 0x04)
                {
                    HighBits |= (1 << 4); /* Drive LED2, DRV4=H DRV2=L */
                    OutBits = ~((1<<4)|(1<<2));
                }
                break;
            case 1:
                if (gLEDs_0_to_7 & 0x02)
                {
                    HighBits |= (1 << 5); /* Drive LED1, DRV4=L DRV5=H */
                    OutBits = ~((1<<4)|(1<<5));
                }
                break;

            default:
                if (gLEDs_0_to_7 & 0x01)
                {
                    HighBits |= (1 << 4); /* Drive LED0, DRV4=H DRV5=L */
                    OutBits = ~((1<<4)|(1<<5));
                }
                State = 12;
            }

            TRISA |= ((1<<5)|(1<<4)|(1<<2)|(1<<1)); /* Turn off all LED output drivers */

            if (OutBits)
            {
                PORTA &= OutBits;      /* Set both LED drivers to low */
                TRISA &= OutBits;      /* Turn on LED output drivers */
                PORTA |= HighBits;     /* Turn on just one of the two LEDs  */
            }
        }
        else
        {
            Timer0Ticks--;
        }
    }
}

Надеюсь, вы получите хорошую оценку за домашнюю работу.

0 голосов
/ 13 июля 2020

По умолчанию AD C настроен на выдачу результатов с выравниванием по левому краю (ADFM = 0). Младшие 8 бит находятся в ADRE SH, а старшие 2 бита хранятся в ADRESL. Вы можете считать оба адреса в 16-битную переменную и отбросить старшие 6 бит.

uint16_t ADC_Value = ( (ADRESH << 8) | ADRESL ) >> 6;
0 голосов
/ 16 июля 2020

Один из способов получить 10 битов из 8 битов AD C: четыре выборки данных AD C по 8 битов можно усреднить, а затем умножить на 4, чтобы получить данные с точностью до 10 бит. Таким образом, общая скорость преобразования 10-битных данных кажется 1/4 от скорости преобразования 8-битных данных AD C.

0 голосов
/ 13 июля 2020

Довольно просто: используйте результат, выровненный по правому краю

ADCON0 = 0b10000001;        //  Turn on the ADC
                                //   Bit 7      - Right Justified Sample
                                //   Bit 6      - Use VDD
                                //   Bit 4:2    - Channel 0
                                //   Bit 1      - Do not Start
                                //   Bit 0      - Turn on ADC

А затем результат 16 бит:

uint16_t   ADC_result;

ADC_result = (uint16_t)(ADRESH <<8) + ADRESL;

Знайте, что 10-битный результат находится в младших 10 битах ADC_result.

Еще одна проблема в вашем коде: посмотрите на фигурные скобки и внимательно сделайте отступ в коде. Это не сработает:

    if ((ADC_Value & (1 << i)) == 0)
        PORTA = 0;
    else
        PORTA = PORTA_Value[i];
        TRISA = TRISA_Value[i];
...