標(biāo)題: 基于STC15w單片機(jī)系列 自帶的AD轉(zhuǎn)換程序 [打印本頁]

作者: 蘇海    時間: 2020-2-15 16:53
標(biāo)題: 基于STC15w單片機(jī)系列 自帶的AD轉(zhuǎn)換程序
15W系列是目前51單片機(jī)里面可用資源較多的處理器。一般的設(shè)計都可以用,本次分享下利用單片機(jī)自帶的AD轉(zhuǎn)換座一個數(shù)字電壓表。顯示用的LCD1602

單片機(jī)源程序如下:
  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完成標(biāo)志
  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延時函數(shù),含有輸入?yún)?shù) 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延時函數(shù),含有輸入?yún)?shù) 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.               判忙函數(shù)
  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.               寫入命令函數(shù)
  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.               寫入數(shù)據(jù)函數(shù)
  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.                 清屏函數(shù)
  95. ------------------------------------------------*/
  96. void LCD_Clear(void)
  97. {
  98. LCD_Write_Com(0x01);
  99. DelayMs(5);
  100. }
  101. /*------------------------------------------------
  102.               寫入字符串函數(shù)
  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.               寫入字符函數(shù)
  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.               初始化函數(shù)
  137. ------------------------------------------------*/
  138. void LCD_Init(void)
  139. {
  140.    LCD_Write_Com(0x38);    /*顯示模式設(shè)置*/
  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);    /*顯示關(guān)閉*/
  148.    LCD_Write_Com(0x01);    /*顯示清屏*/
  149.    LCD_Write_Com(0x06);    /*顯示光標(biāo)移動設(shè)置*/
  150.    DelayMs(5);
  151.    LCD_Write_Com(0x0C);    /*顯示開及光標(biāo)設(shè)置*/
  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;                   //設(shè)置P1口為AD口
  184.     ADC_RES = 0;                    //清除結(jié)果寄存器
  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;                //設(shè)置定時器模式
  192.         TL0 = 0x5C;                //設(shè)置定時初值
  193.         TH0 = 0xF7;                //設(shè)置定時初值
  194.         TF0 = 0;                //清除TF0標(biāo)志
  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中斷服務(wù)程序
  232. ----------------------------*/
  233. void adc_isr() interrupt 5 using 1
  234. {
  235.     ADC_CONTR &= !ADC_FLAG;         //清除ADC中斷標(biāo)志


  236.      p=ADC_RES  ;       //讀取高8位結(jié)果并發(fā)送到串口

  237. //    SendData(ADC_LOW2);           //顯示低2位結(jié)果
  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. }
復(fù)制代碼

所有資料51hei提供下載:
15wAD轉(zhuǎn)換.rar (57.32 KB, 下載次數(shù): 82)



作者: luoshi133    時間: 2020-2-21 04:23
下載學(xué)習(xí)學(xué)習(xí),感謝樓主分享程序。
作者: wsh791    時間: 2020-2-21 13:07
謝謝分享
作者: dwy6122281    時間: 2021-4-29 15:06
具體用的哪款單片機(jī)芯片呢?
作者: 阿飛7812    時間: 2021-4-29 20:48
樓主如果單片電源5V,AD只在5V以內(nèi) ,如要能測量30V以內(nèi)的電壓程序應(yīng)該怎樣改 請指點下
作者: rambo.hu    時間: 2021-5-1 10:53
電阻分壓,我也想試試
作者: bsljling    時間: 2021-5-2 20:20
我是小白:電阻分壓,改變TEMP的比率好像就可以改變測量范圍。不知對否。




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1