基于51单片机控制的波形输出

2023-05-16

介绍

本模块采用PCF8591,它是一款AD-DA集成芯片。所以本节对iic通信协议不做过多的介绍,重心放在iic的rtl建模,本次通过iic控制PCF8591实现DAC输出功能。及输出波形 将数字量转为模拟量通过矩阵按键 可以进行调节模式 设定频率的大小,数值可以在lcd屏幕上进行显示。

pcf8951

原理图

在这里插入图片描述

 

附控制程序

uchar code SinWave[] = {	 //正弦波波表
	127,133,139,145,151,158,164,170,175,181,
	187,192,198,203,208,212,217,221,225,229,
	233,236,239,242,245,247,249,251,252,253,
	254,254,255,254,254,253,252,251,249,247,
	245,242,239,236,233,229,225,221,217,212,
	208,203,198,192,187,181,175,170,164,158,
	151,145,139,133,127,120,114,108,102,95,
	89,83,78,72,66,61,55,50,45,41,
	36,32,28,24,20,17,14,11,8,6,
	4,2,1,1,0,0,0,0,0,1,
	1,2,4,6,8,11,14,17,20,24,
	28,32,36,41,45,50,55,61,66,72,
	78,83,89,95,102,108,114,120
};

uchar code TriWave[] = {  //三角波波表
	0,4,8,12,16,20,24,28,32,36,
	40,44,48,52,56,60,64,68,72,76,
	80,84,88,92,96,100,104,108,112,116,
	120,124,128,132,136,140,144,148,152,156,
	160,164,168,172,176,180,184,188,192,196,
	200,204,208,212,216,220,224,228,232,236,
	240,244,248,252,255,252,248,244,240,236,
	232,228,224,220,216,212,208,204,200,196,
	192,188,184,180,176,172,168,164,160,156,
	152,148,144,140,136,132,128,124,120,116,
	112,108,104,100,96,92,88,84,80,76,
	72,68,64,60,56,52,48,44,40,36,
	32,28,24,20,16,12,8,4
};

uchar code SawWave[] = {
	0,8,16,24,32,40,48,56,64,72,//锯齿波
	80,88,96,104,112,120,128,136,144,152,
	160,168,176,184,192,200,208,216,224,232,
	240,248,256,264,272,280,288,296,304,312,
	320,328,336,344,352,360,368,376,384,392,
	400,408,416,424,432,440,448,456,464,472,
	480,488,496,504,512,520,528,536,544,552,
	560,568,576,584,592,600,608,616,624,632,
	640,648,656,664,672,680,688,696,704,712,
	720,728,736,744,752,760,768,776,784,792,
	800,808,816,824,832,840,848,856,864,872,
	880,888,896,904,912,920,928,936,944,952,
	960,968,976,984,992,1000,1008,1016
};

uchar code FangWave[] = {
	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	
};

void main()
{
	InitLcd1602();
	EA = 1;//开总中断
	pWave = SinWave;//默认正弦波
	SetWaveFreq(10);//默认频率10Hz
	lastaddend = 10;
	LcdShowStr(0,0,"Zheng Xian Bo");
	LcdShowStr(0,1,"Ping Lv:");
	LcdShowStr(8,1,"10");
	LcdShowStr(11,1,"Hz");//位置不再改变
	TMOD &= 0xf0;
	TMOD |= 0x01;
	TH0 = 0xFC;	//为T0赋初值0xFC67,定时1ms
	TL0 = 0x67;
	ET0 = 1;	//使能T0中断
	TR0 = 1;	//启动T0
	while(1)
	{
		KeyDriver();//调用按键驱动
	}
}

void Shownumber(uchar *str, uchar dat)
{
	signed char i = 0;
	uchar buf[6];

	do {
		buf[i++] = dat % 10;
		dat /= 10;
	}  while (dat > 0);
	while(i-->0)
	{
		*str++ = buf[i] + '0';
	}
	*str = '\0';
}

//进入频率设置
void EnterFreSet()
{
	LcdSetCursor(8, 1);
	LcdOpenCursor();//打开光标
	setIndex = 2;
}

