我最近完成了 PIC18F252 的代码,它使用内置 ADC 将来自 3 个传感器的模拟输入转换为可发送到电机的数字输出。代码构建并上传到 PIC 的效果非常好,但不幸的是就是不起作用,我正在努力找出问题所在。 在测试了电机的输出端口后,我发现它们都输出相同的信号,而它们不应该输出,并且它不会根据传感器而改变。 我的第一个想法是 ADC 的输出(从 ADRESH 加载结果)和用于为这些输出分配数字值的 if 语句之间存在问题。 我无法上传整个代码,因为这是类(class)作业,但我已经添加了相关部分。我只包含了使用一个 channel 进行 AD 转换的函数,但其他两个 channel 的函数是相同的,只是更改了变量。
如果有人能够发现此代码的问题(大概是围绕 if 语句),我将不胜感激!
#include <p18F252.h> // PIC specific definitions
#include <xc.h> // Xc8 compiler specifics
#include <stdio.h> // Standard C I/O library
#include <stdlib.h> // Standard C library
// Function declarations
void Config_ADC(void);
void delay(void);
void Motor_Output(unsigned char x, unsigned char y, unsigned char z);
void channel3(void);
unsigned char leftSens = 0b00000000; //Initialise left sensor variable
void Config_ADC(void){
// ADC Setup
TRISA = 0xFF; // configure port A as inputs
ADCON1bits.ADFM =0; // left justified
ADCON1bits.PCFG3=0;
ADCON1bits.PCFG2=1;
ADCON1bits.PCFG1=0;
ADCON1bits.PCFG0=0;
ADCON1bits.ADCS2=0;
ADCON0bits.ADCS1=1;
ADCON0bits.ADCS0=0;
ADCON0bits.ADON =1;
}
// Function for a delay of 1ms
void delay(void){
T2CON = 0x49; // start counting from 73
PR2 = 0x7C; // stop count at 124
T2CONbits.TMR2ON = 1; // activate timer 2
while(!PIR1bits.TMR2IF); // wait for timer flag
T2CONbits.TMR2ON = 0; // stop timer 2
PIR1bits.TMR2IF = 0; // clear flag
}
void channel3(void){
ADCON0bits.CHS2 = 0; //Channel selection
ADCON0bits.CHS1 = 1;
ADCON0bits.CHS0 = 1;
delay(); // Acquisition time to charge hold capacitor
ADCON0bits.GO_DONE = 1; // Start Conversion
while(ADCON0bits.GO_DONE); // Wait for A/D Conversion to complete
leftSens = ADRESH; // Return result
}
void main(void){
TRISB = 0x00; // configure Port B as output
Config_ADC(); // load ADC
while(1) { //loop forever/
channel3(); // Call channel 3 conversion
Motor_Output(leftSens, middleSens, rightSens);
}
}
// Function to send instructions to motors
void Motor_Output(unsigned char x, unsigned char y, unsigned char z){
int left, middle, right;
if(x >= 173){left = 1;} //173 chosen as threshold 8 bit value
else if(x < 173){left = 0;}
else if(y >= 173){middle = 1;}
else if(y < 173){middle = 0;}
else if(z >= 173){right = 1;}
else if(z < 173){right = 0;}
unsigned char output;
output = (left << 2) | (middle << 1) | right; //Bit shifted variables into one value
switch(output){
case 0x0:
PORTBbits.RB7 = 0; //Test for each output and activate motors accordingly
PORTBbits.RB6 = 1;
PORTBbits.RB5 = 0;
PORTBbits.RB4 = 1;
case 0x1:
PORTBbits.RB7 = 0;
PORTBbits.RB6 = 1;
PORTBbits.RB5 = 1;
PORTBbits.RB4 = 0;
case 0x2:
PORTBbits.RB7 = 0;
PORTBbits.RB6 = 1;
PORTBbits.RB5 = 0;
PORTBbits.RB4 = 1;
case 0x3:
PORTBbits.RB7 = 0;
PORTBbits.RB6 = 1;
PORTBbits.RB5 = 1;
PORTBbits.RB4 = 0;
case 0x4:
PORTBbits.RB7 = 1;
PORTBbits.RB6 = 0;
PORTBbits.RB5 = 0;
PORTBbits.RB4 = 1;
case 0x5:
PORTBbits.RB7 = 0;
PORTBbits.RB6 = 1;
PORTBbits.RB5 = 0;
PORTBbits.RB4 = 1;
case 0x6:
PORTBbits.RB7 = 1;
PORTBbits.RB6 = 0;
PORTBbits.RB5 = 0;
PORTBbits.RB4 = 1;
case 0x7:
PORTBbits.RB7 = 0;
PORTBbits.RB6 = 1;
PORTBbits.RB5 = 0;
PORTBbits.RB4 = 1;
}
return;
}
最佳答案
如果不进行更深入的分析,有两个主要问题:
if
-else if
链只会对left
进行一次分配。为了使这一点显而易见,我以这种方式缩进了您的源代码,没有任何其他更改:if (x >= 173) { // Either THIS... left = 1; } else if (x < 173) { // Or THAT will be true. left = 0; } else // None of the following is executed therefore. if (y >= 173) { middle = 1; } else if (y < 173) { middle = 0; } else if (z >= 173) { right = 1; } else if (z < 173) { right = 0; }
因此
middle
和right
将具有未定义的值。switch
中的所有case
都缺少break
。因此,只有最后一个案例或根本不会被执行。为什么“没有”?由于middle
和right
具有未定义的值,导致output
中出现随机值。注意:“随机”可能始终是相同的值,具体取决于分别在
中间
和右
位置设置或重置的位。
关于c - 与 PIC18F252 上的 ADC 输出作斗争,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59067179/