找回密码
 立即注册
查看: 330|回复: 2

【官网例子分析系列】例子11--NTC

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:224
  • 最近打卡:2025-05-07 08:02:46

79

主题

631

回帖

1148

积分

金牌会员

积分
1148
发表于 2024-5-5 18:15:20 | 显示全部楼层 |阅读模式
重点在这里:


ADCTIM:ADC 时序控制寄存器
    CSSETUP:ADC 通道选择时间控制 Tsetup
    CSHOLD[1:0]:ADC 通道选择保持时间控制 Thold
    SMPDUTY[4:0]:ADC 模拟信号采样时间控制 Tduty(注意:SMPDUTY 一定不能设置小于01010B)

ADCCFG:ADC 配置寄存器
    RESFMT:ADC 转换结果格式控制位。
        0:转换结果左对齐。ADC_RES 保存结果的高 8 位,ADC_RESL 保存结果的低 4 位。
        1:转换结果右对齐。ADC_RES 保存结果的高 4 位,ADC_RESL 保存结果的低 8 位。
    SPEED[3:0]:设置 ADC 时钟{FADC=SYSclk/2/(SPEED+1)}

ADC_CONTR:ADC 控制寄存器
    ADC_POWER:ADC 电源控制位
    ADC_START:ADC 转换启动控制位
    ADC_FLAG:ADC 转换结束标志位
    ADC_EPWMT: 使能PWM 实时触发ADC 功能
    ADC_CHS[3:0]: ADC 模拟通道选择位. 具体见666页

ADC_RES:保存转换结果
ADC_RESL:保存转换结果

------------------------------------------------------
原理图:
NTC.png
NTC-mcu.png

-------------------------------------------------------
例子分析:
1.获取ADC值

u16 Get_ADC12bitResult(u8 channel)  //channel = 0~15
{
    ADC_RES = 0;
    ADC_RESL = 0;

        ADC_CONTR = (ADC_CONTR & 0xf0) | channel; //设置ADC转换通道
        ADC_START = 1;//启动ADC转换
    _nop_();
    _nop_();
    _nop_();
    _nop_();

    while(ADC_FLAG == 0);   //wait for ADC finish
    ADC_FLAG = 0;     //清除ADC结束标志
    return  (((u16)ADC_RES << 8) | ADC_RESL);
}

2.计算温度

/********************  计算温度 ***********************************************/
// 计算结果: 0对应-40.0度, 400对应0度, 625对应25.0度, 最大1600对应120.0度.
// 为了通用, ADC输入为12bit的ADC值.
// 电路和软件算法设计: Coody
/**********************************************/

#define     D_SCALE     10      //结果放大倍数, 放大10倍就是保留一位小数
u16 get_temperature(u16 adc)
{
    u16 code *p;
    u16 i;
    u8  j,k,min,max;
   
    adc = 4096 - adc;   //Rt接地
    p = temp_table;
    if(adc < p[0])      return (0xfffe);
    if(adc > p[160])    return (0xffff);
   
    min = 0;        //-40度
    max = 160;      //120度

    for(j=0; j<5; j++)  //对分查表
    {
        k = min / 2 + max / 2;
        if(adc <= p[k]) max = k;
        else            min = k;
    }
         if(adc == p[min])  i = min * D_SCALE;
    else if(adc == p[max])  i = max * D_SCALE;
    else    // min < temp < max
    {
        while(min <= max)
        {
            min++;
            if(adc == p[min])   {i = min * D_SCALE; break;}
            else if(adc < p[min])
            {
                min--;
                i = p[min]; //min
                j = (adc - i) * D_SCALE / (p[min+1] - i);
                i = min;
                i *= D_SCALE;
                i += j;
                break;
            }
        }
    }
    return i;
}

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:35
  • 最近打卡:2025-02-06 20:14:13

1

主题

39

回帖

237

积分

中级会员

积分
237
发表于 2024-5-23 00:45:44 | 显示全部楼层
其实这个例子非常简单,总结起来就是先 设置转换通道再启动然后一直查询,查询到后保存结果。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:239
  • 最近打卡:2025-05-07 07:20:07

61

主题

818

回帖

1514

积分

金牌会员

积分
1514
发表于 2024-5-23 09:19:35 | 显示全部楼层
adc没仔细研究   等学完全部课程  再挨个测试
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-8 00:52 , Processed in 0.118410 second(s), 66 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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