找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 3488|回復(fù): 3
收起左側(cè)

基于51單片機(jī)的adc0832雙路電壓表Proteus仿真程序

[復(fù)制鏈接]
ID:891089 發(fā)表于 2021-5-1 21:16 | 顯示全部樓層 |閱讀模式
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
1.png

單片機(jī)源程序如下:
  1. #include<reg51.h>    //包含單片機(jī)寄存器的頭文件
  2. #include<intrins.h>  //包含_nop_()函數(shù)定義的頭文件
  3. sbit CS=P3^4;       //將CS位定義為P3.4引腳
  4. sbit CLK=P1^0;      //將CLK位定義為P1.0引腳
  5. sbit DIO=P1^1;       //將DIO位定義為P1.1引腳
  6. //////////////////////////////////////////////////////////////////
  7. unsigned char code digit[10]={"0123456789"};   //定義字符數(shù)組顯示數(shù)字
  8. unsigned char code Str[]={"Volt="};            //說明顯示的是電壓
  9. /*******************************************************************************
  10. 以下是對(duì)液晶模塊的操作程序
  11. *******************************************************************************/
  12. sbit RS=P2^0;           //寄存器選擇位,將RS位定義為P2.0引腳
  13. sbit RW=P2^1;           //讀寫選擇位,將RW位定義為P2.1引腳
  14. sbit E=P2^2;            //使能信號(hào)位,將E位定義為P2.2引腳
  15. sbit BF=P0^7;           //忙碌標(biāo)志位,,將BF位定義為P0.7引腳
  16. /*****************************************************
  17. 函數(shù)功能:延時(shí)1ms
  18. (3j+2)*i=(3×33+2)×10=1010(微秒),可以認(rèn)為是1毫秒
  19. ***************************************************/
  20. void delay1ms()
  21. {
  22.    unsigned char i,j;   
  23.      for(i=0;i<10;i++)
  24.       for(j=0;j<33;j++)
  25.        ;         
  26. }
  27. /*****************************************************
  28. 函數(shù)功能:延時(shí)若干毫秒
  29. 入口參數(shù):n
  30. ***************************************************/
  31. void delaynms(unsigned char n)
  32. {
  33.    unsigned char i;
  34.     for(i=0;i<n;i++)
  35.        delay1ms();
  36. }
  37. /*****************************************************
  38. 函數(shù)功能:判斷液晶模塊的忙碌狀態(tài)
  39. 返回值:result。result=1,忙碌;result=0,不忙
  40. ***************************************************/
  41. bit BusyTest(void)
  42.   {
  43.     bit result;
  44.     RS=0;       //根據(jù)規(guī)定,RS為低電平,RW為高電平時(shí),可以讀狀態(tài)
  45.     RW=1;
  46.     E=1;        //E=1,才允許讀寫
  47.     _nop_();   //空操作
  48.     _nop_();
  49.     _nop_();
  50.     _nop_();   //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間   
  51.     result=BF;  //將忙碌標(biāo)志電平賦給result
  52.    E=0;         //將E恢復(fù)低電平
  53.    return result;
  54.   }
  55. /*****************************************************
  56. 函數(shù)功能:將模式設(shè)置指令或顯示地址寫入液晶模塊
  57. 入口參數(shù):dictate
  58. ***************************************************/
  59. void WriteInstruction (unsigned char dictate)
  60. {   
  61.     while(BusyTest()==1);   //如果忙就等待
  62.      RS=0;                  //根據(jù)規(guī)定,RS和R/W同時(shí)為低電平時(shí),可以寫入指令
  63.      RW=0;   
  64.      E=0;                   //E置低電平(根據(jù)表8-6,寫指令時(shí),E為高脈沖,
  65.                            // 就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0"
  66.      _nop_();
  67.      _nop_();               //空操作兩個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
  68.      P0=dictate;            //將數(shù)據(jù)送入P0口,即寫入指令或地址
  69.      _nop_();
  70.      _nop_();
  71.      _nop_();
  72.      _nop_();               //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
  73.      E=1;                   //E置高電平
  74.      _nop_();
  75.      _nop_();
  76.      _nop_();
  77.      _nop_();               //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
  78.       E=0;                  //當(dāng)E由高電平跳變成低電平時(shí),液晶模塊開始執(zhí)行命令
  79. }
  80. /*****************************************************
  81. 函數(shù)功能:指定字符顯示的實(shí)際地址
  82. 入口參數(shù):x
  83. ***************************************************/
  84. void WriteAddress(unsigned char x)
  85. {
  86.      WriteInstruction(x|0x80); //顯示位置的確定方法規(guī)定為"80H+地址碼x"
  87. }
  88. /*****************************************************
  89. 函數(shù)功能:將數(shù)據(jù)(字符的標(biāo)準(zhǔn)ASCII碼)寫入液晶模塊
  90. 入口參數(shù):y(為字符常量)
  91. ***************************************************/
  92. void WriteData(unsigned char y)
  93. {
  94.     while(BusyTest()==1);  
  95.       RS=1;           //RS為高電平,RW為低電平時(shí),可以寫入數(shù)據(jù)
  96.       RW=0;
  97.       E=0;            //E置低電平(根據(jù)表8-6,寫指令時(shí),E為高脈沖,
  98.                      // 就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0"
  99.       P0=y;           //將數(shù)據(jù)送入P0口,即將數(shù)據(jù)寫入液晶模塊
  100.       _nop_();
  101.       _nop_();
  102.        _nop_();
  103.      _nop_();       //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
  104.       E=1;           //E置高電平
  105.       _nop_();
  106.       _nop_();
  107.       _nop_();
  108.      _nop_();        //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
  109.      E=0;            //當(dāng)E由高電平跳變成低電平時(shí),液晶模塊開始執(zhí)行命令
  110. }
  111. /*****************************************************
  112. 函數(shù)功能:對(duì)LCD的顯示模式進(jìn)行初始化設(shè)置
  113. ***************************************************/
  114. void LcdInitiate(void)
  115. {
  116.     delaynms(15);               //延時(shí)15ms,首次寫指令時(shí)應(yīng)給LCD一段較長(zhǎng)的反應(yīng)時(shí)間
  117.     WriteInstruction(0x38);     //顯示模式設(shè)置:16×2顯示,5×7點(diǎn)陣,8位數(shù)據(jù)接口
  118.     delaynms(5);                //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
  119.     WriteInstruction(0x38);
  120.     delaynms(5);               //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
  121.     WriteInstruction(0x38);     //連續(xù)三次,確保初始化成功
  122.     delaynms(5);               //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
  123.     WriteInstruction(0x0c);     //顯示模式設(shè)置:顯示開,無光標(biāo),光標(biāo)不閃爍
  124.     delaynms(5);               //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
  125.     WriteInstruction(0x06);     //顯示模式設(shè)置:光標(biāo)右移,字符不移
  126.     delaynms(5);                //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
  127.     WriteInstruction(0x01);     //清屏幕指令,將以前的顯示內(nèi)容清除
  128.     delaynms(5);             //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間

  129. }
  130. /**************************************************************************
  131. 以下是電壓顯示的說明
  132. **************************************************************************/
  133. /*****************************************************
  134. 函數(shù)功能:顯示電壓符號(hào)
  135. ***************************************************/   
  136. void display_volt(void)
  137. {
  138.     unsigned char i;
  139.      WriteAddress(0x03);    //寫顯示地址,將在第2行第1列開始顯示
  140.      i = 0;                //從第一個(gè)字符開始顯示
  141.      while(Str[i] != '\0')  //只要沒有寫到結(jié)束標(biāo)志,就繼續(xù)寫
  142.       {                        
  143.          WriteData(Str[i]);   //將字符常量寫入LCD
  144.          i++;                 //指向下一個(gè)字符               
  145.         }   
  146. }
  147. void display_volt2(void)
  148. {
  149.     unsigned char i;
  150.      WriteAddress(0x43);    //寫顯示地址,將在第2行第1列開始顯示
  151.      i = 0;                //從第一個(gè)字符開始顯示
  152.      while(Str[i] != '\0')  //只要沒有寫到結(jié)束標(biāo)志,就繼續(xù)寫
  153.       {                        
  154.          WriteData(Str[i]);   //將字符常量寫入LCD
  155.          i++;                 //指向下一個(gè)字符               
  156.         }   
  157. }

  158. /*****************************************************
  159. 函數(shù)功能:顯示電壓的小數(shù)點(diǎn)
  160. ***************************************************/   
  161. void display_dot(void)
  162. {         
  163.      WriteAddress(0x09);      //寫顯示地址,將在第1行第10列開始顯示           
  164.      WriteData('.');       //將小數(shù)點(diǎn)的字符常量寫入LCD        
  165. }
  166. void display_dot2(void)
  167. {         
  168.      WriteAddress(0x49);      //寫顯示地址,將在第1行第10列開始顯示           
  169.      WriteData('.');       //將小數(shù)點(diǎn)的字符常量寫入LCD        
  170. }
  171. /*****************************************************
  172. 函數(shù)功能:顯示電壓的單位(V)
  173. ***************************************************/   
  174. void  display_V(void)
  175. {
  176.     WriteAddress(0x0c); //寫顯示地址,將在第2行第13列開始顯示   
  177.      WriteData('V');     //將字符常量寫入LCD            
  178.             
  179. }
  180. void  display_V2(void)
  181. {
  182.     WriteAddress(0x4c); //寫顯示地址,將在第2行第13列開始顯示   
  183.      WriteData('V');     //將字符常量寫入LCD            
  184.             
  185. }
  186. /*****************************************************
  187. 函數(shù)功能:顯示電壓的整數(shù)部分
  188. 入口參數(shù):x
  189. ***************************************************/
  190. void display1(unsigned char x)
  191. {

  192.     WriteAddress(0x08);    //寫顯示地址,將在第2行第7列開始顯示
  193.     WriteData(digit[x]);    //將百位數(shù)字的字符常量寫入LCD
  194. }
  195. void display1_2(unsigned char x)
  196. {

  197.     WriteAddress(0x48);    //寫顯示地址,將在第2行第7列開始顯示
  198.     WriteData(digit[x]);    //將百位數(shù)字的字符常量寫入LCD
  199. }
  200. /*****************************************************
  201. 函數(shù)功能:顯示電壓的小數(shù)數(shù)部分
  202. 入口參數(shù):x
  203. ***************************************************/
  204. void display2(unsigned char x)
  205. {
  206.      unsigned char i,j;
  207.     i=x/10;            //取十位(小數(shù)點(diǎn)后第一位)
  208.     j=x%10;            //取個(gè)位(小數(shù)點(diǎn)后第二位)
  209.    WriteAddress(0x0a);      //寫顯示地址,將在第1行第11列開始顯示
  210.     WriteData(digit[i]);     //將小數(shù)部分的第一位數(shù)字字符常量寫入LCD
  211.     WriteData(digit[j]);     //將小數(shù)部分的第一位數(shù)字字符常量寫入LCD
  212. }
  213. void display2_2(unsigned char x)
  214. {
  215.      unsigned char i,j;
  216.     i=x/10;            //取十位(小數(shù)點(diǎn)后第一位)
  217.     j=x%10;            //取個(gè)位(小數(shù)點(diǎn)后第二位)
  218.    WriteAddress(0x4a);      //寫顯示地址,將在第1行第11列開始顯示
  219.     WriteData(digit[i]);     //將小數(shù)部分的第一位數(shù)字字符常量寫入LCD
  220.     WriteData(digit[j]);     //將小數(shù)部分的第一位數(shù)字字符常量寫入LCD
  221. }
  222. /*****************************************************
  223. 函數(shù)功能:將模擬信號(hào)轉(zhuǎn)換成數(shù)字信號(hào)
  224. ***************************************************/
  225. unsigned char  A_D()
  226. {
  227.   unsigned char i,dat;
  228.    CS=1;   //一個(gè)轉(zhuǎn)換周期開始
  229.    CLK=0;  //為第一個(gè)脈沖作準(zhǔn)備
  230.    CS=0;  //CS置0,片選有效

  231.    DIO=1;    //DIO置1,規(guī)定的起始信號(hào)  
  232.    CLK=1;   //第一個(gè)脈沖
  233.    CLK=0;   //第一個(gè)脈沖的下降沿,此前DIO必須是高電平
  234.    DIO=1;   //DIO置1, 通道選擇信號(hào)  
  235.    CLK=1;   //第二個(gè)脈沖,第2、3個(gè)脈沖下沉之前,DI必須跟別輸入兩位數(shù)據(jù)用于選擇通道,這里選通道CH0
  236.    CLK=0;   //第二個(gè)脈沖下降沿
  237.    DIO=0;   //DI置0,選擇通道0
  238.    CLK=1;    //第三個(gè)脈沖
  239.    CLK=0;    //第三個(gè)脈沖下降沿
  240.    DIO=1;    //第三個(gè)脈沖下沉之后,輸入端DIO失去作用,應(yīng)置1
  241.    CLK=1;    //第四個(gè)脈沖
  242.    for(i=0;i<8;i++)  //高位在前
  243.     {
  244.       CLK=1;         //第四個(gè)脈沖
  245.       CLK=0;
  246.       dat<<=1;       //將下面儲(chǔ)存的低位數(shù)據(jù)向右移
  247.         dat|=(unsigned char)DIO;      //將輸出數(shù)據(jù)DIO通過或運(yùn)算儲(chǔ)存在dat最低位
  248.     }                     
  249.     CS=1;          //片選無效
  250.      return dat;     //將讀書的數(shù)據(jù)返回     
  251.   }


