找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于STC15w单片机系列 自带的AD转换程序

  [复制链接]
跳转到指定楼层
楼主
ID:499397 发表于 2020-2-15 16:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
15W系列是目前51单片机里面可用资源较多的处理器。一般的设计都可以用,本次分享下利用单片机自带的AD转换座一个数字电压表。显示用的LCD1602

单片机源程序如下:
  1. #include<15w.H>
  2. #include<math.h>
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include<intrins.h>
  6. #define uchar unsigned char
  7. #define uint unsigned int

  8. typedef unsigned int WORD;

  9. #define ADC_POWER   0x80            //ADC电源控制位
  10. #define ADC_FLAG    0x10            //ADC完成标志
  11. #define ADC_START   0x08            //ADC起始控制位
  12. #define ADC_SPEEDLL 0x00            //540个时钟
  13. #define ADC_SPEEDL  0x20            //360个时钟
  14. #define ADC_SPEEDH  0x40            //180个时钟
  15. #define ADC_SPEEDHH 0x60            //90个时钟
  16. unsigned char ch = 0;                        //ADC通道号

  17. int time;
  18. int time1;
  19. int time2;
  20. float p;

  21. sbit RS = P5^5;   //定义端口
  22. sbit RW = P5^4;
  23. sbit EN = P5^3;
  24. sbit pwm=P2^7;
  25. sbit key1 = P2^0;
  26. sbit key2=P2^1;
  27. sbit led=P5^1;
  28. unsigned char ti[]={'0','1',0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
  29. /*------------------------------------------------
  30. uS延时函数,含有输入参数 unsigned char t,无返回值
  31. unsigned char 是定义无符号字符变量,其值的范围是
  32. 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
  33. 长度如下 T=tx2+5 uS
  34. ------------------------------------------------*/
  35. void DelayUs2x(unsigned char t)
  36. {   
  37. while(--t);
  38. }
  39. /*------------------------------------------------
  40. mS延时函数,含有输入参数 unsigned char t,无返回值
  41. unsigned char 是定义无符号字符变量,其值的范围是
  42. 0~255 这里使用晶振12M,精确延时请使用汇编
  43. ------------------------------------------------*/
  44. void DelayMs(unsigned char t)
  45. {
  46.      
  47. while(t--)
  48. {
  49.      //大致延时1mS
  50.      DelayUs2x(245);
  51.          DelayUs2x(245);
  52. }
  53. }
  54. /*------------------------------------------------
  55.               判忙函数
  56. ------------------------------------------------*/
  57. bit LCD_Check_Busy(void)
  58. {
  59. P4= 0xFF;
  60. RS=0;
  61. RW=1;
  62. EN=0;
  63. _nop_();
  64. EN=1;
  65. return (bit)(P4 & 0x80);
  66. }
  67. /*------------------------------------------------
  68.               写入命令函数
  69. ------------------------------------------------*/
  70. void LCD_Write_Com(unsigned char com)
  71. {  
  72. while(LCD_Check_Busy()); //忙则等待
  73. RS=0;
  74. RW=0;
  75. EN=1;
  76. P4= com;
  77. _nop_();
  78. EN=0;
  79. }
  80. /*------------------------------------------------
  81.               写入数据函数
  82. ------------------------------------------------*/
  83. void LCD_Write_Data(unsigned char Data)
  84. {
  85. while(LCD_Check_Busy()); //忙则等待
  86. RS=1;
  87. RW=0;
  88. EN=1;
  89. P4= Data;
  90. _nop_();
  91. EN=0;
  92. }

  93. /*------------------------------------------------
  94.                 清屏函数
  95. ------------------------------------------------*/
  96. void LCD_Clear(void)
  97. {
  98. LCD_Write_Com(0x01);
  99. DelayMs(5);
  100. }
  101. /*------------------------------------------------
  102.               写入字符串函数
  103. ------------------------------------------------*/
  104. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
  105. {     
  106. if (y == 0)
  107.         {     
  108.          LCD_Write_Com(0x80 + x);     //表示第一行
  109.         }
  110. else
  111.         {      
  112.         LCD_Write_Com(0xC0 + x);      //表示第二行
  113.         }        
  114. while (*s)
  115.         {     
  116. LCD_Write_Data( *s);     
  117. s ++;     
  118.         }
  119. }
  120. /*------------------------------------------------
  121.               写入字符函数
  122. ------------------------------------------------*/
  123. void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
  124. {     
  125. if (y == 0)
  126.         {     
  127.         LCD_Write_Com(0x80 + x);     
  128.         }   
  129. else
  130.         {     
  131.         LCD_Write_Com(0xC0 + x);     
  132.         }        
  133. LCD_Write_Data( Data);  
  134. }
  135. /*------------------------------------------------
  136.               初始化函数
  137. ------------------------------------------------*/
  138. void LCD_Init(void)
  139. {
  140.    LCD_Write_Com(0x38);    /*显示模式设置*/
  141.    DelayMs(5);
  142.    LCD_Write_Com(0x38);
  143.    DelayMs(5);
  144.    LCD_Write_Com(0x38);
  145.    DelayMs(5);
  146.    LCD_Write_Com(0x38);  
  147.    LCD_Write_Com(0x08);    /*显示关闭*/
  148.    LCD_Write_Com(0x01);    /*显示清屏*/
  149.    LCD_Write_Com(0x06);    /*显示光标移动设置*/
  150.    DelayMs(5);
  151.    LCD_Write_Com(0x0C);    /*显示开及光标设置*/
  152.    }








  153. void display(uint temp)                        //显示程序
  154. {
  155.    int A1,A2,A3;
  156.    A1=temp/100;
  157.    A2=temp%100/10;
  158.    A3=temp%100%10/1;
  159.    
  160.             LCD_Write_Char(4,0,ti[A1]);
  161.          LCD_Write_Char(5,0,ti[A2]);
  162.          LCD_Write_Char(6,0,'.');
  163.          LCD_Write_Char(7,0,ti[A3]);
  164.          LCD_Write_Char(8,0,'V');


  165.    }
  166. /*----------------------------
  167. 软件延时
  168. ----------------------------*/
  169. void Delay(WORD n)
  170. {
  171.     WORD x;

  172.     while (n--)
  173.     {
  174.         x = 5000;
  175.         while (x--);
  176.     }
  177. }
  178. /*----------------------------
  179. 初始化ADC
  180. ----------------------------*/
  181. void InitADC()
  182. {
  183.     P1ASF = 0x01;                   //设置P1口为AD口
  184.     ADC_RES = 0;                    //清除结果寄存器
  185.     ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
  186.     Delay(2);                       //ADC上电并延时
  187. }

  188. void Timer0Init(void)                //200微秒@11.0592MHz
  189. {
  190.         AUXR |= 0x80;                //定时器时钟1T模式
  191.         TMOD &= 0xF0;                //设置定时器模式
  192.         TL0 = 0x5C;                //设置定时初值
  193.         TH0 = 0xF7;                //设置定时初值
  194.         TF0 = 0;                //清除TF0标志
  195.         TR0 = 1;                //定时器0开始计时
  196.         ET0=1;
  197.         EA=1;

  198. }


  199.   

  200. void main()                                       
  201. {
  202.         float i,j;
  203.     P0M0 = 0x00;
  204.     P0M1 = 0x00;
  205.     P1M0 = 0x00;
  206.     P1M1 = 0x00;
  207.     P2M0 = 0x00;
  208.     P2M1 = 0x00;
  209.     P3M0 = 0x00;
  210.     P3M1 = 0x00;
  211.     P4M0 = 0x00;
  212.     P4M1 = 0x00;
  213.     P5M0 = 0x00;
  214.     P5M1 = 0x00;

  215.     LCD_Init();
  216.     LCD_Clear();//清屏
  217.     InitADC();                      //初始化ADC
  218.     IE = 0xa0;                      //使能ADC中断
  219.            Timer0Init();
  220.        
  221.        
  222.          
  223.   while(1){

  224.            i=p*5;
  225.          j=((i/256)*10);
  226.     display(j);       
  227.         DelayMs(500);  


  228.   }


  229. }
  230. /*----------------------------
  231. ADC中断服务程序
  232. ----------------------------*/
  233. void adc_isr() interrupt 5 using 1
  234. {
  235.     ADC_CONTR &= !ADC_FLAG;         //清除ADC中断标志


  236.      p=ADC_RES  ;       //读取高8位结果并发送到串口

  237. //    SendData(ADC_LOW2);           //显示低2位结果
  238.    
  239.     ch = 0;           //切换到下一个通道
  240.     ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
  241. }


  242. void tm0_isr() interrupt 1
  243. {

  244.     time++;
  245.         time1++;
  246.         time2++;
  247.         if(time1>100)
  248.         time1=0;
  249.         if(time1>50)
  250.         pwm=1;
  251.         else
  252.         pwm=0;






  253.         if(time>5000)
  254. {        time=0;
  255.         led=~led ;  }
  256. }
复制代码

所有资料51hei提供下载:
15wAD转换.rar (57.32 KB, 下载次数: 81)


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

使用道具 举报

沙发
ID:385168 发表于 2020-2-21 04:23 | 只看该作者
下载学习学习,感谢楼主分享程序。
回复

使用道具 举报

板凳
ID:686739 发表于 2020-2-21 13:07 来自手机 | 只看该作者
谢谢分享
回复

使用道具 举报

地板
ID:7781 发表于 2021-4-29 15:06 | 只看该作者
具体用的哪款单片机芯片呢?
回复

使用道具 举报

5#
ID:65237 发表于 2021-4-29 20:48 | 只看该作者
楼主如果单片电源5V,AD只在5V以内 ,如要能测量30V以内的电压程序应该怎样改 请指点下
回复

使用道具 举报

6#
ID:852236 发表于 2021-5-1 10:53 | 只看该作者
电阻分压,我也想试试
回复

使用道具 举报

7#
ID:840797 发表于 2021-5-2 20:20 | 只看该作者
我是小白:电阻分压,改变TEMP的比率好像就可以改变测量范围。不知对否。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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