IO口中断模拟I2C通信方式
更新时间:2024-04-20 22:40:01 阅读量: 综合文库 文档下载
- io模拟i2c从机推荐度:
- 相关推荐
一种IO口中断模拟I2C
通信的方法
单片机与单片机之间的通信方式
Jonney.Peng 2016/8/17
更可靠,效率更高的模拟I2C通信方式,主从机都可模拟
目录
一、 I2C通信原理 ........................................................................ 3 二、 利用IO口模拟I2C的优势 .................................................. 3 三、 利用IO口模拟I2C的原理 .................................................. 3 2、 中断接收数据函数 ............................................................ 4 3、 读指令函数 ........................................................................ 5 4、 发送一个字节函数 .................................................................. 6 5、 发送指令函数 .................................................................... 7 五、 源代码共享地址 ................................................................... 7
一、 I2C通信原理
I2C
总线系统是由SCL(串行时钟)和SDA(串行数据)两
根总线构成的。该总线有严格的时序要求,总线工作时,由串行时钟线SCL传送时钟脉冲,由串行数据线SDA传送数据。
二、 利用IO口模拟I2C的优势
简单的通过单片机IO模拟I2C通信,我们会发现数据接收不正常或者接收错误的情况,同时接收速率比较低,实时性比较差。最重要的是只能模拟主机通信,今天我所介绍的适用于所有单片机与单片机的通信,既可以接收数据也可以发送数据。只需要两个IO口,其中包含一个IO口中断,可以解决串口,I2C和SPI都不够用的问题。
三、 利用IO口模拟I2C的原理
传统的I2C通信方式,SCL负责传送信号脉冲,SDA负责传
送数据,SCL为低时,允许传送数据。通过中断方式实现I2C也是遵循了这个原理。与传统I2C的区别在于,当SCL电平变化时,只传送一位数据,所以接收完一个字节数据时,SCL需由高到低
变化八次。 四、 源代码分析
1、 初始化I2C函数
功能:将SDA与SCL电平置高,SDA可以为任何IO口,
SCL必须为带有中断的IO口。
void I2C_INIT() {
SDA=1; delays(2); SCL=1; delays(2); }
2、 中断接收数据函数
功能:实现数据的接收 变量名含义:
注:此接收函数根据通信协议可以适当调整,我的通信 协议格式是: 包头:00 地址:00-0XFF 包长度:命令+参数+结束位 命令:0X00-0XFF 参数:0X00-0XFF 结束位:0xFF INTTemp:接收数据变量,每一位都存入INTTemp
clk_over_timer:接收超时时基,用于复位相应标志位,后面会介
绍。
INT_i2c:中断标志位
F_INT_read:读数据标志位 F_read_ok:接收完数据标志位 INTnum:中断次数标志位 INTre[]:接收数据缓存区
INTbyteflag:接收字节个数标志位 F_long:接收的指令长度
void I2cRead() interrupt 0
{
INTTemp=INTTemp<<1; INTTemp=INTTemp|SDA; clk_over_timer=0; INT_i2c=1; F_INT_read=0; F_read_ok=0; INTnum++;
if(INTnum==8) //若INTnum为8,说明接收完一个字节的数据,
将数据存入INTre[]
{
INTnum=0;
INTre[INTbyteflag]=INTTemp;
减1,直到F_long=0,说明一条指令接收完毕
}
if(INTbyteflag==3) // INTbyteflag为3时说明长度位已接收完毕 {
值给F_long
}
}
F_long=INTre[2];
if(INTre[0]!=0x00) //包头不对,标志位复位,重新接收
INTbyteflag=0; F_long=32;
{ }
F_long--;
if(INTbyteflag>=3) //当接收数据位后面的数据时,长度标志位相应
INTbyteflag++;
If(INTre[0]==0x00&&INTre[1]==0x01) //包头和地址位接收正确,将长度为赋
{
}
if(INTre[1]!=0x01) //地址位不对,标志位复位,重新接收 INTbyteflag=0; F_long=32; {
}
3、 读指令函数
功能:判断指令接收完毕,当F_long=0说明指令已接收完毕,可以
根据指令处理相应事件。若20ms内没接收完数据,说明数据接收不正常,复位相应标志位。
void Read_ok()
{
if(F_long==0)
{
INTbyteflag=0; F_long=32; INT_i2c=1; F_INT_read=1; F_read_ok=1; clk_d=0; INTnum=0; clk_watch=0;
}
if(clk_over_timer>=2) { INT_i2c=0; INTnum=0; INTbyteflag=0; F_long=32; clk_d=0; clk_watch=0; clk_over_timer=0;
}
}
4、
发送一个字节函数
功能:通过I2C发送一个字数据
void send_byte(uchar b ) {
uchar i;
for(i=0;i<8;i++) { b=b<<1; SDA=CY; _nop_();_nop_();_nop_();_nop_();_nop_(); SCL=0; _nop_();_nop_();_nop_();_nop_();_nop_(); SCL=1; delays(1);
} //延时5us //SCL拉低,此时从
机响应中断进入接收 //延时5us //发送完毕后拉高
SCL和SDA
SCL=1; SDA=1; }
5、 发送指令函数
功能:发送一条指令
bit sendbytes(uchar *s,uchar a) {
uchar i;
EX0=0; //接收时关闭外部中断0,即停止I2C接收 for(i=0;i
IE0=0; //中断位请求标志位置0
EX0=1; //接收完毕,开外部中断,即可以接收I2C数据 INT_i2c=0; return TRUE;
}
五、 源代码共享地址
1、 相应的代码都是基于STC15系列单片机
2、 代码所实现的功能是:主单片机发送指令,12864
显示相应内容 3、 源代码所需硬件:
12864液晶一个,STC15w204s一片
有兴趣的童鞋可以自己写个主单片机发送命令的程序测试一下,亲测效果很好,我们公司现在通信方式都用这个,可以节省串口。 共享资料含通信协议: http://pan.http://www.wodefanwen.com//s/1boRjjo7
正在阅读:
IO口中断模拟I2C通信方式04-20
穷人续写800字06-18
“不忘初心,牢记使命”主题教育活动方案04-26
各商业业态物业条件及工程技术要求(做商业的必备) - 图文10-09
感恩教育主题班会教案05-09
石头作文600字07-16
工程进度考核奖励实施细则(最终版)05-25
汽车底盘练习题09-20
蔬菜病虫防治茄科-番茄病害(2)09-03
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 中断
- 模拟
- 通信
- 方式
- I2C