復(fù)制代碼

全部資料51hei下載地址:
基于ADC0832的數(shù)字電壓表.zip (80.33 KB, 下載次數(shù): 150)

回復(fù)

使用道具 舉報(bào)

ID:236933 發(fā)表于 2024-1-15 17:43 | 顯示全部樓層
為什么測(cè)試發(fā)現(xiàn),任意調(diào)節(jié)一個(gè)滑動(dòng)變阻器,LCD顯示的兩個(gè)通道的電壓值會(huì)一起變動(dòng)為一個(gè)值
回復(fù)

使用道具 舉報(bào)

ID:1108782 發(fā)表于 2024-1-16 09:24 | 顯示全部樓層
芯片通信時(shí)序的第二第三個(gè)脈沖代表通道,你只選了通道0。還有你主函數(shù)呢?
回復(fù)

使用道具 舉報(bào)

ID:1118930 發(fā)表于 2025-4-20 01:37 | 顯示全部樓層
筱豆先生 發(fā)表于 2024-1-15 17:43
為什么測(cè)試發(fā)現(xiàn),任意調(diào)節(jié)一個(gè)滑動(dòng)變阻器,LCD顯示的兩個(gè)通道的電壓值會(huì)一起變動(dòng)為一個(gè)值

代碼是對(duì)的,,但是我改變選擇通道和差分功能的電平改變還是不行,永遠(yuǎn)都是”將CH0作為正輸入端IN+,CH1作為負(fù)輸入端IN-進(jìn)行輸入“。。。。。服了,這到底怎么回事,大概率推測(cè)是ADC0832的問題。。煩,你怎么解決呢?
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表