powerantone 发表于 2025-3-9 23:00

关于mega48 多通道AD转换的问题,转换结果相同

/******************************************************************************/
/*                     多通道AD实验程序                                       */
/******************************************************************************/

#include <iom48v.h>
#include <macros.h>
#define uint unsigned int
#define uchar unsigned char
uint temp1=0,temp4=0;

uint ADC_Convert(uchar channel)
{
ADMUX |= channel; //选择ADC通道为PA0
ADCSRA|=(1<<ADSC);// 开始转换
while (!(ADCSRA&(1<<ADIF))); // 等待转换结束
ADCSRA |=(1<<ADIF); // 清除转换结束标记
return(ADCH);
}

void main(void)
{
DDRD|=0x80;
PORTD&=0x7F;

DDRC&=0xEB;//ad通道输入设置
ADCSRA=0x00;
ADMUX |=0x60; //采用内部5参考电压,左对齐
ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);

while(1)
{
    temp1=ADC_Convert(2);
if(temp1>40)
PORTD|=0x80;

temp4=ADC_Convert(4);
if(temp4<40)
PORTD&=0x7F;
}

}

捉虫天师 发表于 2025-3-21 16:26

可能是由于以下原因导致的:

1. ADMUX通道选择问题
你在ADC_Convert函数中使用ADMUX |= channel;来选择通道,这种方式会保留ADMUX寄存器中的其他位(如参考电压选择、对齐方式等),可能导致通道选择不准确。

应该先清除通道选择位(MUX3:0),再设置新的通道。可以使用ADMUX = (ADMUX & 0xF0) | channel;来确保只修改通道选择位。

2. ADC结果读取问题
你只读取了ADCH(高8位),而没有读取ADCL(低8位)。对于10位精度的ADC,需要同时读取ADCL和ADCH,否则结果可能不准确。

读取顺序应该是先读ADCL,再读ADCH。

3. ADC初始化问题
你在ADMUX中设置了左对齐(0x60),这意味着结果的高8位在ADCH中,低2位在ADCL的高2位。如果你只读取ADCH,会丢失精度。

如果需要完整的10位结果,建议使用右对齐(清除ADLAR位)。

4. 通道输入配置问题
你设置了DDRC &= 0xEB;,但PORTC的配置没有明确说明。如果PORTC的上拉电阻未启用,可能会导致输入信号不稳定。

建议将PORTC的对应引脚设置为输入模式,并启用上拉电阻(如果需要)。

捉虫天师 发表于 2025-3-21 16:26

试试下面的代码
#include <iom48v.h>
#include <macros.h>

#define uint unsigned int
#define uchar unsigned char

uint temp1 = 0, temp4 = 0;

uint ADC_Convert(uchar channel)
{
    ADMUX = (ADMUX & 0xF0) | channel; // 清除通道选择位并设置新通道
    ADCSRA |= (1 << ADSC);            // 开始转换
    while (!(ADCSRA & (1 << ADIF)));// 等待转换结束
    ADCSRA |= (1 << ADIF);            // 清除转换结束标记
    return ADC;                     // 读取完整的10位结果(先读ADCL,再读ADCH)
}

void main(void)
{
    DDRD |= 0x80;    // 设置PD7为输出
    PORTD &= 0x7F;   // PD7初始化为低电平

    DDRC &= 0xEB;    // 设置PC2和PC4为输入
    PORTC |= 0x14;   // 启用PC2和PC4的上拉电阻

    ADCSRA = 0x00;   // 关闭ADC
    ADMUX = 0x40;    // 使用AVCC作为参考电压,右对齐
    ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // 使能ADC,设置预分频为128

    while (1)
    {
      temp1 = ADC_Convert(2); // 读取PC2的ADC值
      if (temp1 > 40)
            PORTD |= 0x80;   // 如果结果大于40,PD7置高

      temp4 = ADC_Convert(4); // 读取PC4的ADC值
      if (temp4 < 40)
            PORTD &= 0x7F;      // 如果结果小于40,PD7置低
    }
}

捉虫天师 发表于 2025-3-21 16:26

说明:
通道选择:使用ADMUX = (ADMUX & 0xF0) | channel;确保只修改通道选择位。

ADC结果读取:使用return ADC;读取完整的10位结果。

右对齐:将ADMUX设置为0x40,使用右对齐模式。

上拉电阻:启用PC2和PC4的上拉电阻,确保输入信号稳定。

捉虫天师 发表于 2025-3-21 16:26

建议:
使用示波器或逻辑分析仪检查PC2和PC4的输入信号,确保信号正常。

在调试时,可以打印temp1和temp4的值,观察ADC结果是否正确。

g36xcv 发表于 2025-3-27 15:26

在设置通道前,应该先清空 ADMUX 的通道位,然后再 OR (|) 赋值。

而服务器人 发表于 2025-3-31 15:59

你可以修改 ADC_Convert() 函数,使其在每次选择通道前 清除 ADMUX 中的通道选择部分,然后再设置新通道。
页: [1]
查看完整版本: 关于mega48 多通道AD转换的问题,转换结果相同