//退出时间设置函数
void ExitFreSet(bit save)
{
	static unsigned long j;
	if (save)
	{	
		if(addend <= 24)
		{
			SetWaveFreq(addend);
			lastaddend = addend;
		}
		else//如果超过范围
		{
			LcdAreaClear(8,1,8);
			LcdShowStr(8, 1, ">24");
			for(j=8000;j>0;j--);
			LcdAreaClear(8,1,8);
			LcdShowStr(11,1,"Hz");
			addend = 0;//清空数值    
			EnterFreSet();
			return;	
		}		
	}
	else//要考虑恢复到上一次的时间
	{
		Shownumber(str,lastaddend);
		LcdAreaClear(8,1,3);
		LcdShowStr(8, 1, str);
	}
	setIndex = 0;
	addend = 0;
	LcdCloseCursor();
	Shownumber(str,setIndex);
	//LcdShowStr(15, 1, str);
}

void KeyAction(uchar keycode)
{
	static uchar cnt = 0;
	static uchar index = 0;
	if ((keycode >= '0') &&(keycode<='9')&&setIndex==2)//进入设置状态
	{
		LcdSetCursor(8, 1+index);
		//LcdOpenCursor();//打开光标
		addend = addend * 10 + (keycode - '0');
		Shownumber(str,addend);
		LcdAreaClear(8,1,3);
		LcdShowStr(8, 1, str);
		index ++;
	}
	else if (keycode == 0x26)
	{
		cnt++;
		if(cnt == 10)
			cnt = 0;
		//在三种波形间循环切换
		if (cnt == 2)
		{
			LcdAreaClear(0,0,16);
			LcdShowStr(0,0,"San Jiao Bo");
			pWave = TriWave;
		}
		else if (cnt == 4)
		{
			LcdAreaClear(0,0,16);
			LcdShowStr(0,0,"Ju Chi Bo");				 
			pWave = SawWave;
		}
		else if (cnt == 6)
		{
			LcdAreaClear(0,0,16);
			LcdShowStr(0,0,"Fang Bo");
			pWave = FangWave;
		}
		else if (cnt == 8)
		{
			LcdAreaClear(0,0,16);
			LcdShowStr(0,0,"Zheng Xian Bo");
			pWave = SinWave;
		}	
	}
	else if (keycode == 0x0d)//回车键
	{
		if (setIndex == 0)//不处于设置状态时,进入设置状态
		{
			EnterFreSet();
		}
		else//已处于设置状态时,保存时间并退出设置
		{
			index = 0;
			ExitFreSet(1);
		}
	}
	else if(setIndex == 2 && keycode == 0x1b)//ESC键
	{
		index = 0;
		ExitFreSet(0);
	}
}


//设置DAC输出值,val-设定值
void SetDACOut(uchar val)
{
	I2CStart();
	if (!I2CWrite(0x48<<1))
	{
		I2CStop();
		return;
	}
	I2CWrite(0x40);
	I2CWrite(val);
	I2CStop();
}
//设置输出波形的频率,freq-设定频率
void SetWaveFreq(uchar freq)
{
	unsigned long tmp;

	tmp = (11059200/12) / (freq*32*3.6);  //这才是频率为10HZ的频率图
	tmp = 65536 - tmp;
	T1RH = (uchar)(tmp>>8);
	T1RL = (uchar) tmp;
	TMOD &= 0x0f;
	TMOD |= 0x10;
	TH1 = T1RH;
	TL1 = T1RL;
	ET1 = 1;
	PT1 = 1;//设置为高优先级
	TR1 = 1;//启动T1	
}

//T1中断服务函数,执行波形输出
void InterruptTimer1() interrupt 3 
{
	static uchar i = 0;

	TH1 = T1RH;
	TL1 = T1RL;
	//循环输出波形中的数据
	SetDACOut(pWave[i]);
	i++;
	if (i >= 128)
	{
		i=0;
	}
}


#include <reg52.h>
#include <intrins.h>

#define uchar unsigned char
#define I2CDelay() {_nop_();_nop_();_nop_();_nop_();}
sbit I2C_SCL = P3^7;
sbit I2C_SDA = P3^6;

