Microchip
直播中

李龙

7年用户 186经验值
私信 关注
[问答]

从ADC读取电压并应用于DAC,C代码不起作用

嗨,我正在研究一个小程序,它从一个引脚读取电压,并将DAC寄存器设置为一个值,以便它应该输出与ADC之前读取的电压大致相同的电压,这是我目前对PIC16F15766的方法:但是这个C代码不起作用:变量“DAC”用CO加下划线。MtMeNo.C:19:错误:(195)表达式SythActudio.C: 19:错误:(314)“;”预期

以上来自于百度翻译


      以下为原文

    Hi,

i am working on a small program which reads voltage from a pin and sets the DAC register to a value so that it should output roughly the same voltage as the ADC read before, this is my current approach for the PIC16F15376:

#include
#include

#pragma config WDTE = OFF // WDT operating mode (WDT Disabled, SWDTEN is ignored)

void interrupt __isr_handler(void) {
    if (PIR0bits.TMR0IF == 1) { //it is a timer0 interrupt
        
        ADCON0bits.GO = 1; //Start ADC conversion
        while(ADCON0bits.GO != 0) //Wait until conversion is done
            ;
        
        short result = (ADRESH << 2) | (ADRESL >> 6); //combine High and low register
        float measuredV = (3.30 * (float)result) / 1023.0 //calculate measured voltage
        unsigned char dac = (unsigned char)((measuredV * 31.0) / 3.3); //[0..31]
        DAC1CON1 = dac;
        
        PIR0bits.TMR0IF = 0; //Clear interrupt flag
    }
}

// Read from: RD7
void initADC(){
    // Configure RD7
    TRISDbits.TRISD7 = 1; //Disable output driver
    ANSELDbits.ANSD7 = 1; //Analog input
   
    ADCON0bits.CHS = 0b011111; //Read from pin RD7
    ADCON1bits.ADFM = 0; //Left justified
    ADCON1bits.ADCS = 0b010; //Fosc / 32
    ADCON1bits.ADPREF = 0b00; //Vref is connected to Vdd
   
    ADCON0bits.ADON = 1; //Enable ADC
}

void initTimer0(){
    T0CON1bits.T0CS = 0b011; //HFINTOSC (32MHz)
    T0CON1bits.T0CKPS = 0b0111; //128 Prescaler
    T0CON0bits.T016BIT = 0; //8bit Timer
   
    PIR0bits.TMR0IF = 0; //Clear overflow interrupt bit
   
    PIE0bits.TMR0IE = 1; //Enable overflow interrupt
    INTCONbits.GIE = 1; //Enable global interrupts
   
    T0CON0bits.T0EN = 1; //Enable Timer 0
}

void initDAC(){
    DAC1CON0bits.DAC1EN = 1; //Enable DAC
    DAC1CON0bits.DAC1OE1 = 1; //Tie voltage level to DAC1OUT1 pin (RA2)
   
    DAC1CON0bits.PSS = 0b00;
}

void initOscillator(){
    OSCCON1bits.NOSC = 0b110; //Select HFINTOSC
    OSCCON1bits.NDIV = 0b0000;
    OSCFRQbits.HFFRQ = 0b110; //32 MHz
}

void main(void) {
    initOscillator();
    initDAC();
    initADC();
    initTimer0();
    while(1){
    }
}

But this C code isn't working:

        short result = (ADRESH << 2) | (ADRESL >> 6); //combine High and low register
        float measuredV = (3.30 * (float)result) / 1023.0 //calculate measured voltage
        unsigned char dac = (unsigned char)((measuredV * 31.0) / 3.3);
        DAC1CON1 = dac;

The variable "dac" is underlined with the comment

main.c:19: error: (195) expression syntax
main.c:19: error: (314) ";" expected

回帖(15)

王竹

2019-2-18 13:29:56
上面显示错误的那条线不完整。

以上来自于百度翻译


      以下为原文

    The line above the one that shows the error is not complete.
(; is missing ;-)
举报

李兆峰

2019-2-18 13:42:55
是的,我也避免在上面的情况下使用中断,因为你开始了ADC转换和轮询……你可能想要使用一种不同的、更优化的方法,稍后,但是现在我将在主循环中完成所有这些操作。

以上来自于百度翻译


      以下为原文

    Yeah
I'd also avoid using interrupt in the above case, since you're starting ADC conversion and polling for it...
 
You may want to use a different, more optimized approach, later, but right now I'd do it all in the main loop.
举报

张恒

2019-2-18 13:58:18
哦,这太难堪了,因为前面我的评论,我找不到那个错误:(这个PIC只有一个“全局”中断功能吗?”我习惯于为每个中断定义不同的中断例程(例如,完成ADC转换的一个功能,一个用于定时器溢出中断等),但我不知道在这种情况下这是否可能?如果不是这样的话,我想用我所做的if语句过滤适当的中断原因,我猜?

以上来自于百度翻译


      以下为原文

    Oh that's so embarrassing, i couldn't find that error because of my comment in front of it :(
 
Is there only one "global" interrupt function for this PIC? I am used to defining different interrupt routines for each interrupt (for example, one function for ADC conversion completed, one for Timer overflow interrupt, etc.), but i don't know if this is possible in this case? If not: I have to filter the appropriate interrupt cause with if-statements like i did, i guess?
举报

蒋喜玲

2019-2-18 14:09:40
你基本上是正确的。只有一个中断向量,并且该向量上的中断服务例程必须检查中断标志(并且中断使所有中断都不能启用)能够确定需要中断什么中断。当然,每个中断都有它自己的主ISR调用函数,但我不喜欢在ISROF过程中执行函数调用,如果只有一个中断启用,如果需要更快的服务,可以跳过标志检查。在新的K42部件之前的PIC18部件具有两个中断向量,允许时间关键中断具有更快和一致的定时,而不排除对较低优先级任务的中断。

以上来自于百度翻译


      以下为原文

    You are essentially correct. There is only one interrupt vector, and the interrupt service routine at that vector must check interrupt flags (and interrupt enables for any interrupts that aren't always enabled) to determine what interrupt needs to be serviced. Each interrupt can of course have it's own function called by the main ISR, but I prefer not to do function calls in the ISR
 
Of course if there's only one interrupt enabled, you can skip the flag check if you need faster servicing. PIC18 parts prior to the new K42 parts have two interrupt vectors allowing a time critical interrupt to have faster and consistent timing without precluding interrupts for lower priority tasks.
举报

更多回帖

发帖
×
20
完善资料,
赚取积分