【Proteus仿真】51单片机+DAC0832+LCD1602制作LM317数控直流电源
【Proteus仿真】51单片机+DAC0832+LCD1602制作LM317简易数控直流电源
- 🎬Proteus仿真

✨需要注意的是:当电压调低时,实际显示的电压值和LM317输出值有1.2V的差异,不是很准确。
DAC0832简略介绍
DAC0832是8位的D/A转换集成芯片.
- VREF:基准电压输入引脚,VREF的范围为-10V~+10V;
- Vcc:电源输入端,Vcc的范围为:+5V~+15V;
- IOUT1:电流输出端1,其值随DAC寄存器的内容线性变化;
- IOUT2:电流输出端2,其值与IOUT1值之和为一常数;
📝示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
| #include <reg51.h> #include<string.h>
typedef unsigned char u8; // 重命名类型u8简化代码编写 typedef unsigned int u16;
#define LCD1602\_DATA\_PORT P2 // LCD1602的8位数据端口
sbit gLcd1602_E = P3^2; // LCD1602控制总线的使能信号 sbit gLcd1602_RW = P3^1; // LCD1602控制总线的读写选择信号 sbit gLcd1602_RS = P3^0; // LCD1602控制总线的数据/命令选择信号
sbit Key1 = P3^5; sbit Key2 = P3^7;
float Output_DA = 200;
void delay10ms(void) { unsigned char a,b,c; for(c=1;c>0;c--) for(b=38;b>0;b--) for(a=130;a>0;a--); }
void Lcd1602WaitNoBusy(void) //忙检测函数,判断bit7是0,允许执行;1禁止 { unsigned char sta = 0; //
LCD1602_DATA_PORT = 0xff; gLcd1602_RS = 0; gLcd1602_RW = 1; do { gLcd1602_E = 1; sta = LCD1602_DATA_PORT; gLcd1602_E = 0; //使能,用完就拉低,释放总线 }while(sta & 0x80); }
void Lcd1602WriteCmd(unsigned char cmd) { Lcd1602WaitNoBusy(); // 先等待LCD1602处于不忙状态
gLcd1602_E = 0; // 禁止LCD gLcd1602_RS = 0; // 选择发送命令模式 gLcd1602_RW = 0; // 选择写入模式 LCD1602_DATA_PORT = cmd; // 将1字节命令字放入8位并行数据端口 gLcd1602_E = 1; // 使能LED gLcd1602_E = 0; // 禁止LCD }
void Lcd1602WriteData(unsigned char dat) { Lcd1602WaitNoBusy(); // 先等待LCD1602处于不忙状态
gLcd1602_E = 0; // 禁止LCD gLcd1602_RS = 1; // 选择发送数据模式 gLcd1602_RW = 0; // 选择写入模式 LCD1602_DATA_PORT = dat; // 将1字节命令字放入8位并行数据端口 gLcd1602_E = 1; // 使能LED gLcd1602_E = 0; // 禁止LCD }
void Lcd1602SetCursor(unsigned char x,unsigned char y) // 坐标显示 { unsigned char addr = 0;
switch (y) { case 0: // 上面一行 addr = 0x00 + x; break; case 1: // 下面一行 addr = 0x40 + x; break; default: break; } Lcd1602WriteCmd(addr | 0x80); }
void Lcd1602ShowStr(unsigned char x, unsigned char y, unsigned char \*pStr) //显示字符串 { Lcd1602SetCursor(x, y); //当前字符的坐标 while (\*pStr != '\0') { Lcd1602WriteData(\*pStr++); } }
void Lcd1602Init(void) { Lcd1602WriteCmd(0x38); // 按照数据手册的初始化时序,先发送38H delay10ms(); // 延时10ms Lcd1602WriteCmd(0x38); // 按照数据手册的初始化时序,先发送38H delay10ms(); // 延时10ms Lcd1602WriteCmd(0x38); // 按照数据手册的初始化时序,先发送38H delay10ms(); // 延时10ms Lcd1602WriteCmd(0x38); // 显示模式设置 Lcd1602WriteCmd(0x08); // 关闭显示 Lcd1602WriteCmd(0x01); // 清屏(同时清数据指针) Lcd1602WriteCmd(0x06); // 读写后指针自动加1,写1个字符后整屏显示不移动 Lcd1602WriteCmd(0x0c); // 开显示,不显示光标 Lcd1602ShowStr(2,0,"NC ADJ POWER "); Lcd1602ShowStr(0,1,"Voltage: V"); }
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* 显示函数 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ void Write\_Volt(unsigned char hang,unsigned char add,unsigned int date) //用于显示 { if(hang==1) Lcd1602WriteCmd(0x80+add); else Lcd1602WriteCmd(0x80+0x40+add); Lcd1602WriteData(0x30+date%1000/100); //显示百位 Lcd1602WriteData(0x30+date%100/10); //显示十位 Lcd1602WriteData('.'); //显示. Lcd1602WriteData(0x30+date%10); //显示个位 Lcd1602WriteData('V'); //显示字母V }
void Out\_Volt(unsigned char Volt) { P0=Volt; }
void main() { Lcd1602Init(); while (1) { Out\_Volt(Output_DA); if (Key1 == 0) { delay10ms(); if (Key1 == 0) { if(Output_DA < 200) Output_DA += 2; } while(!Key1); } if (Key2 == 0) { delay10ms(); if (Key2 == 0) { if(Output_DA >= 2) Output_DA -= 2; } while(!Key2); } Write\_Volt(0,8,Output_DA/2.0); } }
|
程序源码和仿真资源
1 2 3
| 链接:https://pan.baidu.com/s/1ByxFQLLneV9XNUqZ\_A0ioA 提取码:exs0
|
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!