/*****************************************/
/* Copyright (c) 2005, 通信工程学院 */
/* All rights reserved. */
/* 作 者:戴 佳 */
/*****************************************/
#include "I2C.h"
/* 延时约5微秒,对于12M时钟 */
void delay5us()
{
uint i;
for (i=0;i<5;i++)
_nop_();
}
/* 起始条件子函数 */
void start(void)
{
SDA = 1; // 启动I2C总线
SCL = 1;
delay5us();
SDA = 0;
delay5us();
SCL = 0;
}
/* 停止条件子函数 */
void stop(void)
{
SDA = 0; // 停止I2C总线数据传送
SCL = 1;
delay5us();
SDA = 1;
delay5us();
SCL = 0;
}
/* 发送应答子函数 */
void ack(void)
{
SDA = 0; // 发送应答位
SCL = 1;
delay5us();
SDA = 1;
SCL = 0;
}
/* 发送非应答子函数 */
void n_ack(void)
{
SDA = 1; // 发送非应答位
SCL = 1;
delay5us();
SDA = 0;
SCL = 0;
}
/* 应答位检查子函数 */
void checkack(void)
{
SDA = 1; // 应答位检查(将p1.0设置成输入,必须先向端口写1)
SCL = 1;
nackFlag = 0;
if(SDA == 1) // 若SDA=1表明非应答,置位非应答标志F0
nackFlag = 1;
SCL = 0;
}
/* 发送一个字节数据子函数 */
void sendbyte(uchar idata *ch)
{
uchar idata n = 8;
uchar idata temp;
temp = *ch;
while(n--)
{
if((temp&0x80) == 0x80) // 若要发送的数据最高位为1则发送位1
{
SDA = 1; // 传送位1
SCL = 1;
delay5us();
SDA = 0;
SCL = 0;
}
else
{
SDA = 0; // 否则传送位0
SCL = 1;
delay5us();
SCL = 0;
}
temp = temp<<1; // 数据左移一位
}
}
/* 接收一字节子程序 */
void recbyte(uchar idata *ch)
{
uchar idata n=8; // 从SDA线上读取一位数据字节,共8位
uchar idata temp = 0;
while(n--)
{
SDA = 1;
SCL = 1;
temp = temp<<1; // 左移一位
if(SDA == 1)
temp = temp|0x01; // 若接收到的位为1,则数据的最后一位置1
else
temp = temp&0xfe; // 否则数据的最后一位置0
SCL=0;
}
*ch = temp;
}
/* 发送n字节数据子程序 */
void sendnbyte(uchar idata *sla, uchar n)
{
uchar idata *p;
start(); // 发送启动信号
sendbyte(sla); // 发送从器件地址字节
checkack(); // 检查应答位
if(F0 == 1)
{
NACK = 1;
return; // 若非应答表明器件错误或已坏,置错误标志位NACK
}
p = sbuf;
while(n--)
{
sendbyte(p);
checkack(); // 检查应答位
if (nackFlag == 1)
{
NACK=1;
return; // 若非应答表明器件错误或已坏,置错误标志位NACK
}
p++;
}
stop(); // 全部发完则停止
}
/* 接收n字节数据子程序 */
void recnbyte(uchar idata *sla, uchar n)
{
uchar idata *p;
start(); // 发送启动信号
sendbyte(sla); // 发送从器件地址字节
checkack(); // 检查应答位
if(nackFlag == 1)
{
NACK = 1;
return;
}
p = rbuf; // 接收字节存放在rbuf中
while(n--)
{
recbyte (p);
ack(); // 收到一个字节后发送一个应答位
p++;
}
n_ack(); // 收到最后一个字节后发送一个非应答位
stop();
}
/* 主函数,模拟实现I2C总线的数据收发 */
void main(void)
{
uchar i,numbyte;
numbyte = 8;
/* 需发送的8字节数据 */
for (i=0;i<numbyte;i++)
sbuf[i] = i+0x11;
SLAdd = 0x58; // 从器件地址
sendnbyte(&SLAdd,numbyte); // 向从器件发送存放在sbuf中的8字节数据
for (i=0;i<10000;i++)
delay5us();
recnbyte(&SLAdd,numbyte); // 由从器件接收8字节数据,存放在rbuf中
}
i2c.rar_51 I2C
版权申诉
159 浏览量
2022-09-23
08:19:41
上传
评论
收藏 17KB RAR 举报
林当时
- 粉丝: 100
- 资源: 1万+
最新资源
- 演讲稿.txt
- 基于Python的爬虫案例-软科中国大学TOP200
- 碳排放权交易明细数据(2024年5月更新).xlsx
- 特殊文件属性命令chattr和lsattr
- HTML、CSS 和 JavaScript动态、交互式的网页 .txt
- b0cd8f9b23d4e5e381b6a8fd8ee0e907.JPG
- ff45d61c5900e45634cf4cac6cff61a1.JPG
- springboot.springboot.springboot.springboot.txt
- linux-进程与服务管理
- 毕业设计基于Django+MySQL+Redis实现简单的天气预报系统python源码.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