/*************** writer:shopping.w ******************/
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define Delay4us() {_nop_();_nop_();_nop_();_nop_();}
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
sbit SCL = P1^0;
sbit SDA = P1^1;
uchar Recv_Buffer[4];
uint Voltage[]={'0','0','0','0'};
bit bdata IIC_ERROR;
uchar LCD_Line_1[] = {"1- . V 2- . V"};
uchar LCD_Line_2[] = {"3- . V 4- . V"};
void Delay(uint ms)
{
uchar i;
while(ms--)
{
for(i=0;i<120;i++);
}
}
bit LCD_Busy_Check()
{
bit Result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
Delay4us();
Result = (bit)(P0&0x80);
LCD_EN = 0;
return Result;
}
void LCD_Write_Command(uchar cmd)
{
while(LCD_Busy_Check());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
Delay4us();
LCD_EN = 1;
Delay4us();
LCD_EN = 0;
}
void LCD_Write_Data(uchar dat)
{
while(LCD_Busy_Check());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
Delay4us();
LCD_EN = 1;
Delay4us();
LCD_EN = 0;
}
void LCD_Initialise()
{
LCD_Write_Command(0x38);Delay(5);
LCD_Write_Command(0x0c);Delay(5);
LCD_Write_Command(0x06);Delay(5);
LCD_Write_Command(0x01);Delay(5);
}
void LCD_Set_Position(uchar pos)
{
LCD_Write_Command(pos | 0x80);
}
void LCD_Display_A_Line(uchar Line_Addr,uchar s[])
{
uchar i;
LCD_Set_Position(Line_Addr);
for(i=0;i<16;i++)
{
LCD_Write_Data(s[i]);
}
}
void Convert_To_Voltage(uchar val)
{
uchar Tmp;
Voltage[2] = val/51+'0';
Tmp = val%51*10;
Voltage[1] = Tmp/51+'0';
Tmp = Tmp%51*10;
Voltage[0] = Tmp/51+'0';
}
void IIC_Start()
{
SDA = 1;
SCL = 1;
Delay4us();
SDA = 0;
Delay4us();
SCL = 0;
}
void IIC_Stop()
{
SDA = 0;
SCL = 1;
Delay4us();
SDA = 1;
Delay4us();
SCL = 0;
}
void Slave_ACK()
{
SDA = 0;
SCL = 1;
Delay4us();
SCL = 0;
SDA = 1;
}
void Slave_NOACK()
{
SDA = 1;
SCL = 1;
Delay4us();
SCL = 0;
SDA = 0;
}
void IIC_SendByte(uchar wd)
{
uchar i;
for(i=0;i<8;i++)
{
SDA=(bit)(wd&0x80);
_nop_();
_nop_();
SCL = 1;
Delay4us();
}
Delay4us();
SDA = 1;
SCL = 1;
Delay4us();
IIC_ERROR = SDA;
SCL = 0;
Delay4us();
}
uchar IIC_ReceiveByte()
{
uchar i,rd = 0x00;
for(i=0;i<8;i++)
{
SCL = 1;
rd <<= 1;
rd |= SDA;
Delay4us();
SCL = 0;
Delay4us();
}
SCL = 0;
Delay4us();
return rd;
}
void ADC_PCF8591(uchar CtrlByte)
{
uchar i;
IIC_Start();
IIC_SendByte(0x90);
if(IIC_ERROR == 1) return;
IIC_SendByte(CtrlByte);
if(IIC_ERROR == 1) return;
IIC_Start();
IIC_SendByte(0x91);
if(IIC_ERROR == 1) return;
IIC_ReceiveByte();
Slave_ACK();
for(i=0;i<4;i++)
{
Recv_Buffer[i++] = IIC_ReceiveByte();
Slave_ACK();
}
Slave_NOACK();
IIC_Stop();
}
void DAC_PCF8591(uchar CtrlByte,uchar dat)
{
IIC_Start();
Delay4us();
IIC_SendByte(0x90);
if(IIC_ERROR == 1) return;
IIC_SendByte(CtrlByte);
if(IIC_ERROR == 1) return;
IIC_SendByte(dat);
if(IIC_ERROR == 1) return;
IIC_Stop();
Delay4us();
Delay4us();
}
void main()
{
LCD_Initialise();
while(1)
{
ADC_PCF8591(0x40);
Convert_To_Voltage(Recv_Buffer[0]);
LCD_Line_1[2]=Voltage[2];
LCD_Line_1[4]=Voltage[1];
LCD_Line_1[5]=Voltage[0];
Convert_To_Voltage(Recv_Buffer[1]);
LCD_Line_1[11]=Voltage[2];
LCD_Line_1[13]=Voltage[1];
LCD_Line_1[14]=Voltage[0];
Convert_To_Voltage(Recv_Buffer[2]);
LCD_Line_2[2]=Voltage[2];
LCD_Line_2[4]=Voltage[1];
LCD_Line_2[5]=Voltage[0];
Convert_To_Voltage(Recv_Buffer[3]);
LCD_Line_2[11]=Voltage[2];
LCD_Line_2[13]=Voltage[1];
LCD_Line_2[14]=Voltage[0];
LCD_Display_A_Line(0x00, LCD_Line_1);
LCD_Display_A_Line(0x40, LCD_Line_2);
DAC_PCF8591(0x40,Recv_Buffer[0]);
}
}
PCF8591模数与数模转换实验
需积分: 0 105 浏览量
更新于2023-03-23
收藏 64KB ZIP 举报
**PCF8591模数与数模转换实验**
在电子工程领域,尤其是在嵌入式系统设计中,模数转换器(ADC)和数模转换器(DAC)是两个非常重要的组件。PCF8591是一款集成了ADC和DAC功能的芯片,常用于微控制器(如单片机)系统中进行信号处理。本实验主要围绕如何利用单片机与PCF8591进行模数与数模转换的实践操作。
我们需要了解PCF8591的基本特性。PCF8591是一款低功耗、4通道模拟输入/1通道模拟输出的I2C接口芯片。它具有8位分辨率,能够将模拟信号转化为数字信号,同时也可将数字信号还原为模拟信号。其I2C通信协议使得与单片机的连接更为简单,只需两根线(SCL和SDA)即可完成数据传输。
在实验过程中,我们首先要配置单片机的I2C接口。大部分单片机如AVR或STM32都有内置的I2C模块,需要设置相应的时钟频率、地址以及启动和停止条件。单片机通过发送特定的命令来控制PCF8591的读写操作。在进行模数转换时,单片机会向PCF8591发送一个转换命令,然后等待转换完成,再读取转换结果。而数模转换则相反,单片机会将要输出的数字数据写入到PCF8591,芯片会根据这些数据生成对应的模拟电压。
在代码实现方面,一般分为以下几个步骤:
1. 初始化I2C:设置I2C时钟、启动条件和单片机的I2C地址。
2. 写入命令:向PCF8591发送模数转换或数模转换的命令。
3. 数据传输:根据需要进行读取或写入操作。对于模数转换,读取PCF8591返回的8位数据;对于数模转换,写入8位数字数据。
4. 错误处理:检查并处理可能出现的通信错误,如超时、数据冲突等。
在实验中,你可能需要用到以下函数:
- `void i2c_init(void)`: 初始化I2C接口。
- `void pcf8591_write(unsigned char addr, unsigned char data)`: 向PCF8591写入数据。
- `unsigned char pcf8591_read(unsigned char addr)`: 从PCF8591读取数据。
- `void dac_set_value(unsigned char value)`: 设置数模转换的输出值。
- `unsigned char adc_get_value(void)`: 获取模数转换的输出值。
通过实际操作,你将深入理解PCF8591的工作原理,以及如何利用单片机的I2C接口进行有效的通信。这不仅有助于提升硬件接口编程技能,也有利于理解数字信号和模拟信号之间的转换过程。在完成实验后,你可以尝试扩展功能,例如增加多个传感器输入,或者设计更复杂的控制系统,以此增强对嵌入式系统设计的理解。
嵌入式开发星球
- 粉丝: 3w+
- 资源: 211
最新资源
- 机械结构动态图-间歇机构等.zip
- 永磁无刷直流电机计算软件,电机控制器,无刷电机设计软件,电机电磁设计软件
- 机械结构动态图-棘轮机制鲍登线等.zip
- 机械结构动态图-可调轴距的两平行轴间的传动等.zip
- 机械结构动态图-经典结构图.zip
- 机械结构动态图-链条传动.zip
- 机械结构动态图-流水线设备及机构动画.zip
- 机械结构动态图-马氏轮、螺旋传动等.zip
- 机械结构动态图-螺母-螺杆差速器.zip
- 机械结构动态图-摩擦锥球弧面变速器等.zip
- 机械结构动态图-摩擦锥辊传动与球面四杆机构等.zip
- 基于滑膜控制的差动制动防侧翻稳定性控制,上层通过滑膜控制产生期望的横摆力矩,下层根据对应的paper实现对应的制动力矩分配,实现车辆的防侧翻稳定性控制,通过通过carsim和simulink联合仿真
- 机械结构动态图-盘形凸轮机构,空间凸轮机构弧面分度凸轮等等.zip
- 机械设计锥套冲模机creo5.0非常好的设计图纸100%好用.zip
- 机械结构动态图-液压动画.zip
- 4WS4WD无人车横摆稳定性控制 通过滑模控制理论对后轮转角和直接横摆力矩进行集成控制,考虑前后轴荷及路面附着系数实现转矩分配,提高车身稳定性 carsim/simulink联合仿真