extern void LcdShowStr(uchar x, uchar y, uchar *str);

//产生总线起始信号
void I2CStart()
{
	I2C_SDA = 1;//首先确保SDA, SCL都是高电平
	I2C_SCL = 1;
	I2CDelay();
	I2C_SDA = 0;//先拉低SDA
	//起始信号的条件是SCL为高电平期间,SDA由高电平向低电平产生一个下降沿
	I2CDelay();
	I2C_SCL = 0;//再拉低SCL
}

//产生总线停止信号
void I2CStop()
{
	I2C_SCL = 0;//首先要确保SDA, SCL都是低电平
	I2C_SDA = 0;
	I2CDelay();
	I2C_SCL = 1;//先拉高SCL
	I2CDelay();
	I2C_SDA = 1;//再拉高SDA
	//停止信号的条件是SCL为高电平期间,SDA由低电平向高电平产生一个上降沿
	I2CDelay();
}

//I2C总线写操作,dat-待写入字节,返回值-从机应答位的值
bit I2CWrite(uchar dat)
{
	bit ack;
	uchar mask;//用于探测字节内某一位值的掩码变量
	//mask=1000 0000向右进1,即为1100 0000
	for (mask = 0x80; mask!=0; mask>>=1)//从高位到低位依次进行
	{
		if ((mask&dat) == 0)//该为输出到SDA上
			I2C_SDA = 0;
		else
			I2C_SDA = 1;
		I2CDelay();
		I2C_SCL = 1;
		I2CDelay();
		I2C_SCL = 0;
	}
	I2C_SDA = 1;//8位数据发送完后,主机释放SDA,以检测从机应答
	I2CDelay();
	I2C_SCL = 1;//拉高SCL
	ack = I2C_SDA;//读取此时的SDA值,即为从机的应答值
	I2CDelay();
	I2C_SCL = 0;//再拉低SCL完成应答位,并保持住总线
	return (~ack);//返回从机应答值
}


//I2C总线读操作,并发送非应答信号,返回值-读到的字节
uchar I2CReadNAK()
{
    uchar mask;
    uchar dat;

    I2C_SDA = 1;//首先确保主机释放SDA
    for (mask=0x80;mask!=0;mask>>=1)//从高位到低位依次进行    
	{
        I2CDelay();
        I2C_SCL = 1;//拉高SCL
        if (I2C_SDA == 0)//读取SDA的值          
			dat &= ~mask;//为0时,dat对应位清零
        else
            dat |= mask;//为1时,dat对应位置1
        I2CDelay();
        I2C_SCL = 0;//再拉低SCL以使从机发出下一位
    }
    I2C_SDA = 1;//8位数据发送完以后,拉高SDA,产生非应答信号
    I2CDelay();
    I2C_SCL = 1;//拉高SCL
    I2CDelay();
    I2C_SCL = 0;//再拉低SCL完成非应答为位,并保持住总线

    return dat;
}

//I2C总线读操作,并发送应答信号,返回值-读到的字节
uchar I2CReadACK()
{
    uchar mask;
    uchar dat;

    I2C_SDA = 1;//首先确保主机释放SDA
    for (mask=0x80;mask!=0;mask>>=1)//从高位到低位依次进行    
	{
        I2CDelay();
        I2C_SCL = 1;//拉高SCL
        if (I2C_SDA == 0)//读取SDA的值          
			dat &= ~mask;//为0时,dat对应位清零
        else
            dat |= mask;//为1时,dat对应位置1
        I2CDelay();
        I2C_SCL = 0;//再拉低SCL以使从机发出下一位
    }
    I2C_SDA = 0;//8位数据发送完以后,拉高SDA,产生应答信号
    I2CDelay();
    I2C_SCL = 1;//拉高SCL
    I2CDelay();
    I2C_SCL = 0;//再拉低SCL完成非应答为位,并保持住总线

    return dat;
}

#include <reg52.h>

#define uchar unsigned char
#define lcd1602_db P0

sbit lcd1602_rs = P1^0;
sbit lcd1602_rw = P1^1;
sbit lcd1602_e = P1^5;

