標(biāo)題: 可調(diào)單片機(jī)DAC0832電壓源Proteus仿真圖與源程序 [打印本頁(yè)]

作者: subobo    時(shí)間: 2021-12-24 17:46
標(biāo)題: 可調(diào)單片機(jī)DAC0832電壓源Proteus仿真圖與源程序
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機(jī)源程序如下:
  1. #include <reg51.h>
  2. #include<string.h>

  3. typedef unsigned char u8;                 // 重命名類型u8簡(jiǎn)化代碼編寫
  4. typedef unsigned int u16;

  5. #define LCD1602_DATA_PORT         P2                // LCD1602的8位數(shù)據(jù)端口

  6. sbit gLcd1602_E         = P3^2;                // LCD1602控制總線的使能信號(hào)
  7. sbit gLcd1602_RW = P3^1;                // LCD1602控制總線的讀寫選擇信號(hào)
  8. sbit gLcd1602_RS = P3^0;                // LCD1602控制總線的數(shù)據(jù)/命令選擇信號(hào)

  9. sbit Key1 = P3^5;
  10. sbit Key2 = P3^7;

  11. float Output_DA = 200;

  12. void delay10ms(void)   
  13. {
  14.     unsigned char a,b,c;
  15.     for(c=1;c>0;c--)
  16.         for(b=38;b>0;b--)
  17.             for(a=130;a>0;a--);
  18. }

  19. void Lcd1602WaitNoBusy(void)  //忙檢測(cè)函數(shù),判斷bit7是0,允許執(zhí)行;1禁止
  20. {
  21.     unsigned char sta = 0;      //

  22.     LCD1602_DATA_PORT = 0xff;
  23.     gLcd1602_RS = 0;
  24.     gLcd1602_RW = 1;
  25.     do
  26.     {
  27.         gLcd1602_E = 1;
  28.         sta = LCD1602_DATA_PORT;
  29.         gLcd1602_E = 0;    //使能,用完就拉低,釋放總線
  30.     }while(sta & 0x80);
  31. }

  32. void Lcd1602WriteCmd(unsigned char cmd)         
  33. {
  34.         Lcd1602WaitNoBusy();                // 先等待LCD1602處于不忙狀態(tài)

  35.         gLcd1602_E = 0;                     // 禁止LCD
  36.         gLcd1602_RS = 0;                           // 選擇發(fā)送命令模式
  37.         gLcd1602_RW = 0;                           // 選擇寫入模式        
  38.         LCD1602_DATA_PORT = cmd;    // 將1字節(jié)命令字放入8位并行數(shù)據(jù)端口
  39.         gLcd1602_E = 1;                          // 使能LED
  40.         gLcd1602_E = 0;                                // 禁止LCD
  41. }

  42. void Lcd1602WriteData(unsigned char dat)                        
  43. {
  44.         Lcd1602WaitNoBusy();                // 先等待LCD1602處于不忙狀態(tài)

  45.         gLcd1602_E = 0;                     // 禁止LCD
  46.         gLcd1602_RS = 1;                           // 選擇發(fā)送數(shù)據(jù)模式
  47.         gLcd1602_RW = 0;                           // 選擇寫入模式        
  48.         LCD1602_DATA_PORT = dat;    // 將1字節(jié)命令字放入8位并行數(shù)據(jù)端口
  49.         gLcd1602_E = 1;                          // 使能LED
  50.         gLcd1602_E = 0;                                // 禁止LCD
  51. }

  52. void Lcd1602SetCursor(unsigned char x,unsigned char y)          // 坐標(biāo)顯示
  53. {
  54.     unsigned char addr = 0;

  55.            switch (y)
  56.         {
  57.                 case 0:                                                 // 上面一行
  58.                         addr = 0x00 + x;                break;        
  59.                 case 1:                                                // 下面一行
  60.                         addr = 0x40 + x;                 break;
  61.                 default:
  62.                                                                         break;
  63.         }
  64.     Lcd1602WriteCmd(addr | 0x80);
  65. }

  66. void Lcd1602ShowStr(unsigned char x, unsigned char y, unsigned char *pStr)     //顯示字符串
  67. {
  68.     Lcd1602SetCursor(x, y);      //當(dāng)前字符的坐標(biāo)
  69.     while (*pStr != '\0')
  70.     {
  71.         Lcd1602WriteData(*pStr++);
  72.     }
  73. }

  74. void Lcd1602Init(void)                                                
  75. {
  76.          Lcd1602WriteCmd(0x38);          // 按照數(shù)據(jù)手冊(cè)的初始化時(shí)序,先發(fā)送38H
  77.         delay10ms();                                        // 延時(shí)10ms
  78.         Lcd1602WriteCmd(0x38);          // 按照數(shù)據(jù)手冊(cè)的初始化時(shí)序,先發(fā)送38H
  79.         delay10ms();                                        // 延時(shí)10ms
  80.         Lcd1602WriteCmd(0x38);          // 按照數(shù)據(jù)手冊(cè)的初始化時(shí)序,先發(fā)送38H
  81.         delay10ms();                                        // 延時(shí)10ms
  82.         Lcd1602WriteCmd(0x38);                // 顯示模式設(shè)置
  83.         Lcd1602WriteCmd(0x08);                // 關(guān)閉顯示
  84.         Lcd1602WriteCmd(0x01);                // 清屏(同時(shí)清數(shù)據(jù)指針)
  85.         Lcd1602WriteCmd(0x06);                // 讀寫后指針自動(dòng)加1,寫1個(gè)字符后整屏顯示不移動(dòng)
  86.         Lcd1602WriteCmd(0x0c);                // 開顯示,不顯示光標(biāo)
  87.         
  88.         Lcd1602ShowStr(0,0,"OutputVolt:    V");        
  89. }

  90. /*************** 顯示函數(shù) *************************************************/
  91. void Write_Volt(unsigned char hang,unsigned char add,unsigned int date)           //用于顯示
  92. {
  93.         if(hang==1)   
  94.                 Lcd1602WriteCmd(0x80+add);
  95.         else
  96.                 Lcd1602WriteCmd(0x80+0x40+add);
  97.         Lcd1602WriteData(0x30+date%1000/100);         //顯示百位
  98.         Lcd1602WriteData(0x30+date%100/10);                 //顯示十位
  99.         Lcd1602WriteData('.');                                         //顯示.
  100.         Lcd1602WriteData(0x30+date%10);                         //顯示個(gè)位
  101.         Lcd1602WriteData('V');                                         //顯示字母V
  102. }

  103. void Out_Volt(unsigned char Volt)
  104. {                 
  105.         P0=Volt;
  106. }

  107. void main()
  108. {
  109.         Lcd1602Init();
  110.         while (1)
  111.         {
  112.                 Out_Volt(Output_DA);
  113.                
  114.                 if (Key1 == 0)        
  115.                 {
  116.                         delay10ms();               
  117.                         if (Key1 == 0)                        
  118.                         {
  119.                                 if(Output_DA < 200) Output_DA += 2;
  120.                         }               
  121.                         while(!Key1);
  122.                 }
  123.                 if (Key2 == 0)        
  124.                 {
  125.                         delay10ms();               
  126.                         if (Key2 == 0)                        
  127.                         {
  128.                                 if(Output_DA >= 2) Output_DA -= 2;
  129.                         }                        
  130.                         while(!Key2);
  131.                 }
  132.                
  133.                 Write_Volt(1,11,Output_DA/2.0);
  134.         }         
  135. }
復(fù)制代碼

Keil代碼與Proteus仿真下載:
電壓源DAC0832-1602-LM317.zip (144.66 KB, 下載次數(shù): 104)

作者: sioon77    時(shí)間: 2023-3-15 20:58
很好的貼子頂一下,不過這個(gè)顯示用LCD浪費(fèi)了,數(shù)碼管足矣




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