生成一个设计一个基于51单片机的数控电流源,具有可预设电流,电流步进,显示电流的功能,系统工作原理为:通过键盘设定输出电流,讲设定值通过DAC0832转换为模拟电压,送至恒流源电路产生恒定电流,另外,对输出恒定电流进行采样,送至ADC0832转换为数字电流,与设定的电流相比较,单片机根据比较调整D/A转换值。从而实现对恒流源输出电流的闭环调节,使输出电流能实时跟随设定值。采用具有反馈控制的闭环控制系统,提高了反应速度和精度,能够使误差保持在较低的水平的代码
时间: 2024-02-25 17:56:10 浏览: 18
这是一个非常具体和专业的问题,需要较为深入的电路和程序设计知识才能回答。以下是一个基本的代码框架:
```
#include <reg51.h>
// 定义 DAC0832 和 ADC0832 的引脚
sbit DAC_CS = P2^4;
sbit ADC_CS = P2^5;
sbit DAC_SCL = P2^1;
sbit DAC_SDA = P2^0;
sbit ADC_CLK = P2^1;
sbit ADC_DIN = P2^0;
sbit ADC_DOUT = P2^2;
// 定义数码管显示引脚
sbit LED_A = P1^0;
sbit LED_B = P1^1;
sbit LED_C = P1^2;
sbit LED_D = P1^3;
sbit LED_E = P1^4;
sbit LED_F = P1^5;
sbit LED_G = P1^6;
sbit LED_DP = P1^7;
// 定义按键输入引脚
sbit KEY_1 = P3^0;
sbit KEY_2 = P3^1;
sbit KEY_3 = P3^2;
sbit KEY_4 = P3^3;
// 定义电流步进值和电流范围
#define STEP 0.1
#define MAX_CURRENT 10.0
#define MIN_CURRENT 0.0
// 定义 DAC0832 输出电压的计算公式
#define DAC_OUT(x) (x) / 10.0 * 255.0 / 5.0
// 定义 ADC0832 输入电流的计算公式
#define ADC_IN(x) (x) * 5.0 / 255.0 * 10.0
// 定义按键扫描函数
unsigned char key_scan()
{
unsigned char key_val = 0xff;
if (!KEY_1) key_val = 0;
if (!KEY_2) key_val = 1;
if (!KEY_3) key_val = 2;
if (!KEY_4) key_val = 3;
return key_val;
}
// 定义 DAC0832 的写入函数
void dac_write(unsigned char val)
{
unsigned char i;
DAC_CS = 0;
for (i = 0; i < 8; i++)
{
DAC_SCL = 0;
if (val & 0x80)
{
DAC_SDA = 1;
}
else
{
DAC_SDA = 0;
}
val <<= 1;
DAC_SCL = 1;
}
DAC_CS = 1;
}
// 定义 ADC0832 的读取函数
unsigned char adc_read()
{
unsigned char i, val = 0;
ADC_CS = 0;
ADC_CLK = 0;
ADC_DIN = 1;
for (i = 0; i < 8; i++)
{
ADC_CLK = 1;
ADC_CLK = 0;
val <<= 1;
if (ADC_DOUT)
{
val |= 0x01;
}
}
ADC_CS = 1;
return val;
}
// 定义主函数
void main()
{
float set_current = 0.0;
float cur_current = 0.0;
unsigned char cur_dac = 0;
unsigned char cur_adc = 0;
unsigned char cur_digit = 0;
unsigned char cur_key = 0xff;
while (1)
{
// 按键扫描
cur_key = key_scan();
if (cur_key != 0xff)
{
if (cur_key == 0)
{
set_current += STEP;
if (set_current > MAX_CURRENT)
{
set_current = MAX_CURRENT;
}
}
else if (cur_key == 1)
{
set_current -= STEP;
if (set_current < MIN_CURRENT)
{
set_current = MIN_CURRENT;
}
}
}
// DAC0832 输出电压值计算
cur_dac = DAC_OUT(set_current);
dac_write(cur_dac);
// ADC0832 读取电流值
cur_adc = adc_read();
cur_current = ADC_IN(cur_adc);
// 数码管显示电流值
cur_digit = (unsigned char)(cur_current * 10);
LED_A = (cur_digit == 1 || cur_digit == 4) ? 0 : 1;
LED_B = (cur_digit == 5 || cur_digit == 6) ? 0 : 1;
LED_C = (cur_digit == 2) ? 0 : 1;
LED_D = (cur_digit == 1 || cur_digit == 4 || cur_digit == 7) ? 0 : 1;
LED_E = (cur_digit == 1 || cur_digit == 3 || cur_digit == 4 || cur_digit == 7) ? 0 : 1;
LED_F = (cur_digit == 0 || cur_digit == 1 || cur_digit == 7) ? 0 : 1;
LED_G = (cur_digit == 1 || cur_digit == 3 || cur_digit == 4 || cur_digit == 5 || cur_digit == 7 || cur_digit == 9) ? 0 : 1;
LED_DP = 0;
}
}
```
需要注意的是,这只是一个简单的代码框架,具体实现还需要根据实际情况进行调整和优化。同时,为了保证安全和可靠性,这个任务需要经过严密的测试和调试,如果你没有相关的经验和知识,最好不要尝试自己进行设计和制作。建议你可以请专业的电路设计师和程序员来完成这个任务。