void LcdWaitReady()
{
	uchar sta;
	lcd1602_db = 0xff;
	lcd1602_rs = 0;
	lcd1602_rw = 1;
	do {
		lcd1602_e = 1;
		sta = lcd1602_db;
		lcd1602_e = 0;
	} while(sta & 0x80);//只是检测是否忙没有执行任何操作,1表示在忙,0表示空闲
}

//向液晶写入一行命令,cmd-待写入命令值
void LcdWriteCmd(uchar cmd)
{
	LcdWaitReady();
	lcd1602_rs = 0;//0为命令
	lcd1602_rw = 0;//0表示写入
	lcd1602_db = cmd;
	lcd1602_e = 1;//产生高脉冲
	lcd1602_e = 0;
}

//向液晶写入一字节数据,dat-待写入数据值
void LcdWriteDat(uchar dat)
{
	LcdWaitReady();
	lcd1602_rs = 1;//1为数据
	lcd1602_rw = 0;//0表示写入
	lcd1602_db = dat;
	lcd1602_e = 1;//产生高脉冲
	lcd1602_e = 0;
}

//设置显示RAM起始地址,亦即光标位置,(x,y)-对应屏幕上的字符坐标
void LcdSetCursor(uchar x, uchar y)
{
	uchar addr;
	if(y==0)
		addr = 0x00 + x;//这意味着第一个显示字符x=0
	else
		addr = 0x40 + x;
	LcdWriteCmd(addr | 0x80);//设置RAM地址
}

/*
//在液晶上显示字符串,和设置函数的功能部分重复
void LcdShowStr(uchar x,uchar y,uchar *str,uchar len)
{
	LcdSetCursor(x, y);	
	while(len--)//通过长度来改变,而静态显示时是通过判断最后一个字符是否为/0,while(*str!='\0')
	{
		LcdWriteDat(*str++);
	}
}
*/

void LcdShowStr(uchar x,uchar y,uchar *str)
{
	LcdSetCursor(x, y);	
	while(*str != '\0')//通过长度来改变,而静态显示时是通过判断最后一个字符是否为/0,while(*str!='\0')
	{
		LcdWriteDat(*str++);
	}
}

//打开光标闪烁效果
void LcdOpenCursor()
{
	LcdWriteCmd(0x0f);
}

//关闭光标显示
void LcdCloseCursor()
{
	LcdWriteCmd(0x0c);
}

//区域清除,清除从(x,y)坐标起始的len个字符位
void LcdAreaClear(uchar x,uchar y,uchar len)
{
	LcdSetCursor(x, y);
	while(len--)
	{
		LcdWriteDat(' ');
	}
} 


//整屏清除
void LcdFullClear()
{
	LcdWriteCmd(0x01);
}


//初始化1602液晶
void InitLcd1602()
{
	LcdWriteCmd(0x38);//写入
	LcdWriteCmd(0x0c);//显示器开,光标关闭
	LcdWriteCmd(0x06);//文字不动,地址自动+1
	LcdWriteCmd(0x01);//清屏操作
}
#include <reg52.h>

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

sbit KEY_IN_1 = P2^3;
sbit KEY_IN_2 = P2^2;
sbit KEY_IN_3 = P2^1;
sbit KEY_IN_4 = P2^0;

sbit KEY_OUT_1 = P2^4;
sbit KEY_OUT_2 = P2^5;
sbit KEY_OUT_3 = P2^6;
sbit KEY_OUT_4 = P2^7;

unsigned char code KeyCodeMap[4][4] = {
	{'1', '2', '3', 0x26},//向上键
	{'4', '5', '6', 0x25},//向左键
	{'7', '8', '9', 0x28},//向下键
	{'0',0x1B, 0x0D, 0x27}//ESC键,回车键,向右键
};

