找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 189|回复: 1
打印 上一主题 下一主题
收起左侧

为什么我这个代码读出来的ADC值一直都是0

[复制链接]
跳转到指定楼层
楼主
ID:1041297 发表于 2024-8-28 14:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "H/Function_Init.H"
#include "math.h"
#include "H/TM1637.H"

unsigned char code CODE[10]={0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,};
unsigned char code number[12] = {0xFD,0x51,0xBB,0xAF,0x67,0xCF,0xDF,0xA5,0xFF,0xEF,0x20,0x76};
                                                                                                                                //0   1    2     3    4    5    6    7    8    9  LED灯  H
unsigned char code time[10] = {0xFD,0x51,0xBB,0xAF,0x67,0xCF,0xDF,0xA5,0xFF,0xEF};
                               //0   1    2     3    4    5    6    7    8    9
uint8_t data ucRunStatus = 0;//0表示待机状态,1表示进入焦度调整模式
uint8_t data program;        //焦度模式选择
uint8_t data mode_3s_flag;   //焦度模式3s不操作标志位
uint16_t data mode_3s_time;   //焦度模式3s累计时间
uint8_t data mode_last_value;  //上次焦度模式的值
uint8_t data mode_value;       //焦度模式的值
uint8_t data digital_tube_flash;
uint8_t data digital_tube_flashtime;
uint8_t key_pressdown_total = 0; //按键按下总数
uint16_t time_setting;      //时间设定


//float T_c=0.0;   //温度值
// 定义常量
#define R_FIXED 1000.0 // 固定电阻值1kΩ
#define B_CONST 4537.0 // NTC的B常数
#define T0 373.15 // 100℃转换为开尔文
#define R0 1000.0 // NTC在25℃时的电阻值1kΩ
#define clk  P20
#define dio  P05
#define key_press P25
#define Time_Max  945
#define Time_Min  0

unsigned int ADCValue = 0x0000;
unsigned int  tmpValue;
bit AdcFlag = 0;
/***********ADC采样频率选择*************/
enum ADCFreq {F32=0,F24,F16,F12,F8,F6,F4,F3};

/***********ADC采样口选择*************/
#if (IC_MODEL == SC92F7413)
enum Channel {AIN0=0,AIN1,AIN2,AIN3,AIN4,AIN5,AIN6,AIN7,AIN8,AIN9,VDD4=31};
#endif

#if (IC_MODEL == SC92F7412)
enum Channel {AIN2=2,AIN3,AIN4,AIN5,AIN8=8,AIN9,VDD4=31};
#endif

#if (IC_MODEL == SC92F7411)
enum Channel {AIN2=2,AIN3,AIN4,AIN8=8,AIN9,VDD4=31};
#endif


/********************延时函数,延时nms******************/
void delay_nms(unsigned int n)
{
         unsigned int i;
         while(n--)
         for(i=0;i<550;i++);
}
///=======================================
void Delay_us(unsigned int i) //nus 延时
{
         for(;i>0;i--)
         _nop_();
}


/*
函数功能:IIC开始信号
参数:无
返回值:无
备注:无
*/
void I2CStart(void)
{
         clk = 1;
         dio = 1;
         Delay_us(2);
         dio = 0;
}


/*
函数功能:IIC应答信号
参数:无
返回值:无
备注:无
*/
void I2Cask(void)
{
        clk = 0;
        Delay_us(5); //在第八个时钟下降沿之后延时 5us,开始判断 ACK 信号
        while(dio);
        clk = 1;
        Delay_us(2);
        clk=0;
}
///========================================

/*
函数功能:IIC停止信号
参数:无
返回值:无
备注:无
*/
void I2CStop(void)  
{
         clk = 0;
         Delay_us(2);
         dio = 0;
         Delay_us(2);
         clk = 1;
         Delay_us(2);
         dio = 1;
}


