找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STC单片机比较器用作AD例程

[复制链接]
跳转到指定楼层
楼主
STC单片机比较器用作AD例程

所有源程序下载:
比较器做AD用.zip (49.18 KB, 下载次数: 123)

部分源码预览:
  1. //工作频率为20M
  2. #include <STC15F2K60S2.H>
  3. #include <intrins.h>
  4. #include"CMP-AD.H"
  5. #include"math.h"
  6. #define uint unsigned int
  7. #define ulint unsigned long int
  8. #define uchar unsigned char
  9. //对ADC控制寄存器ADC_CONTR进行位定义 (ADC_CONTR寄存器不能进行位操作)
  10. #define ENABLE_IAP  0x82   //if SYSCLK<20MH
  11. #define ADC_POWER   0x80            //ADC电源控制位
  12. #define ADC_FLAG    0x10            //ADC完成标志
  13. #define ADC_START   0x08            //ADC起始控制位
  14. #define ADC_SPEEDLL 0x00            //540个时钟
  15. #define ADC_SPEEDL  0x20            //360个时钟
  16. #define ADC_SPEEDH  0x40            //180个时钟
  17. #define ADC_SPEEDHH 0x60            //90个时钟
  18. #define CH6          6
  19. sfr ADC_LOW2=0XBE;          //ADC低2位结果
  20. //sbit P_ADC=P3^3;     //定义比价器的输出口
  21. sbit P_ADC=P1^4;     //定义比价器的输出口
  22. sbit power=P3^3;     //主电源开机使能位
  23. sbit in_ac=P3^2;     //AC输入电压类型 1:AC60V  0:AC90v
  24. sbit smg1=P1^5;
  25. sbit smg2=P1^6;
  26. sbit smg3=P1^7;
  27. uchar ch=0;
  28. uchar i_t2;
  29. uint t0val;                         //定时器0的初值
  30. uint t2val;          //定时器2的初值   
  31. uint adc_scal;       //AD量程
  32. uint adc_count;      //比较结果为高计数
  33. uint adc_duty;       //ADC计数周期
  34. uint adc_val;        //ADC值
  35. bit  adc_ok;                 //ADC转换完成标志
  36. uchar ok_count;      //AD采集次数
  37. bit  one_ok;         //取样完成标志
  38. ulint val1,val2;     //中间临时值
  39. uint rmsval;         //输入电压有效值
  40. uchar smgval[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
  41. uchar temp[4];
  42. uchar i;
  43. //1ms延时子程序
  44. void delay(uint x)  
  45. {uint a,b;
  46. for (a=x; a>0;a--)  
  47.   for (b=100;b>0; b--);
  48. }
  49. //AD初始化程序
  50. void intad()
  51. {        ch=0;
  52.     P1ASF = 0x01 ;                  //设置P1口为AD口
  53.     ADC_RES = 0;                    //清除结果寄存器
  54.     ADC_CONTR = ADC_POWER | ADC_SPEEDHH | ADC_START | ch;
  55.     delay(2);

  56. }
  57. //读取AD结果
  58. int getad()
  59. {ADC_CONTR=ADC_POWER|ADC_SPEEDHH|ch|ADC_START;
  60. _nop_();
  61. _nop_();
  62. _nop_();
  63. _nop_();
  64. while(!(ADC_CONTR&ADC_FLAG)) ;
  65. ADC_CONTR=~ADC_CONTR;
  66. return ((uint)((uint)(ADC_RES<<2)+(uint)(ADC_LOW2)));
  67. }
  68. //主程序初始化
  69. void int_main()   
  70. {
  71. intad();
  72. P3M1=0;
  73. P3M0=0XFF;
  74. P1M1=0;
  75. P1M0=0Xf0;
  76. /////////////
  77. power=0;
  78. in_ac=1;                         //刚上电时候先关闭主电源
  79. P5M1=0XFF;
  80. P5M0=0;                                  //P54 P55设为高阻状态
  81. adc_scal=500;                  //AD量程
  82. adc_duty=adc_scal;
  83. //P3M0=0X80;              //P33为强推挽模式  P32为准双向口模式
  84. CMPCR1=0;             //比价器寄存器1初始化
  85. CMPCR2=0;             //比较器寄存器2初始化
  86. CMPCR1&=~PIS;                  //选择P55脚为比较器的正极输入端
  87. CMPCR1|= NIS;         //选择P54脚为比较器的负极输入端
  88. CMPCR1&=~CMPOE;                  //禁止比较器的结果输出
  89. CMPCR2&=~INVCMPO;          //比机器结果正常输出
  90. CMPCR2|=DISFLT;          //不使能比较器输出0.1us滤波
  91. CMPCR2&=~LCDTY;       //比较器结果不去抖 直接输出
  92. CMPCR1|=CMPEN;        //使能比机器
  93. t0val=55536;          //定时器0定时时间为0.5ms
  94. t2val=45536;                  //定时器0定时时间为1ms
  95. TH0=t0val>>8;
  96. TL0=t0val;
  97. T2H=t2val>>8;
  98. T2L=t2val;
  99. AUXR=0X94;                           //定时器0的速度为传统8051的12倍,即不分频  允许定时器2运行 速度为1分频
  100. //IE2|=ET2;             //定时器2中断开启

  101. TMOD=0;               //定时器0工作模式为16位自动重装
  102. ET0=1;                                  //允许T0中断
  103. TR0=1;                //定时器0使能
  104. PT0=1;                //定时器0中断为最高优先级中断
  105. EA=1;                 //开启总中断
  106. }
  107. main()
  108. {
  109. int_main();
  110. while(1)
  111. {
  112. //if(adc_ok==1)
  113. {
  114.   adc_ok=0;
  115.   temp[0]=rmsval/100;
  116.   temp[1]=rmsval%100/10;
  117.   temp[2]=rmsval%100%10;
  118. }
  119. P3=smgval[temp[0]];
  120. smg1=1;
  121. delay(5);
  122. smg1=0;
  123. P3=smgval[temp[1]];
  124. smg2=1;
  125. delay(5);
  126. smg2=0;
  127. P3=smgval[temp[2]];
  128. smg3=1;
  129. delay(5);
  130. smg3=0;

  131. }
  132. }
  133. //定时器中断0入口
  134. void t0() interrupt 1
  135. {

  136. ulint ls1,ls2,ls3;
  137.   i_t2++;
  138. ls1=getad();
  139. ls2=ls1*ls1;
  140. val1=val1+ls2;
  141. if(i_t2>=200)
  142. {
  143.   i_t2=0;
  144.   ls3=sqrt(val1/200);
  145.   val1=0;
  146.   rmsval=ls3*90/594          ;
  147. }

  148. }



复制代码


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

使用道具 举报

沙发
ID:1 发表于 2017-1-3 02:07 | 只看该作者
51黑有你更精彩!!!
回复

使用道具 举报

板凳
ID:202142 发表于 2017-5-18 13:02 | 只看该作者
感谢分享~~~~
回复

使用道具 举报

地板
ID:155467 发表于 2021-10-4 17:27 | 只看该作者
楼主,你的getad() 函数里面用的都是stc自带的ADC功能,而不是用比较器进行adc转换。
回复

使用道具 举报

5#
ID:973749 发表于 2022-1-13 22:48 | 只看该作者
代码好乱啊,分几个模块吧
回复

使用道具 举报

6#
ID:1092895 发表于 2023-10-11 20:43 | 只看该作者
根本不是利用比较器实现ADC
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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