

PIC16F1827を用いAD変換値で  
LEDの点滅速度を変化させようとしています。

以下にコードを示します。  
↓

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <xc.h>
    #define _XTAL_FREQ 4000000
    
    // CONFIG1
    #pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
    #pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
    #pragma config PWRTE = ON       // Power-up Timer Enable (PWRT enabled)
    #pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
    #pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
    #pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
    #pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
    #pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
    #pragma config IESO = ON        // Internal/External Switchover (Internal/External Switchover mode is enabled)
    #pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
    
    // CONFIG2
    #pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
    #pragma config PLLEN = OFF      // PLL Enable (4x PLL disabled)
    #pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
    #pragma config BORV = HI        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), high trip point selected.)
    #pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)
    
    void internal_osc();
    void io_int();
    void adc_int();
    int adc_read();
    void wait1(char val);
    int adc_tmp;
    
    void main(void){
        internal_osc();
        io_int();
        adc_int();
        while(1){
            adc_tmp = adc_read();
            PORTB = 0x01;
            wait1(adc_tmp>>2);
            PORTB = 0x03;
            wait1(adc_tmp>>2);
            PORTB = 0x07;
            wait1(adc_tmp>>2);
            PORTB = 0x0f;
            wait1(adc_tmp>>2);
            PORTB = 0x00;
            wait1(adc_tmp>>2);
            PORTB = 0x0f;
            wait1(adc_tmp>>2);
            PORTB = 0x00;
            wait1(adc_tmp>>2);
            PORTB = 0x0f;
            wait1(adc_tmp>>2);
        }
    }
    
    void internal_osc(void){
        /*
         * SPLLEN=0;4xPLL is disabled
         * IRCF=1101;4MHz
         * SCS=10;Internal oscillator block
         * OSCCON=0b01101010;
         */
        OSCCON = 0x6a;
    }
    void io_int(void){
        /*
         * RB0=0;LED0
         * RB1=0;LED1
         * RB2=0;LED2
         * RB3=0;LED3
         * RA0=1;AN0
         * TRISA=0b00000001;
         * TRISB=0b00000000;
         * ANSELA=0b00000001;
         * ANSELB=0b00000000;
         */
        TRISA = 0x01;
        TRISB = 0x00;
        ANSELA = 0x01;
        ANSELB = 0x00;
    }
    void adc_int(void){
        /*
         * CHS=00000;AN0
         * ADON=1;
         * ADFM=1;Right justified
         * ADCS=001;FOSC->1/8;
         * ->4MHz ad_scan 2us
         * ADNREF=0;VREF- is connected to AVSS
         * ADPREF=00;VREF+ is connected to AVDD
         * ADCON0=0b00000001;
         * ADCON1=0b10010000;
         */
        ADCON0 = 0x01;
        ADCON1 = 0x90;
    }
    int adc_read(void){
        __delay_us(20);
        ADCON0bits.GO_nDONE = 1;
        while(ADCON0bits.GO_nDONE);
        return (ADRESH<<8) + ADRESL;
    }
    void wait1(char val){
        for(int i=0; i<=val; i++){
            __delay_ms(10);
        }
    }
    
[/code]

このコードではAD変換値を読み取ったら  
whileで先頭に戻るまでadc_tmpの値を  
変化させることはできないかと思います。

whileループの中で依存せず、  
自由にadc_tmpの値を変化させる  
方法が思いつきません。

どなたかご教授お願いします。


CC BY-SA 3.0
2018-01-01T12:41:42.337
40656
2018-01-02T11:42:14.790
2018-01-01T12:49:23.963
7283
26851
question
c
リアルタイムでのAD変換方法


自己解決しました。  
タイマー割り込みを用い、割り込み中にAD変換をすることで  
メインルーチンに依存せずLEDの点滅速度を変化させることができました。  
ありがとうございました。

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <xc.h>
    #define _XTAL_FREQ 4000000
    
    // CONFIG1
    #pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
    #pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
    #pragma config PWRTE = ON       // Power-up Timer Enable (PWRT enabled)
    #pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
    #pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
    #pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
    #pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
    #pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
    #pragma config IESO = ON        // Internal/External Switchover (Internal/External Switchover mode is enabled)
    #pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
    
    // CONFIG2
    #pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
    #pragma config PLLEN = OFF      // PLL Enable (4x PLL disabled)
    #pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
    #pragma config BORV = HI        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), high trip point selected.)
    #pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)
    
    void internal_osc();
    void io_int();
    void tmr0_int();
    void adc_int();
    int adc_read();
    void wait1(char val);
    char tmr0_cnt;
    int adc_tmp;
    
    void main(void){
        internal_osc();
        io_int();
        tmr0_int();
        adc_int();
        while(1){
            PORTB = 0x01;
            wait1(adc_tmp>>2);
            PORTB = 0x03;
            wait1(adc_tmp>>2);
            PORTB = 0x07;
            wait1(adc_tmp>>2);
            PORTB = 0x0f;
            wait1(adc_tmp>>2);
            PORTB = 0x00;
            wait1(adc_tmp>>2);
            PORTB = 0x0f;
            wait1(adc_tmp>>2);
            PORTB = 0x00;
            wait1(adc_tmp>>2);
            PORTB = 0x0f;
            wait1(adc_tmp>>2);
        }
    }
    void interrupt ISR(void){
        INTCONbits.TMR0IF = 0;
        TMR0 = 130;
        adc_tmp = adc_read();
    }
    void internal_osc(void){
        /*
         * SPLLEN=0;4xPLL is disabled
         * IRCF=1101;4MHz
         * SCS=10;Internal oscillator block
         * OSCCON=0b01101010;
         */
        OSCCON = 0x6a;
    }
    void io_int(void){
        /*
         * RB0=0;LED0
         * RB1=0;LED1
         * RB2=0;LED2
         * RB3=0;LED3
         * RA0=1;AN0
         * TRISA=0b00000001;
         * TRISB=0b00000000;
         * ANSELA=0b00000001;
         * ANSELB=0b00000000;
         */
        TRISA = 0x01;
        TRISB = 0x00;
        ANSELA = 0x01;
        ANSELB = 0x00;
    }
    void tmr0_int(void){
        /*
         * 1msec interval_timer
         * FOSC->4MHz
         * interval_time=(255-TMR0)*(FOSC/4)*PS;
         * PS=010;Prescaler->1/8
         * TMR0=130
         * OPTION_REG=0b10000010;
         */
        OPTION_REG = 0x82;
        TMR0 = 130;
        INTCONbits.TMR0IE = 1;
        INTCONbits.GIE = 1;
    }
    void adc_int(void){
        /*
         * CHS=00000;AN0
         * ADON=1;
         * ADFM=1;Right justified
         * ADCS=001;FOSC->1/8;
         * ->4MHz ad_scan 2us
         * ADNREF=0;VREF- is connected to AVSS
         * ADPREF=00;VREF+ is connected to AVDD
         * ADCON0=0b00000001;
         * ADCON1=0b10010000;
         */
        ADCON0 = 0x01;
        ADCON1 = 0x90;
    }
    int adc_read(void){
        __delay_us(20);
        ADCON0bits.GO_nDONE = 1;
        while(ADCON0bits.GO_nDONE);
        return (ADRESH<<8) + ADRESL;
    }
    void wait1(char val){
        for(int i=0; i<=val; i++){
            __delay_ms(10);
        }
    }
    
[/code]


CC BY-SA 3.0
2018-01-02T07:40:33.280
40665
2018-01-02T11:42:14.790
2018-01-02T11:42:14.790
754
26851
40656
answer