我们从2011年坚守至今,只想做存粹的技术论坛。  由于网站在外面,点击附件后要很长世间才弹出下载,请耐心等待,勿重复点击不要用Edge和IE浏览器下载,否则提示不安全下载不了

 找回密码
 立即注册
搜索
查看: 1624|回复: 5

基于stc单片机的比较器做ADC实验

[复制链接]

该用户从未签到

19

主题

61

回帖

124

积分

二级逆天

积分
124

终身成就奖

发表于 2020-11-25 14:42:25 | 显示全部楼层 |阅读模式
使用MCU自带的比较器进行ADC转换, 并通过串口输出结果. 用定时器0产生10us中断查询比较器的状态.
  1. #define MAIN_Fosc        22118400L    //定义主时钟
  2. #define    BaudRate1        9600ul        //定义波特率
  3. #define    ADC_SCALE        50000        //ADC满量程, 根据需要设置
  4. #include    "STC15Fxxxx.H"
  5. /*************    本地常量声明    **************/
  6. //CMPCR1
  7. #define    CMPEN    0x80    //1: 允许比较器, 0: 禁止,关闭比较器电源
  8. #define    CMPIF    0x40    //比较器中断标志, 包括上升沿或下降沿中断, 软件清0
  9. #define    PIE        0x20    //1: 比较结果由0变1, 产生上升沿中断
  10. #define    NIE        0x10    //1: 比较结果由1变0, 产生下降沿中断
  11. #define    PIS        0x08    //输入正极性选择, 0: 选择内部P5.5做正输入,           1: 由ADCIS[2:0]所选择的ADC输入端做正输入.
  12. #define    NIS        0x04    //输入负极性选择, 0: 选择内部BandGap电压BGv做负输入, 1: 选择外部P5.4做输入.
  13. #define    CMPOE    0x02    //1: 允许比较结果输出到P1.2, 0: 禁止.
  14. #define    CMPRES    0x01    //比较结果, 1: CMP+电平高于CMP-,  0: CMP+电平低于CMP-,  只读
  15. //CMPCR2
  16. #define    INVCMPO    0x80    //1: 比较器输出取反,  0: 不取反
  17. #define    DISFLT    0x40    //1: 关闭0.1uF滤波,   0: 允许
  18. #define    LCDTY    0x00    //0~63, 比较结果变化延时周期数
  19. #define    TIM_16BitAutoReload            0
  20. #define    TIM_16Bit                    1
  21. #define    TIM_8BitAutoReload            2
  22. #define    TIM_16BitAutoReloadNoMask    3
  23. #define    Pin0        0x01    //IO引脚 Px.0
  24. #define    Pin1        0x02    //IO引脚 Px.1
  25. #define    Pin2        0x04    //IO引脚 Px.2
  26. #define    Pin3        0x08    //IO引脚 Px.3
  27. #define    Pin4        0x10    //IO引脚 Px.4
  28. #define    Pin5        0x20    //IO引脚 Px.5
  29. #define    Pin6        0x40    //IO引脚 Px.6
  30. #define    Pin7        0x80    //IO引脚 Px.7
  31. #define    PinAll        0xFF    //IO所有引脚
  32. /*************    本地变量声明    **************/
  33. //sbit    P_ADC    = P1^2;    //P1.2 比较器转IO输出端
  34. sbit    P_ADC    = P1^4;    //P1.2 比较器转IO输出端
  35. u16        adc;            //ADC中间值, 用户层不可见
  36. u16        adc_duty;        //ADC计数周期, 用户层不可见
  37. u16        adc_value;        //ADC值, 用户层使用
  38. bit        adc_ok;            //ADC结束标志, 为1则adc_value的值可用. 此标志给用户层查询,并且清0
  39. /*************    本地函数声明    **************/
  40. void    TxString(u8 *puts);
  41. void main(void)
  42. {
  43.     u8    i;
  44.     u8    tmp[5];
  45. //IO口初始化
  46. //    P1n_push_pull(Pin2);        //P1.2设置为push-pull output
  47.     P1n_push_pull(Pin4);        //P1.2设置为push-pull output
  48.     P5n_pure_input(Pin4+Pin5);    //P5.4 P5.5设置为高阻输入
  49. //比较器初始化
  50.     CMPCR1 = 0;
  51.     CMPCR2 = 20;        //比较结果变化延时周期数, 0~63
  52.     CMPCR1 |= CMPEN;    //允许比较器        ENABLE,DISABLE
  53. //    CMPCR1 |= PIE;        //允许上升沿中断    ENABLE,DISABLE
  54. //    CMPCR1 |= NIE;        //允许下降沿中断    ENABLE,DISABLE
  55. //    CMPCR1 |= PIS;        //输入正极性选择, 0: 选择内部P5.5做正输入,           1: 由ADCIS[2:0]所选择的ADC输入端做正输入.
  56.     CMPCR1 |= NIS;        //输入负极性选择, 0: 选择内部BandGap电压BGv做负输入, 1: 选择外部P5.4做输入
  57. //    CMPCR1 |= CMPOE;    //允许比较结果输出到P1.2,   ENABLE,DISABLE
  58. //    CMPCR2 |= INVCMPO;    //比较器输出取反,     ENABLE,DISABLE
  59.     CMPCR2 |= DISFLT;    //内部0.1uF滤波,      ENABLE,DISABLE
  60. //定时器0 初始化
  61.     TMOD &= ~0x0f;
  62.     Timer0_16bitAutoReload();    //设置为16位自动重装模式
  63.     Timer0_1T();    //设置为1T模式
  64.     ET0 = 1;        //允许中断
  65.     PT0 = 1;        //高优先级中断
  66.     TH0 = (u8)((65536 - MAIN_Fosc / 100000ul)>>8);        //重装值    100KHZ, 10us,    65536 - (MAIN_Fosc)/100000
  67.     TL0 = (u8)( 65536 - MAIN_Fosc / 100000ul);
  68.     TR0 = 1;        //开始运行
  69. //串口1初始化
  70.     S1_USE_P30P31();    //UART1 使用P30 P31口    默认
  71. //    S1_USE_P36P37();    //UART1 使用P36 P37口
  72. //    S1_USE_P16P17();    //UART1 使用P16 P17口
  73.     S1_8bit();            //8位数据,波特率可变
  74.     S1_RX_Enable();        //允许接收
  75.     S1_TXD_RXD_OPEN();    //将TXD与RXD连接中继断开    默认
  76.     S1_BRT_UseTimer2();    //使用Timer2做波特率发生器
  77.     ES = 0;                //禁止中断, 使用查询发送
  78.     Timer2_1T();    //Timer2 1T模式, 固定为16位自动重装
  79.     T2L = (65536 - (MAIN_Fosc/4/BaudRate1));   //设置波特率重装值
  80.     T2H = (65536 - (MAIN_Fosc/4/BaudRate1))>>8;
  81.     Timer2_Run();    //允许定时器2计数
  82.     EA = 1;            //允许全局中断
  83.     TxString("\r\n使用比较器做ADC例子\r\n");    //SUART1发送一个字符串
  84.    
  85.     while (1)
  86.     {
  87.         if(adc_ok)        //等待ADC结束
  88.         {
  89.             adc_ok = 0;                //清除ADC已结束标志
  90.             TxString("ADC = ");    //转十进制
  91.             tmp[0] = adc_value / 10000 + '0';
  92.             tmp[1] = adc_value % 10000 / 1000 + '0';
  93.             tmp[2] = adc_value % 1000 / 100 + '0';
  94.             tmp[3] = adc_value % 100 / 10 + '0';
  95.             tmp[4] = adc_value % 10 + '0';
  96.             for(i=0; i<4; i++)        //消无效0
  97.             {
  98.                 if(tmp[i] != '0')    break;
  99.                 tmp[i] = ' ';
  100.             }
  101.             for(i=0; i<5; i++)        //发串口
  102.             {
  103.                 TI = 0;
  104.                 SBUF = tmp[i];
  105.                 while(!TI);
  106.                 TI = 0;
  107.             }
  108.             TxString("\r\n");
  109.         }
  110.     }
  111. }
  112. void TxString(u8 *puts)        //发送一个字符串
  113. {
  114.     for (; *puts != 0;    puts++)       //遇到停止符0结束
  115.     {
  116.         TI = 0;
  117.         SBUF = *puts;
  118.         while(!TI);
  119.         TI = 0;
  120.     }
  121. }
  122. /********************* Timer0中断函数************************/
  123. void timer0_int (void) interrupt TIMER0_VECTOR
  124. {
  125.     if((CMPCR1 & CMPRES) == 0)    P_ADC = 0;    //比较器输出高电平
  126.     else                //P_ADC输出低电平, 给负输入端做反馈.
  127.     {
  128.         P_ADC = 1;            //P_ADC输出高电平, 给负输入端做反馈.
  129.         adc ++;    //ADC计数+1
  130.     }
  131.     if(--adc_duty == 0)            //ADC周期-1, 到0则ADC结束
  132.     {
  133.         adc_duty = ADC_SCALE;    //周期计数赋初值
  134.         adc_value = adc;        //保存ADC值
  135.         adc = 0;                //清除ADC值
  136.         adc_ok = 1;                //标志ADC已结束
  137.     }
  138. }
