TDA2030功放电路图 电动车充电器电路图 电子电路 功放电路 电子制作 集成块资料 电子报 pcb 变压器 元器件知识 逆变器电路图 电路图 开关电源电路图 传感器技术 led 电磁兼容
电子电路图
当前位置: 首页 > 电子电路 > 设计编程

单片机的I2C通信设计

时间:2019-12-05 09:15:30来源:电子发烧友 作者:admin 点击:
I2C每一位信号的时序流程,而I2C通信在字节级的传输中,也有固定的时序要求。I2C通信的起始信号(Start)后,首先要发送一个从机的地址,这个地址一共有 7位,紧跟着的第 8

I2C每一位信号的时序流程,而I2C通信在字节级的传输中,也有固定的时序要求。I2C通信的起始信号(Start)后,首先要发送一个从机的地址,这个地址一共有 7位,紧跟着的第 8 位是数据方向位(R/W),“0”表示接下来要发送数据(写),‘“1”表示接下来是请求数据(读)。

我们知道,打电话的时候,当拨通电话,接听方捡起电话肯定要回一个“喂”,这就是告诉拨电话的人,这边有人了。同理,这个第九位 ACK 实际上起到的就是这样一个作用。当我们发送完了这 7 位地址和 1 位方向后,如果发送的这个地址确实存在,那么这个地址的器件应该回应一个 ACK(拉低 SDA 即输出“0”),如果不存在,就没“人”回应 ACK(SDA将保持高电平即“1”)。

那我们写一个简单的程序,访问一下我们板子上的 EEPROM 的地址,另外再写一个不存在的地址,看看它们是否能回一个 ACK,来了解和确认一下这个问题。

我们板子上的 EEPROM 器件型号是 24C02,在 24C02 的数据手册 3.6 节中可查到,24C02的 7 位地址中,其中高 4 位是固定的 0b1010,而低 3 位的地址取决于具体电路的设计,由芯片上的 A2、A1、A0 这 3 个引脚的实际电平决定,来看一下我们的 24C02 的电路图,它和24C01 的原理图完全一样,如图 14-4 所示。

<a href=http://www.dziuu.com/tags-etagid15-0.html target=_blank class=infotextkey>单片机</a>的I2C通信设计

图 14-4 24C02 原理图

从图 14-4 可以看出来,我们的 A2、A1、A0 都是接的 GND,也就是说都是 0,因此 24C02的 7 位地址实际上是二进制的 0b1010000,也就是 0x50。我们用 I2C 的协议来寻址 0x50,另外再寻址一个不存在的地址 0x62,寻址完毕后,把返回的 ACK 显示到我们的 1602 液晶上,大家对比一下。

/***************************Lcd1602.c 文件程序源代码*****************************/

#include

#define LCD1602_DB P0

sbit LCD1602_RS = P1^0;

sbit LCD1602_RW = P1^1;

sbit LCD1602_E = P1^5;

/* 等待液晶准备好 */

void LcdWaitReady(){

unsigned char sta;

LCD1602_DB = 0xFF;

LCD1602_RS = 0;

LCD1602_RW = 1;

do {

LCD1602_E = 1;

sta = LCD1602_DB; //读取状态字

LCD1602_E = 0;

} while (sta & 0x80); //bit7 等于 1 表示液晶正忙,重复检测直到其等于 0 为止

}

/* 向 LCD1602 液晶写入一字节命令,cmd-待写入命令值 */

void LcdWriteCmd(unsigned char cmd){

LcdWaitReady();

LCD1602_RS = 0;

LCD1602_RW = 0;

LCD1602_DB = cmd;

LCD1602_E = 1;

LCD1602_E = 0;

}

/* 向 LCD1602 液晶写入一字节数据,dat-待写入数据值 */

void LcdWriteDat(unsigned char dat){

LcdWaitReady();

LCD1602_RS = 1;

LCD1602_RW = 0;

LCD1602_DB = dat;

LCD1602_E = 1;

LCD1602_E = 0;

}

/* 设置显示 RAM 起始地址,亦即光标位置,(x,y)-对应屏幕上的字符坐标 */

void LcdSetCursor(unsigned char x, unsigned char y){

unsigned char addr;

if (y == 0){ //由输入的屏幕坐标计算显示 RAM 的地址

addr = 0x00 + x; //第一行字符地址从 0x00 起始

}else{

addr = 0x40 + x; //第二行字符地址从 0x40 起始

}

LcdWriteCmd(addr | 0x80); //设置 RAM 地址

}

/* 在液晶上显示字符串,(x,y)-对应屏幕上的起始坐标,str-字符串指针 */

void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str){

LcdSetCursor(x, y);//设置起始地址

while (*str != ‘’){ //连续写入字符串数据,直到检测到结束符

LcdWriteDat(*str++);

}

}

/* 初始化 1602 液晶 */

void InitLcd1602(){

LcdWriteCmd(0x38); //16*2 显示,5*7 点阵,8 位数据接口

LcdWriteCmd(0x0C); //显示器开,光标关闭

LcdWriteCmd(0x06); //文字不动,地址自动+1

LcdWriteCmd(0x01); //清屏

}

/*****************************main.c 文件程序源代码******************************/

#include

#include

#define I2CDelay() {_nop_();_nop_();_nop_();_nop_();}

sbit I2C_SCL = P3^7;

sbit I2C_SDA = P3^6;本文由容源电子网(www.dziuu.com)整理提供,部分内容来源于网络,如有侵犯到你的权利请与我们联系更正。

本文地址:http://www.dziuu.com/dz/22/15755085833520.shtml


本文标签:


.
123下一页尾页
顶一下
0%
返回首页
0
0%

------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
表情:
名称: E-mail: 验证码: 匿名发表
发布文章,推广自己产品。
推荐内容
  • 特斯拉线圈原理揭秘解读

    特斯拉线圈原理揭秘解读特斯拉线圈是一种射频 振荡器,可驱动空芯双调谐振变压器,在低电流时产生高压。特斯拉的原始电路以及大多数现代线圈使用简单的火花隙来激发调谐变

  • 51单片机对LCD1602液晶显示器的控

    51单片机对LCD1602液晶显示器的控制 要想实现人机交互,显示装置是不可缺少的。这篇文章主要关于如何控制液晶显示,并在此基础上加上定时器的功能,把原来已用数码管显示

  • 介绍编码器的工作原理和作用

    编码器的工作原理和功能:它是一个旋转传感器,将旋转位移转换为一系列数字脉冲信号。这些脉冲可用于控制角位移。如果编码器与齿轮杆或螺钉组合,可用于测量线性位移。

热门标签