unsigned char KeySta[4][4] = {	//全部矩阵按键的当前状态
	{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
};

extern void KeyAction(unsigned char keycode);

void KeyDriver()
{
	unsigned char i, j;
	static unsigned char backup[4][4] = {	//按键值备份,保存前一次的值
	{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
	};
	for(i=0; i<4; i++)
	{
		for(j=0; j<4; j++)
		{
			if(backup[i][j] != KeySta[i][j])//如果当前值和备份值不同
			{
				if(backup[i][j] != 0)//如果backup[i][j]!=0即当前为按下状态
				{
					//P0 = LedChar[i*4 + j];//将编号显示到数码管
					KeyAction(KeyCodeMap[i][j]);
				}
				backup[i][j] = KeySta[i][j];//更新下一次的备份值
			}
		}
	}	
}

void InterruptTimer0() interrupt 1
{
	unsigned char i;
	static unsigned char keyout = 0;
	static unsigned char keybuf[4][4] = {
	{0xFF,0xFF,0xFF,0xFF}, {0xFF,0xFF,0xFF,0xFF},
	{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF}
	};//初始时全为1

	TH0 = 0xFC;
	TL0 = 0x67;
	//按行扫描,keyout为行数的索引
	keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;
	keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;
	keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;
	keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;

	for(i=0; i<4; i++)
	{
		if ((keybuf[keyout][i] & 0x0F) == 0x00)
		{
			KeySta[keyout][i]=0;
		}
		else if ((keybuf[keyout][i] & 0x0F) == 0x0F)
		{
			KeySta[keyout][i] = 1;
		}
	}
	keyout++;//到下一行
	keyout = keyout & 0x03;//如果行数索引到4则清零,比if更好
	switch(keyout)
	{
		case 0:KEY_OUT_4 = 1; KEY_OUT_1 = 0; break;//为下一次扫描的行做好准备
		case 1:KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;//因为其余两个值为1,因此只需将上一次被扫描的行值赋1
		case 2:KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;
		case 3:KEY_OUT_3 = 1; KEY_OUT_4 = 0; break;
		default: break;
	}
}


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于51单片机控制的波形输出 的相关文章

随机推荐

  • Modbus通信协议

    一 Modbus 协议简介 Modbus 协议是应用于电子控制器上的一种通用语言 通过此协议 xff0c 控制器相互之间 控制器经由网络 xff08 例如以太网 xff09 和其它设备之间可以通信 它已经成为一通用工业标准 有了它 xff0
  • 77组合

    给定两个整数 n 和 k xff0c 返回 1 n 中所有可能的 k 个数的组合 示例 输入 n 61 4 k 61 2 输出 2 4 3 4 2 3 1 2 1 3 1 4 最容易想到的应该是回溯 xff0c 更多题目思路及代码见 xff
  • 结构体内数据元素对齐

    默认情况下 xff0c 为方便结构体内元素的访问于管理 xff0c 当结构体内的数据元素的长度小于处理器的位数的时候 xff0c 便以结构体内的最长数据元素为对齐单位 xff0c 即结构体的长度一定为最长数据元素的长度的整数倍 如果结构体内
  • 关于stm32中串口重定向问题详解(找个时间好好理解下)

    usart这部分代码我也是从网上copy出来的 xff0c 一下是作者的解释 xff1a 简单地说 xff1a 想在mdk 中用printf xff0c 需要同时重定义fputc函数和避免使用semihosting 半主机模式 xff09
  • 缓冲区溢出(buffer overflow)避免方法

    什么是缓冲区溢出 xff1f copy数据进buffer时 xff0c 数据长度超过buffer中的剩余空间 缓冲区溢出的危害 xff1f 缓冲区溢出 xff0c 结果随机 xff0c 可能会导致程序功能不正常 xff0c 也可能导致程序崩
  • 【嵌入式系统应用开发】ROS环境安装配置与入门实操

    目录 前言1 ROS简介2 ROS软件安装2 1 添加ROS软件源2 2 添加密钥2 3 安装ROS2 4 初始化rosdep2 5 设置环境变量2 6 安装rosinstall 3 ROS初试 小海龟3 1 启动ROS Master3 2
  • 头文件包含的合理顺序

    如果包含顺序不当 xff0c 可能出现包含顺序依赖问题 xff0c 甚至引起编译错误 推荐如下顺序 xff1a 在头文件中 xff1a xff08 1 xff09 包含当前工程中所需要的自定义头文件 xff08 顺序自定 xff09 xff
  • windows下使用 SITL 模拟飞行——APM

    1 环境配置 按照官网教程配置环境 xff0c 链接 xff1a https ardupilot org dev docs building setup windows cygwin html building setup windows
  • Nvidia Xavier Nx平台修改CAN时钟调试记录

    1 前言 JETSON NX开发板上配置CAN bus与一个CAN收发器SN65HVD230 要求是改变设备树中的CAN时钟速率 让CAN时钟修改为40MHZ 2 如何设置准确的40MHz 要实现40MHz 首先需要设置CAN父时钟为pll
  • 【CMake】常见目录——10.1安装项目

    CMake中的目录 常见目录所代表的含义 PROJECT SOURCE DIR xff1a 工程的根目录 PROJECT BINARY DIR xff1a 运行cmake命令的目录 xff0c 通常为 PROJECT SOURCE DIR
  • 编译的时候所使用的动态库中出现错误:未定义的引用

    1 使用makefile编译的时候 xff0c 出现错误如下 xff1a 如上图所示 xff0c 是在动态库libicdbapi so中出现了未定义错误 xff0c 既然是未定义错误 xff0c 说明sqlprct sqlnult这5个符号
  • STL1:简介

    STL1 简介 1 背景1 1 STL是什么 xff1f 1 2 STL与C 43 43 标准库的关系1 3 版本 2 STL的组成3 容器分类4 迭代器分类4 1 分类原则 xff1a 访问方式4 2 分类原则 xff1a 操作类型4 3
  • Linux网络编程 5 - select模式的TCP服务器

    为了同时处理多个客户端的连接 xff0c 上一篇介绍了利用多线程的方法实现 xff0c 每个连接新建一个线程 xff0c 然后各自去处理 这是最简单也是最容易想到的方式 客户端的连接存在 xff0c 线程就存在 但是 xff0c 对于每一个
  • c标准库—参考手册

    1 lt errno h gt 2 lt float h gt 3 lt limits h gt 4 lt locale h gt 5 lt math h gt 6 lt signal h gt 7 lt setjmp h gt 8 lt
  • MPU6050

    1 个人总结 常用的MPU6050有八个针脚 xff0c VCC 跟GND 给模块供电 xff0c 模块通讯方式采用IIC通讯 xff0c SCL跟SDA为信号传递通道 xff0c XDA 跟 XCl是用来外接电磁传感器 xff0c 玩过M
  • 自学 Python 第一天

    总结 xff1a 感觉Python 前边学起来 跟c差不多 xff0c 之前学习过c语言 xff0c 但是并没有学这么细 xff0c 刚好学python xff0c 把当时忽略的知识点 重新减一下 打算花费两周学完Python为后续学习Op
  • 多功能悬赏任务平台app+小程序源码开源版搭建开发

    悬赏任务app源码 xff0c 从名字本身就可以理解这个PHP项目的流程 通过在线管理员工任务 即使它也可以在Intranet中工作 MySQL数据库是此源代码的最终部分 它易于实施和遵循 它是所有企业公司的主要项目应用程序 IT公司的任务
  • usart串口发送与接收问题

    项目场景 xff1a 串口通信可以说很常用的一种通信方式 xff0c 例如 蓝牙通信 openmv 与串口 通信 等等 问题描述 1 我们在进行数据传输过程中数据不时出现丢失的情况 xff0c 偶尔会丢失一部分数据 xff0c 导致数据部分
  • 基于51单片机光照强度检测系统

    介绍 本设计采用单片机作为数据处理与控制单元 xff0c 为了进行数据处理 xff0c 通过光敏电阻来感应光强弱变化 xff0c 经过ADC0804转换 xff0c 直接将数字信号送入到单片机中进行数据处理 单片机数据处理之后 xff0c
  • 基于51单片机控制的波形输出

    介绍 本模块采用PCF8591 xff0c 它是一款AD DA集成芯片 所以本节对iic通信协议不做过多的介绍 xff0c 重心放在iic的rtl建模 xff0c 本次通过iic控制PCF8591实现DAC输出功能 及输出波形 将数字量转为