打印
[其他产品]

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

[复制链接]
766|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
powerantone|  楼主 | 2025-3-9 23:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/******************************************************************************/
/*                     多通道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的上拉电阻,确保输入信号稳定。

使用特权

评论回复
5
捉虫天师| | 2025-3-21 16:26 | 只看该作者
建议:
使用示波器或逻辑分析仪检查PC2和PC4的输入信号,确保信号正常。

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

使用特权

评论回复
6
g36xcv| | 2025-3-27 15:26 | 只看该作者
在设置通道前,应该先清空 ADMUX 的通道位,然后再 OR (|) 赋值。

使用特权

评论回复
7
而服务器人| | 2025-3-31 15:59 | 只看该作者
你可以修改 ADC_Convert() 函数,使其在每次选择通道前 清除 ADMUX 中的通道选择部分,然后再设置新通道。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

601

主题

3106

帖子

4

粉丝