#include<reg51.h> #include<intrins.h> #define uchar unsigned char #define uint unsigned int #define FILTER_SIZE 4 static uchar filter_buffer[FILTER_SIZE]; static uchar filter_index = 0; sbit s1=P3^5; // 频率+/幅度+ sbit s2=P3^6; // 频率-/幅度- sbit s3=P3^7; // 模式切换 sbit s4=P3^4; // 波形切换 char num, u,boxing; int pinlv = 1000; uchar fudu = 4; // 幅度值1-10对应0.25V-2.5V #define DAC_REF 5.0 #define DAC_SCALE (255.0 / DAC_REF) // 51 per Volt unsigned long int m; int a, b, h; // 波形数据定义 uchar code zifu[] = { 0x0e, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x0e, 0x00, }; uchar code juxing[256] = { // 前128点为高电平(255),后128点为低电平(0) 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; uchar code sanjiao[256] = { // 从0递增到255(128点),再从255递减到0(128点) 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, 255, 253, 251, 249, 247, 245, 243, 241, 239, 237, 235, 233, 231, 229, 227, 225, 223, 221, 219, 217, 215, 213, 211, 209, 207, 205, 203, 201, 199, 197, 195, 193, 191, 189, 187, 185, 183, 181, 179, 177, 175, 173, 171, 169, 167, 165, 163, 161, 159, 157, 155, 153, 151, 149, 147, 145, 143, 141, 139, 137, 135, 133, 131, 129, 127, 125, 123, 121, 119, 117, 115, 113, 111, 109, 107, 105, 103, 101, 99, 97, 95, 93, 91, 89, 87, 85, 83, 81, 79, 77, 75, 73, 71, 69, 67, 65, 63, 61, 59, 57, 55, 53, 51, 49, 47, 45, 43, 41, 39, 37, 35, 33, 31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1 }; uchar code juchi[256] = { // 从0线性递增到255(256点) 0,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,157,158,159, 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 }; // 串口初始化 void init_serial() { TMOD |= 0x21; // T1模式2, T0模式1 TH1 = 0xFD; // 9600波特率(11.0592MHz) TL1 = 0xFD; SCON = 0x50; // 串口模式1,允许接收 TR1 = 1; // 启动T1 ES = 1; // 允许串口中断 EA = 1; // 总中断允许 } void delay(uint xms) { int a, b; for (a = xms; a > 0; a--) for (b = 110; b > 0; b--); } // 滤波函数 uchar filter(uchar value) { uchar sum = 0; int i; filter_buffer[filter_index] = value; filter_index = (filter_index + 1) % FILTER_SIZE; for (i = 0; i < FILTER_SIZE; i++) { sum += filter_buffer[i]; } return sum / FILTER_SIZE; } void keyscan() { if (s1 == 0) { delay(5); if (s1 == 0) { while(!s1); if (h == 0) { // 频率调整 pinlv += 100; if (pinlv > 10000) pinlv = 1000; } else { // 幅度调整 fudu += 1; if (fudu > 10) fudu = 1; } } } if (s2 == 0) { delay(5); if (s2 == 0) { while(!s2); if (h == 0) { pinlv -= 100; if (pinlv < 1000) pinlv = 1000; } else { fudu -= 1; if (fudu < 1) fudu = 1; } } } // 波形切换 // 波形切换(S4) if(s4==0) { delay(5); if(s4==0) { while(!s4); boxing++; if(boxing>=3) boxing=0; } } } // 模式切换 void fudujiance() { if (s3 == 0) { delay(5); if (s3 == 0) { while(!s3); h = 1 - h; // 切换模式 if (h == 0) { } else { } } } } void main() { init_serial(); // 初始化串口 TMOD |= 0x01; // T0模式1 TH0 = (65536 - 1000) / 256; TL0 = (65536 - 1000) % 256; ET0 = 1; TR0 = 1; EA = 1; while(1) { keyscan(); fudujiance(); // 波形输出 switch (boxing) { case 0: P1 = filter((juxing[u] * fudu) / 30); break; case 1: P1 = filter((sanjiao[u] * fudu) / 30); break; case 2: P1 = filter((juchi[u] * fudu) / 30); break; } } } // 定时器T0中断(波形生成) void T0_time() interrupt 1 { static unsigned long last_time = 0; unsigned long current_time = (65536 - (12000000UL / pinlv)); // 只有当时间差大于一定阈值时才更新定时器 if (current_time - last_time >= 1) { TH0 = current_time / 256; TL0 = current_time % 256; last_time = current_time; SBUF = P1; // 发送数据到上位机 while (!TI); TI = 0; u++; if (u >= 256) u = 0; } } // 串口中断(接收控制指令) void serial() interrupt 4 { uchar cmd = SBUF; if(RI) { RI = 0; switch(cmd) { case 'F': // 设置频率 while(!RI); RI = 0; pinlv = SBUF << 8; while(!RI); RI = 0; pinlv |= SBUF; break; case 'A': // 设置幅度 while(!RI); RI = 0; fudu = SBUF; break; case 'W': // 设置波形 while(!RI); RI = 0; boxing = SBUF; break; } } }运行该代码仿真时没有波形生成啊,使用的是DAC0832是这个造成的吗
时间: 2025-06-02 18:39:24 浏览: 58
### 题目重述
运行提供的代码进行仿真时没有波形生成。请分析原因并提供解决方案,特别是考虑是否由DAC0832造成的问题。
### 代码解析
提供的代码实现了基于51单片机的波形发生器,能够生成不同类型的波形并通过串口发送数据到上位机。但是仿真时没有波形生成,这可能是由于以下几个方面的原因:
1. **DAC0832连接问题**:代码中没有明确说明DAC0832的连接和配置,可能导致波形数据无法正确输出。
2. **定时器中断和波形生成逻辑问题**:波形生成逻辑可能存在错误,导致数据没有正确输出。
3. **仿真环境配置问题**:仿真环境中可能缺少必要的硬件配置或仿真参数设置不正确。
### 分析与解决方案
#### 1. 确认DAC0832连接与配置
DAC0832是一个8位D/A转换器,通常需要三个控制引脚:`CS`(片选)、`WR`(写入)、`XFER`(数据传输)。确保这些引脚正确连接,并在代码中正确配置。
##### DAC0832配置示例
```c
sbit CS = P2^0; // CS引脚连接到P2.0
sbit WR = P2^1; // WR引脚连接到P2.1
sbit XFER = P2^2; // XFER引脚连接到P2.2
void dac_write(uchar value) {
CS = 0; // 片选有效
P0 = value; // 将波形数据输出到P0口
WR = 0; // 写入有效
WR = 1; // 写入无效
CS = 1; // 片选无效
}
```
#### 2. 优化波形生成逻辑
确保波形生成逻辑正确,并且数据能够正确输出到DAC。在定时器中断中添加DAC输出逻辑。
```c
// 定时器T0中断(波形生成)
void T0_time() interrupt 1 {
static unsigned long last_time = 0;
unsigned long current_time = (65536 - (12000000UL / pinlv));
// 只有当时间差大于一定阈值时才更新定时器
if (current_time - last_time >= 1) {
TH0 = current_time / 256;
TL0 = current_time % 256;
last_time = current_time;
// 波形生成
uchar wave_value;
switch (boxing) {
case 0: wave_value = (juxing[u] * fudu) / 30; break;
case 1: wave_value = (sanjiao[u] * fudu) / 30; break;
case 2: wave_value = (juchi[u] * fudu) / 30; break;
default: wave_value = 0; break;
}
// 滤波处理
uchar filtered_value = filter(wave_value);
// 输出到DAC
dac_write(filtered_value);
// 发送数据到上位机
SBUF = filtered_value;
while (!TI);
TI = 0;
u++;
if (u >= 256) u = 0;
}
}
```
#### 3. 确保仿真环境配置正确
- **硬件连接**:确保仿真环境中正确配置了DAC0832的连接。
- **波特率和串口配置**:确保仿真环境中串口配置正确,波特率匹配(9600)。
- **时钟源配置**:确保仿真环境中时钟源配置正确(11.0592 MHz)。
#### 4. 完整代码
以下是整合了DAC0832配置和优化波形生成逻辑的完整代码:
```c
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define FILTER_SIZE 4
static uchar filter_buffer[FILTER_SIZE];
static uchar filter_index = 0;
sbit s1 = P3^5; // 频率+/幅度+
sbit s2 = P3^6; // 频率-/幅度-
sbit s3 = P3^7; // 模式切换
sbit s4 = P3^4; // 波形切换
sbit CS = P2^0; // DAC0832 CS引脚连接到P2.0
sbit WR = P2^1; // DAC0832 WR引脚连接到P2.1
sbit XFER = P2^2; // DAC0832 XFER引脚连接到P2.2
char num, u = 0, boxing = 0;
int pinlv = 1000;
uchar fudu = 4; // 幅度值1-10对应0.25V-2.5V
#define DAC_REF 5.0
#define DAC_SCALE (255.0 / DAC_REF) // 51 per Volt
unsigned long int m;
int a, b, h = 0;
// 波形数据定义
uchar code juxing[256] = {
// 前128点为高电平(255),后128点为低电平(0)
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
uchar code sanjiao[256] = {
// 从0递增到255(128点),再从255递减到0(128点)
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94,
96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126,
128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158,
160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190,
192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222,
224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254,
255, 253, 251, 249, 247, 245, 243, 241, 239, 237, 235, 233, 231, 229, 227, 225,
223, 221, 219, 217, 215, 213, 211, 209, 207, 205, 203, 201, 199, 197, 195, 193,
191, 189, 187, 185, 183, 181, 179, 177, 175, 173, 171, 169, 167, 165, 163, 161,
159, 157, 155, 153, 151, 149, 147, 145, 143, 141, 139, 137, 135, 133, 131, 129,
127, 125, 123, 121, 119, 117, 115, 113, 111, 109, 107, 105, 103, 101, 99, 97,
95, 93, 91, 89, 87, 85, 83, 81, 79, 77, 75, 73, 71, 69, 67, 65,
63, 61, 59, 57, 55, 53, 51, 49, 47, 45, 43, 41, 39, 37, 35, 33,
31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1
};
uchar code juchi[256] = {
// 从0线性递增到255(256点)
0,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,157,158,159,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
};
// 串口初始化
void init_serial() {
TMOD |= 0x21; // T1模式2, T0模式1
TH1 = 0xFD; // 9600波特率(11.0592MHz)
TL1 = 0xFD;
SCON = 0x50; // 串口模式1,允许接收
TR1 = 1; // 启动T1
ES = 1; // 允许串口中断
EA = 1; // 总中断允许
}
void delay(uint xms) {
int a, b;
for (a = xms; a > 0; a--)
for (b = 110; b > 0; b--);
}
// 滤波函数
uchar filter(uchar value) {
uchar sum = 0;
int i;
filter_buffer[filter_index] = value;
filter_index = (filter_index + 1) % FILTER_SIZE;
for (i = 0; i < FILTER_SIZE; i++) {
sum += filter_buffer[i];
}
return sum / FILTER_SIZE;
}
void dac_write(uchar value) {
CS = 0; // 片选有效
P0 = value; // 将波形数据输出到P0口
WR = 0; // 写入有效
WR = 1; // 写入无效
CS = 1; // 片选无效
}
void keyscan() {
if (s1 == 0) {
delay(5);
if (s1 == 0) {
while(!s1);
if (h == 0) { // 频率调整
pinlv += 100;
if (pinlv > 10000) pinlv = 1000;
} else { // 幅度调整
fudu += 1;
if (fudu > 10) fudu = 1;
}
}
}
if (s2 == 0) {
delay(5);
if (s2 == 0) {
while(!s2);
if (h == 0) {
pinlv -= 100;
if (pinlv < 1000) pinlv = 1000;
} else {
fudu -= 1;
if (fudu < 1) fudu = 1;
}
}
}
// 波形切换
if (s4 == 0) {
delay(5);
if (s4 == 0) {
while(!s4);
boxing++;
if (boxing >= 3) boxing = 0;
}
}
}
void fudujiance() {
if (s3 == 0) {
delay(5);
if (s3 == 0) {
while(!s3);
h = 1 - h; // 切换模式
}
}
}
void main() {
init_serial(); // 初始化串口
TMOD |= 0x01; // T0模式1
TH0 = (65536 - 1000) / 256;
TL0 = (65536 - 1000) % 256;
ET0 = 1;
TR0 = 1;
EA = 1;
while (1) {
keyscan();
fudujiance();
}
}
// 定时器T0中断(波形生成)
void T0_time() interrupt 1 {
static unsigned long last_time = 0;
unsigned long current_time = (65536 - (12000000UL / pinlv));
// 只有当时间差大于一定阈值时才更新定时器
if (current_time - last_time >= 1) {
TH0 = current_time / 256;
TL0 = current_time % 256;
last_time = current_time;
// 波形生成
uchar wave_value;
switch (boxing) {
case 0: wave_value = (juxing[u] * fudu) / 30; break;
case 1: wave_value = (sanjiao[u] * fudu) / 30; break;
case 2: wave_value = (juchi[u] * fudu) / 30; break;
default: wave_value = 0; break;
}
// 滤波处理
uchar filtered_value = filter(wave_value);
// 输出到DAC
dac_write(filtered_value);
// 发送数据到上位机
SBUF = filtered_value;
while (!TI);
TI = 0;
u++;
if (u >= 256) u = 0;
}
}
// 串口中断(接收控制指令)
void serial() interrupt 4 {
uchar cmd = SBUF;
if (RI) {
RI = 0;
switch (cmd) {
case 'F': // 设置频率
while (!RI); RI = 0;
pinlv = SBUF << 8;
while (!RI); RI = 0;
pinlv |= SBUF;
break;
case 'A': // 设置幅度
while (!RI); RI = 0;
fudu = SBUF;
break;
case 'W': // 设置波形
while (!RI); RI = 0;
boxing = SBUF;
break;
}
}
}
```
### 关键改进点
1. **DAC0832配置**:确保DAC0832的控制引脚正确连接,并编写`dac_write`函数以正确输出波形数据。
2. **波形生成逻辑**:将波形生成逻辑移到定时器中断中,并确保波形数据正确输出到DAC。
3. **仿真环境配置**:确保仿真环境中正确配置了硬件连接和时钟源。
通过这些改进,代码应该能够在仿真环境中正确生成波形,并通过DAC0832输出。如果问题依然存在,请检查仿真环境的具体配置,确保所有硬件连接和参数设置正确无误。
阅读全文
相关推荐



















