实验5 IIC通讯与AD/接DA接口
1.利用单片机控制PCF8591的AD转换,控制AD0和AD1电位器,在数码光上显示DA转换的值。
2.利用单片机控制PCF8591的DA转换,让发光二极管D1由暗到亮变化,整个过程时间差不多2s左右,再由亮到暗变化,循环变化。
以下代码将1、2实验合并成一个实验。
Lab6.1
#include<reg51.h>
#include <I2C.H>
#define PCF8591 0x90 //PCF8591 地址
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
//=========全局变量区============================================
unsignedchar AD_CHANNEL;
];
sbit high;
sbit mid;
sbit low;
uint code NumTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数字的编码
//=========全局变量区结束========================================
//=========函数区============================================
/*******************************************************************
延时
*******************************************************************/
void delay_1ms(uint x){
uint i=x;
uint j;
;--i){
;--j);
}
}
/*******************************************************************
在数码管上显示对应的值
参数说明:
Num 要显示的数字
*******************************************************************/
void display(uchar Num,uchar withDot)
{
P0=NumTable[Num]|withDot;
delay_1ms);
P0; //送完段选信号后,进行消影的处理
}
/*******************************************************************
控制数码管显示,并分解计数值
*******************************************************************/
void DisplayNumByOrder(uint left,uint right){
low); //left
low);
low,0x80);
low);
//right
low);
low);
low,0x80);
low);
}
/*******************************************************************
DAC 变换, 转化函数
*******************************************************************/
bit DACconversion(unsignedchar sla,unsignedchar c, unsignedchar Val)
{
Start_I2c(); //启动总线
SendByte(sla); //发送器件地址
);
SendByte(c); //发送控制字节
);
SendByte(Val); //发送DAC的数值
);
Stop_I2c(); //结束总线
);
}
/*******************************************************************
ADC发送字节[命令]数据函数
*******************************************************************/
bit ISendByte(unsignedchar sla,unsignedchar c)
{
Start_I2c(); //启动总线
SendByte(sla); //发送器件地址
);
SendByte(c); //发送数据
);
Stop_I2c(); //结束总线
);
}
/*******************************************************************
ADC读字节数据函数
*******************************************************************/
unsignedchar IRcvByte(unsignedchar sla)
{ unsignedchar c;
Start_I2c(); //启动总线
SendByte); //发送器件地址
);
c
Ack_I2c); //发送非就答位
Stop_I2c(); //结束总线
return(c);
}
//******************************************************************/
main()
{
)
{
/********以下AD-DA处理*************/
//个时钟才是正常的值,相当于
//swith经历了一轮case 0~4后,程序里面读取到的AD转换的值才是正常的。
switch(AD_CHANNEL) // A/D信道,通过这个函数,4个信道的数值都能读到
{
: ISendByte(PCF8591,0x41);
D倍显示
break;
: ISendByte(PCF8591,0x42);
D
break;
: ISendByte(PCF8591,0x43);
D
break;
: ISendByte(PCF8591,0x40);
D
break;
]);//DAC 数模转换
break;
}
D]; // 把模拟输入采样的信号通过数模转换输出,最终改变灯泡亮度
;
DisplayNumByOrder]);//将AD的值送到LED数码管显示
}
}
//=========函数结束区============================================
/*************************此部分为I2C总线的驱动程序*************************************/
I2c.c
#include<reg51.h>
#include <intrins.h>
#include <I2C.H>
#define NOP() _nop_() /* 定义空指令 */
#define _Nop() _nop_() /*定义空指令*/
sbit SCL; //I2C 时钟
sbit SDA; //I2C 数据
bit ack; /*应答标志位*/
/*******************************************************************
起动总线函数
函数原型: void Start_I2c();
功能: 启动I2C总线,即发送I2C起始条件.
********************************************************************/
void Start_I2c()
{
SDA; /*发送起始条件的数据信号*/
_Nop();
SCL;
_Nop(); /*起始条件建立时间大于4.7us,延时*/
_Nop();
_Nop();
_Nop();
_Nop();
SDA; /*发送起始信号*/
_Nop(); /* 起始条件锁定时间大于4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
SCL; /*钳住I2C总线,准备发送或接收数据 */
_Nop();
_Nop();
}
/*******************************************************************
结束总线函数
函数原型: void Stop_I2c();
功能: 结束I2C总线,即发送I2C结束条件.
********************************************************************/
void Stop_I2c()
{
SDA; /*发送结束条件的数据信号*/
_Nop(); /*发送结束条件的时钟信号*/
SCL; /*结束条件建立时间大于4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA; /*发送I2C总线结束信号*/
_Nop();
_Nop();
_Nop();
_Nop();
}
/*******************************************************************
字节数据发送函数
函数原型: void SendByte(UCHAR c);
功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
此状态位进行操作.(不应答或非应答都使ack=0)
发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
********************************************************************/
void SendByte(unsignedchar c)
{
unsignedchar BitCnt;
位*/
{
; /*判断发送位*/
;
_Nop();
SCL; /*置时钟线为高,通知被控器开始接收数据位*/
_Nop();
_Nop(); /*保证时钟高电平周期大于4μs*/
_Nop();
_Nop();
_Nop();
SCL;
}
_Nop();
_Nop();
SDA; /*8位发送完后释放数据线,准备接收应答位*/
_Nop();
_Nop();
SCL;
_Nop();
_Nop();
_Nop();
;
; /*判断是否接收到应答信号*/
SCL;
_Nop();
_Nop();
}
/*******************************************************************
字节数据接收函数
函数原型: UCHAR RcvByte();
功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
发完后请用应答函数应答从机。
********************************************************************/
unsignedchar RcvByte()
{
unsignedchar retc;
unsignedchar BitCnt;
retc;
SDA; /*置数据线为输入方式*/
;BitCnt++)
{
_Nop();
SCL; /*置时钟线为低,准备接收数据位*/
_Nop();
_Nop(); /*时钟低电平周期大于4.7μs*/
_Nop();
_Nop();
_Nop();
SCL; /*置时钟线为高使数据线上数据有效*/
_Nop();
_Nop();
retc;
; /*读数据位,接收的数据位放入retc中 */
_Nop();
_Nop();
}
SCL;
_Nop();
_Nop();
return(retc);
}
/********************************************************************
应答子函数
函数原型: void Ack_I2c(bit a);
功能: 主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
********************************************************************/
void Ack_I2c(bit a)
{
; /*在此发出应答或非应答信号 */
;
_Nop();
_Nop();
_Nop();
SCL;
_Nop();
_Nop(); /*时钟低电平周期大于4μs*/
_Nop();
_Nop();
_Nop();
SCL; /*清时钟线,钳住I2C总线以便继续接收*/
_Nop();
_Nop();
}
I2c.h