复制代码
回复

使用道具 举报

该用户从未签到

77

主题

4432

回帖

4091

积分

二级逆天

积分
4091

终身成就奖社区居民忠实会员社区劳模最爱沙发原创达人优秀斑竹奖

QQ
发表于 2020-11-25 16:26:24 | 显示全部楼层
回复

使用道具 举报

  • TA的每日心情
    开心
    1 小时前
  • 签到天数: 102 天

    [LV.6]常住居民II

    49

    主题

    1万

    回帖

    7万

    积分

    三级逆天

    积分
    73176

    终身成就奖特殊贡献奖原创先锋奖社区居民忠实会员社区劳模最爱沙发社区明星原创达人优秀斑竹奖宣传大使奖

    QQ
    发表于 2020-11-26 05:54:39 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    开心
    前天 09:57
  • 签到天数: 106 天

    [LV.6]常住居民II

    5

    主题

    6750

    回帖

    1万

    积分

    三级逆天

    积分
    14182

    终身成就奖特殊贡献奖原创先锋奖

    发表于 2020-11-26 08:52:27 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    23

    主题

    3167

    回帖

    1059

    积分

    二级逆天

    积分
    1059

    忠实会员社区居民社区劳模终身成就奖优秀斑竹奖

    QQ
    发表于 2021-8-8 12:29:30 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    2

    主题

    81

    回帖

    0

    积分

    二级逆天

    积分
    0

    终身成就奖

    发表于 2021-8-10 17:26:13 | 显示全部楼层
    回复

    使用道具 举报

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

    本版积分规则

    论坛开启做任务可以
    额外奖励金币快速赚
    积分升级了


    Copyright ©2011-2024 NTpcb.com All Right Reserved.  Powered by Discuz! (NTpcb)

    本站信息均由会员发表,不代表NTpcb立场,如侵犯了您的权利请发帖投诉

    平平安安
    TOP
    快速回复 返回顶部 返回列表