AD/DA 与外设控制
1. 硬件地址与控制字速查表
以下地址/控制字用于函数调用参数或外设控制:
| 设备名称 | 类型 | 控制字/指令 (Hex) | 说明 |
|---|---|---|---|
| 光敏电阻 | AD输入 | 0x41 |
PCF8591 通道 1 (AIN1) |
| 滑动变阻器 | AD输入 | 0x43 |
PCF8591 通道 3 (AIN3) |
| 继电器 | 数字输出 | 0x10 |
需配合锁存器/译码器使用 |
| 蜂鸣器 | 数字输出 | 0x40 |
需配合锁存器/译码器使用 |
2. I2C 驱动代码 (PCF8591)
AD 读取函数 (模数转换)
用于读取传感器(如光敏电阻、滑动变阻器)的电压值。
-
输入参数
addr: 对应上方表格中的0x41(光敏) 或0x43(变阻器)。 -
返回值: 读取到的 8位 数据 (0-255)。
C
unsigned char Ad_Read(unsigned char addr)
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0x90); // 发送设备写地址 (PCF8591)
IIC_WaitAck();
IIC_SendByte(addr); // 发送控制字节 (如 0x41 或 0x43)
IIC_WaitAck();
IIC_Start(); // 重启 I2C 总线
IIC_SendByte(0x91); // 发送设备读地址
IIC_WaitAck();
temp = IIC_RecByte(); // 读取数据
IIC_SendAck(1); // 发送非应答 (NACK),结束读取
IIC_Stop();
return temp;
}
DA 写入函数 (数模转换)
用于输出模拟电压(例如控制 LED 亮度或波形输出)。
-
注意: 此处函数参数名为
addr,但实际逻辑中它代表要写入的数据值 (Data/Voltage),而非地址。 -
固定配置: 代码中硬编码了
0x41,表示开启 DAC 输出并允许模拟输入通道 1。
C
void Da_Write(unsigned char addr) // 注意:此处的 addr 实为要输出的电压数据
{
IIC_Start();
IIC_SendByte(0x90); // 发送设备写地址 (PCF8591)
IIC_WaitAck();
IIC_SendByte(0x41); // 发送控制字节 (开启 DAC 输出)
IIC_WaitAck();
IIC_SendByte(addr); // 发送 DAC 数据值 (0-255)
IIC_WaitAck();
IIC_Stop();
}
3. 关键逻辑说明
-
I2C 时序:
-
读取流程:
Start→Write Addr(0x90)→Control Byte→Restart→Read Addr(0x91)→Read Data→Stop。 -
IIC_SendAck(1):在读取最后一个字节后,主机通常发送非应答(NACK,通常逻辑为1)来通知从机释放总线。
-
-
PCF8591 控制字:
-
0x41: 二进制0100 0001。-
Bit 6 = 1 (允许模拟电压输出/DAC Enable)。
-
Bit 0-1 = 01 (选择通道 1/光敏电阻)。
-
-
0x43: 二进制0100 0011。-
Bit 6 = 1 (允许模拟电压输出)。
-
Bit 0-1 = 11 (选择通道 3/滑动变阻器)。
-
-
-
继电器与蜂鸣器:
-
0x10和0x40通常不是 I2C 地址,而是用于控制板载外设(如 74HC573 锁存器或 ULN2003 驱动)的位掩码。 -
继电器:
0x10(对应 P0.4)。 -
蜂鸣器:
0x40(对应 P0.6)。
-
没问题!这是包含完整代码的更新版笔记。我把代码直接嵌入到了对应的操作说明中,方便你直接复制使用。![]()
![]()
EEPROM (AT24C02) 读写操作笔记
1. 核心概念:AT24C02 芯片特性 
(基于中间说明图)
-
芯片类型:I2C 接口的 EEPROM 芯片。
-
寻址方式:每个字节都有唯一地址,其中一个地址对应一个字节。
-
关键约束(页写入限制):-
该芯片具有 8个字节 的页长(Page Size)。
-
地址对齐:在示例代码中,要求读写地址 必须是8的倍数。
-
写入限制:一次写入操作最多只能写入8个字节。如果不按8的倍数对齐或超过页长,可能导致写入错误或数据丢失。
-
2. 写操作 (EEPROM_Write) 
(基于第一张代码图)
该函数用于向EEPROM的特定地址写入指定数量的字符。
- 关键流程:Start → 发送器件地址(写) → 发送数据地址 → 循环写入数据 (需延时) → Stop
C
//函数名:写EEPROM函数
//入口参数:需要写入的字符串,写入的地址(务必为8的倍数),写入数量
//返回值:无
//函数功能:向EERPOM的某个地址写入字符串中特定数量的字符。
void EEPROM_Write(unsigned char* EEPROM_String, unsigned char addr, unsigned char num)
{
IIC_Start(); //发送开启信号
IIC_SendByte(0xA0);//选择EEPROM芯片,确定写的模式
IIC_WaitAck(); //等待EEPROM反馈
IIC_SendByte(addr);//写入要存储的数据地址
IIC_WaitAck(); //等待EEPROM反馈
while(num--)
{
IIC_SendByte(*EEPROM_String++); //将要写入的信息写入
IIC_WaitAck(); //等待EEPROM反馈
IIC_Delay(200); //重要:等待内部写入完成
}
IIC_Stop(); //停止发送
}
3. 读操作 (EEPROM_Read) 
(基于第三张代码图)
该函数用于从EEPROM的特定地址读取数据并存入数组。
- 关键流程:Start → 发送器件地址(写) → 发送数据地址 → Restart → 发送器件地址(读) → 循环读取 (注意ACK/NACK) → Stop
C
//函数名:读EEPROM函数
//入口参数:读到的数据需要存储的字符串,读取的地址(务必为8的倍数),读取的数量
//返回值:无
//函数功能:读取EERPOM的某个地址中的数据,并存放在字符串数组中。
void EEPROM_Read(unsigned char* EEPROM_String, unsigned char addr, unsigned char num)
{
IIC_Start(); //发送开启信号
IIC_SendByte(0xA0);//选择EEPROM芯片,确定写的模式
IIC_WaitAck(); //等待EEPROM反馈
IIC_SendByte(addr);//写入要读取的数据地址
IIC_WaitAck(); //等待EEPROM反馈
IIC_Start(); //发送开启信号
IIC_SendByte(0xA1);//选择EEPROM芯片,确定读的模式
IIC_WaitAck(); //等待EEPROM反馈
while(num--)
{
*EEPROM_String++ = IIC_RecByte(); //接收数据
if(num) IIC_SendAck(0); //发送应答 (继续读)
else IIC_SendAck(1); //不应答 (最后一位,准备停止)
}
IIC_Stop(); //停止发送
}
重点对比记忆
-
延时:写操作在循环中每写一个字节都需要
IIC_Delay(200),而读操作不需要。 -
模式切换:读操作中间多了一次
IIC_Start()和0xA1(读模式指令)的发送。 -
应答信号:
-
写:主机只负责接收从机的 ACK。
-
读:主机读取数据后,需要主动发送 ACK(继续)或 NACK(结束)。
-