/*
函数功能:写一个字节
参数:无
返回值:无
备注:无
*/
void I2CWrByte(unsigned char oneByte) //
{
         unsigned char i;
         for(i=0;i<8;i++)
         {
                  clk = 0;
            if(oneByte&0x01) //低位在前
           {
             dio = 1;
           }
                 else
                 {
                         dio = 0;
                 }
                 Delay_us(3);
                 oneByte=oneByte>>1;
                 clk=1;
                 Delay_us(3);
        }
}

/*
函数功能:自动地址加一模式
参数:无
返回值:无
备注:无
*/
void SmgDisplay(void) //写显示寄存器
{
         unsigned char i;
         I2CStart();
         I2CWrByte(0x40); // 40H 地址自动加 1 模式,44H 固定地址模式,本程序采
         I2Cask();
         I2CStop();
         I2CStart();
         I2CWrByte(0xc0); //设置首地址,
         I2Cask();
         for(i=0;i<4;i++) //地址自加,不必每次都写地址
         {
                        I2CWrByte(0x00); //送数据
                        I2Cask();
         }
         I2CStop();
         I2CStart();
         I2CWrByte(0x8f); //开显示 ,最大亮度
         I2Cask();
         I2CStop();
}


/*
函数功能:显示函数,固定地址写数据
参数:无
返回值:无
备注:无
*/
void disp(unsigned char add, unsigned char value)
{
         I2CStart();
         I2CWrByte(0x44);                                 //数据命令设置:固定地址,写数据到显示寄存器
         I2Cask();
         I2CStop();

         I2CStart();
         I2CWrByte(add);                                //地址命令设置:写入add对应地址
         I2Cask();

       
                 I2CWrByte(number[value]);                        //给add地址写数据
                 I2Cask();
                 I2CStop();
               
         
         I2CStart();
         I2CWrByte(0x8C);                                //显示控制命令:开显示,脉冲宽度为11/16.
         I2Cask();
         I2CStop();

}




/*****************************************************
*函数名称:void ADC_Init(uint Channel,uchar ADCFreq)
*函数功能:ADC初始化
*入口参数:void
*出口参数:void
*****************************************************/
void ADC_Init(uint Channel)
{
        ADCCON = 0X80|Channel;                //开启ADC,ADC采样频率为3M ,选择Channel位ADC采样口
        if(Channel<8)
        {
                ADCCFG0 = 1<<Channel;   //设置Channel作为采样口
        }
        else
        {
                ADCCFG1 = 1<<(Channel-8);   //设置Channel作为采样口
        }
        //ADCCFG2 = F8;
        IE |= 0X40;        //开启ADC中断
        //EA = 1;
}

/*****************************************************
*函数名称:uint ADC_GetAverageValue(uint Channel,ADC_SamplesNum_TypeDef ADC_SamplesNum)
*函数功能:ADC采样取平均值
*入口参数:
ADC_SamplesNum_TypeDef ADC_SamplesNum:采样次数
*出口参数:
uint:多次采样平均值
*****************************************************/
uint ADC_GetAverageValue(ADC_SamplesNum_TypeDef ADC_SamplesNum)
{
        uchar tmpCnt;
        uint tmpValueSum = 0, tmpValue;
  uint tmpValue_Max = 0, tmpValue_Min = 0xFFFF;

        for(tmpCnt = 0; tmpCnt < ADC_SamplesNum; tmpCnt ++)
  {
                EA = 0;
                OPINX = 0xC1;
          OPREG |= 0x10;      //切换至二分频               
                EA = 1;               
                ADCCON |= 0X40;             //开始一次ADC转换
          while(!AdcFlag);          //等待ADC转换完成       
                EA = 0;
                OPINX = 0xC1;
          OPREG &= 0xCF;      //返回至一分频
                EA = 1;       
               
                AdcFlag = 0;            
          tmpValue=(ADCVH<<4)+(ADCVL>>4);     //获取单次转换值
                  
    if(tmpValue > tmpValue_Max)   //获取多次转换值中的最大值
      tmpValue_Max = tmpValue;   
    if(tmpValue < tmpValue_Min)   //获取多次转换值中的最小值
      tmpValue_Min = tmpValue;               
    tmpValueSum += tmpValue;   //累加多次转换值的和
  }

        /* 通过硬件乘除法器来计算平均值 */
  {
    OPERCON |= 0X40;
    /* 被除数为16位数据 */
    tmpValueSum -= (tmpValue_Max + tmpValue_Min);
    EXA0 = tmpValueSum;
    EXA1 = tmpValueSum >> 8;
    EXBL = ADC_SamplesNum - 2;                        //除数为8位数据

    OPERCON |= 0x80;                                //开始除法计算
    while(OPERCON & 0x80);                        //等待计算完毕

    //获取商
    tmpValue = (uint)EXA0;
    tmpValue |= EXA1 << 8;
        }
    return tmpValue;                        //返回平均值
}