实验5 IIC通讯与AD/接DA接口的更多相关文章
- 实验4 IIC通讯与EEPROM接口
1. 用C语言编程,利用定时器产生一个0~99秒变化的秒表,并且显示在数码管上,每过一秒将这个变化写入实验板上AT24C02,当关闭实验板电源,并再次打开实验板电源时,单片机从AT24C0 ...
- 51单片机学习笔记(郭天祥版)(6)——键盘的作业题、AD、DA、DS18B20(这里之后看清翔的补一下好了)
A:analog,D:digital AD,就是模拟量转换为数字量,DA就是数字量转换为模拟量 为什么要转换? 单片机是数字芯片,内部只有0和1,没法表示模拟量 比如我们如果需要2.5V怎么办?其实是 ...
- 基于esp32的IIC通讯
本文源码地址在:http://download.csdn.net/download/noticeable/9962029 IIC 通讯应该是当代比较常用的几种通讯方式之一,其无需特殊的IO接口,连线方 ...
- 用Verilog实现IIC通讯
注意,此代码是错误代码,并不能实现想要的结果. 之所以留着,因为里面的enable 是独立开来的思想值得借鉴.就是控制单元和运算单元分开(我也是借鉴别人的实现思想).具体用verilogHDL实现II ...
- LPC1768的iic通讯
LPC1768有三路IIC,其中IIC0支持高速模式和plus模式,另外两路是普通IIC,使用IIC的过程如下 首先依然是打开IIC时钟,同时打开GPIO时钟 然后配置引脚为IIC功能 另外,因为ii ...
- 2018-2019-1-20165221&20165225 《信息安全系统设计》实验五:通讯协议设计
2018-2019-1-20165221&20165225 <信息安全系统设计>-实验五:通讯协议设计 OpenSSL学习: 简介: OpenSSL是为网络通信提供安全及数据完整性 ...
- STM32作为主设备,Arduino作为从设备进行IIC通讯的注意要点
近日公司的项目重心要往米思齐的Arduino图形化编程上转移了,需要我将STM32和Arduino的IIC通讯调通.之前Arduino并没怎么使用过,仅仅是将超声波的代码移植成TOF激光测距而已.网上 ...
- 「STM32 」IIC通讯原理及其实验
I2C两线式串行总线通讯协议,它是由飞利浦开发的,主要用于连接微控制器及其外围设备之间,它是由数据线SDA和信号线SCL构成的,可发送和接收数据即在MUC和I2C设备之间,I2C和I2C之间进行全双工 ...
- STM32F412应用开发笔记之三:SPI总线通讯与AD采集
本次我们在NUCLEO-F412ZG试验模拟量输入采集.我们的模拟量输入采用ADI公司的AD7705,是一片16位两路差分输入的AD采集芯片.具有SPI接口,我们将采用SPI接口与AD7705通讯.两 ...
随机推荐
- MySQL数据库相关操作
查看数据库 mysql> SHOW DATABASES; 选择数据库 mysql> USE 数据库名称: 查看当前数据库 mysql> select database(); -- 第 ...
- html中 和空格的区别
Non-Breaking Space 注意是 这6个字符是一个整体, 在html中, 是空格的占位符.一个 代表一个空格:两个 代表两个空格,即使用几个 就显示几个空格. 但是普通的空格在h ...
- How to change and add some params to request in Laravel controller?
$request->merge([ 'aae_id' => request('id', 0), 'foo' => 'bar', ]);
- [Selenium Grid] 搭建Hub和Node环境
Note : 先在Hub和Node的机器上安装好JDK, IE浏览器,Chrome浏览器,Firefox浏览器 准备好红色框标示的东西: Hub.bat :启动Hub AllNodes.bat : ...
- mysql如何查看自己数据库文件所在的位置
mysql如何查看自己数据库文件所在的位置 C:\Program Files\MySQL\MySQL Server 5.5 mysql数据库 方法/步骤 第1步: 打开mysqml文件夹,显示 ...
- hibernate集合映射inverse和cascade详解<转载>
1.到底在哪用cascade="..."? cascade属性并不是多对多关系一定要用的,有了它只是让我们在插入或删除对像时更方便一些,只要在cascade的源头上插入或是删除,所 ...
- Redis (非关系型数据库) 数据类型 之 String类型
Redis 一个内存数据库,通过 Key-Value 键值对的的方式存储数据.由于 Redis 的数据都存储在内存中,所以访问速度非常快,因此 Redis 大量用于缓存系统,存储热点数据,可以极大的提 ...
- form表单序列化为json格式数据
在web开发过程中,经常遇到将form序列化不能格式的字符串提交到后台,下面就介绍怎样将form表单序列化为json字符串. 首先,是扩展的jquery序列化插件,依赖jquery.经测试,这段代码可 ...
- 查阅JDK,collection与collections区别大
看起来collection,和collections相像,但其中的差别之大你造吗? Collection是Collection层次结构中的根接口.Collection表示一组对象,这也对象也称为col ...
- DDR4控制笔记
DDR4接口 A[17:0] input 为激活命令提 供行地址,为读.写命令地址输入:提供列地址,也为模式寄存器设 置提供操作码,A[16]只用于8Gb和16Gb,A[17]只用于16Gb,另外 ...