///*
//函数功能:LED灯全灭
//参数:无
//返回值:无
//备注:无
//*/
void Display_OFF(void)
{
        I2CStart();
        I2CWrByte(0x80);
        I2CStop();   
}

uint32_t code ntc_r[100]=
{
        //180°~ 189°
        1548,1514,1480,1447,1414,1383,1353,1323,1294,1266,
       
        //190°~199°
        1239,1212,1186,1160,1136,1112,1088,1065,1043,1021,
       
        //200°~209°
        1000,978,957,937,917,897,878,860,841,824,
       
        //210~219°
        807,790,773,758,742,727,712,698,683,670,
       
        //220°~229°
        656,643,630,618,606,594,582,571,560,549,
};






float calculate_temperature(float voltage) {
    float R_ntc, T;
    float V_supply = 5; // 电源电压3.3V

    // 计算NTC电阻值
    R_ntc = R_FIXED * (V_supply / voltage - 1);

    // 计算温度(开尔文)
    T = 1 / (1 / T0 + log(R_ntc / R0) / B_CONST);

    // 转换为摄氏度
    T = T - 273.15;

    return T;
}



uint8_t b;

//void digital(uint8_t c)
//{
//               
//                disp(0xc0,c/100);
//                disp(0xc1,c/10%10);
//                disp(0xc2,c%10);
//}




///==============================================
void main(void)
{
        uint8_t a;

ADC_Init(AIN2);
IO_Init(); //初始化
Timer_Init();
SmgDisplay(); //开机时先全灭,不加这条会乱显示

while(1)
{
         if(ubTime100mS)
         {
                 ubTime100mS =0;
                        a = ADC_GetAverageValue();
                        //b = calculate_temperature(a);
                        disp(0xc0,a/100);
                disp(0xc1,a/10%10);
                disp(0xc2,a%10);

                }
                        
        }
}
请大伙帮我看看,这个是赛元微的芯片,SC92F7411

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:404160 发表于 2024-8-28 16:09 | 只看该作者
初始化问题:确保 ADC_Init 函数正确初始化了 ADC。注意,你的代码中使用了 ADC_Init(AIN2),这意味着你选择 AIN2 作为采样通道,确保这个通道连接到了合适的模拟信号。

中断问题:在 ADC_GetAverageValue 函数中,你使用 while(!AdcFlag); 等待 ADC 转换完成。确保没有中断冲突,并且 AdcFlag 被正确设置。

硬件连接问题:确保 AIN2 引脚与需要测量的模拟信号正确连接,并且没有任何短路或开路的问题。

电源和参考电压:检查电源是否稳定,确保 ADC 的参考电压正确设置,因为如果参考电压过低,可能会导致读数为 0。

滤波和去噪:如果信号有噪声或不稳定,可能会影响 ADC 的读数。考虑在硬件或软件(通过软件滤波)上加入滤波。

ADC 配置问题:检查 ADCCON、ADCCFG0 和 ADCCFG1 的配置是否符合芯片手册的推荐设置。

软件逻辑问题:检查 ADC_GetAverageValue 函数的逻辑是否正确,特别是取平均值的逻辑部分。

显示问题:注意,你有一个注释掉的 digital 函数,如果你打算使用它来显示数值,需要取消注释,并确保它的逻辑是正确的。

调试:在 ADC_GetAverageValue 函数中,打印 tmpValue 或 tmpValueSum 来检查在取平均值之前和之后的值,以帮助诊断问题。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表