历史上的今天
今天是:2025年08月12日(星期二)
2021年08月12日 | MC9S12XDP512下IIC模块的应用总结
2021-08-12 来源:eefocus
IIC应用笔记
IIC总线相关知识:
1.起始信号: 时钟线保持高电平时,数据线上出现由高变低的信号。
2.停止信号:时钟线保持高电平时,数据线上出现由低变高的信号。
3.数据传输:时钟线为高电平时,数据线上的逻辑状态必须保持一致。时钟线为低电平时,允许数据线上的电平发生变化(即传输)。
4.起始信号和停止信号都由主控制器产生,应答信号在每个数据传输后的第9个时钟周期由接收器产生,低电平有效。当主控制器为接收方时,接收到最后一个字节时,不应发送应答信号。
5. 写过程:启动IIC→发送从机地址→发送要写单元地址→发送写数据(一个或者连续写) →发送停止信号,关闭IIC。
6.读过程:主机发送开始信号,启动IIC→发送从机地址→产生连续启动,发送要读单元地址→接收数据,发送应答信号→接收最后一个数据,不发送应答信号→发送停机信号
芯片相关知识:
1. FM3135(RTC模块):
1.支持最高1MHZ的IIC总线时钟频率。
2.RTC模块读取时间流程:向地址0x00处先写0x01(即置位R)→地址移动到0x02→读取时间数据→向地址0x00处写0x00(即复位R)
3.RTC模块修改时间流程:向地址0x00处写0x02(即置位W) →写时钟寄存器→向地址0x00处写0x00
2.MC9S12XDP512IIC模块:
1.IBCR:第5位,主/模式选择位,该位从0变成1时,产生起始信号;该位从1变成0时,产生一个停止信号(只有当IBIF=1时,停止信号才能产生).
2.IBDR:在发送模式下,当一个数据被写到IBDR时,数据传输就开始了。
在接收模式下,读该寄存器将机动下一字节的接收。注意:接收第一字节之前,空读该寄存器以启动接收。在读最后一个字节之前,要将寄存器设置成不发送应答信号。当下一次中断(最后一个字节之后的一个数据)来临时,不能再读IBDR,应直接写IBCR的第5位产生停止信号。
3. 主机做接收方时,需要将主机设置成连续启动.
4. 发送中断来临时,还需等待从机应答信号到来才能发送下一个字节。
==========================================================
// IIC启动函数
// 通信速率,总线频率的128分频,363KHZ
// 0:读时钟,1:修改时钟
// ==========================================================
void IIC_Function(byte cmd)
{
if(cmd == 0) // 读时钟
{
while((Status.Bits.Time_Write == 1)||(Status.Bits.Time_Read == 1)); // 等待修改时钟命令完成
Status.Bits.Time_Read = 1; // 置位读时钟标志
}
else
{
while((Status.Bits.Time_Read == 1)||(Status.Bits.Time_Write == 1));
Status.Bits.Time_Write = 1; // 置位写时钟标志
}
IIC_Start();
}
// ==========================================================
// IIC初始化函数
// 通信速率:总线时钟40分频,1MHZ
// ==========================================================
void IIC_Init(void)
{
IIC0_IBSR_IBAL = 1; // 清零仲裁丢失位
// initial iic
IIC0_IBFD = 0X07; // 设置时钟为总线时钟频率40分频,1MHZ
IIC0_IBCR |=0xC0; // 使能IIC,IIC总线中断使能
}
// ==========================================================
// IIC Start Function
// 注意:1. 启动IIC后,由中断函数控制IIC的读取与写入
// 2. 此函数只供IIC_Function()函数调用
// ==========================================================
void IIC_Start(void)
{
while(IIC0_IBSR_IBB); // 等待总线空闲
IIC0_IBCR |= 0X30; // 主模式,选择发送,产生起始信号
while(IIC0_IBSR_IBB==0); // 等待总线忙
IIC0_IBDR = IIC_WADDR; // 写IBDR,启动发送
}
// ==============================================
// IIC中断函数
// ==============================================
interrupt void IIC_Int(void)
{
static char tcount = 0, rcount = 0; // 发送,接收计数器
// 修改时钟
if(Status.Bits.Time_Write == 1)
{
// IIC 发送
if(IIC0_IBCR_TX_RX == 1)
{
if((tcount == 0) || (tcount == 11))
{
while(IIC0_IBSR_RXAK == 1); // 等待应答信号
IIC0_IBSR_IBIF = 1; // 清除标志位
IIC0_IBDR = 0x00; // 写地址
tcount++;
}
// 发送控制字: 0x02,W=1,置位写
else if((tcount == 1)|| (tcount == 12))
{
while(IIC0_IBSR_RXAK == 1); // 等待应答信号
IIC0_IBSR_IBIF = 1; // 清除标志位
if(tcount == 1)
IIC0_IBDR = 0x02; // W = 1
else
IIC0_IBDR = 0X00; // W = 0
tcount++;
}
else if(tcount == 2)
{
while(IIC0_IBSR_RXAK == 1); // 等待应答信号
IIC0_IBSR_IBIF = 1; // 清除标志位
IIC0_IBDR = 0x00; // enable oscillator
tcount++;
}
else if(tcount == 10) // 最后一个字节
{
IIC0_IBCR &= 0XDF; // 1-0,产生STOP信号,进入从模式
IIC0_IBSR_IBIF = 1; // 清除标志位
while(IIC0_IBSR_IBB); // 等待总线空闲
IIC0_IBCR |= 0X30; // 主模式,选择发送,产生起始信号
while(IIC0_IBSR_IBB==0); // 等待总线忙
IIC0_IBDR = IIC_WADDR; // 写IBDR,启动发送
tcount++;
}
else if(tcount == 13) // 结束
{
IIC0_IBCR &= 0XDF; // 1-0,产生STOP信号,进入从模式
IIC0_IBSR_IBIF = 1; // 清除标志位
// 复位
tcount = 0;
Status.Bits.Time_Write = 0;
}
else
{
while(IIC0_IBSR_RXAK == 1); // 等待应答信号
IIC0_IBSR_IBIF = 1; // 清除标志位
IIC0_IBDR = TimeStr_W[tcount-3]; // 写,数据发送开始
tcount++;
}
}
}
// 读取时钟
else
{
// 发送环节: IIC地址在读取时钟函数中发送,此处还需发送的有:地址,IIC写地址
if(IIC0_IBCR_TX_RX == 1) // 1: 发送
{
tcount++;
switch(tcount)
{
// 发送要读的单元地址
case 1:
{
while(IIC0_IBSR_RXAK == 1); // 等待应答信号
IIC0_IBSR_IBIF = 1;
IIC0_IBDR = 0X00; // 地址为0x00
break;
}
case 2: // 置位读标志
{
while(IIC0_IBSR_RXAK == 1); // 等待应答信号
IIC0_IBSR_IBIF = 1;
IIC0_IBDR = 0X01; // R = 1
break;
}
case 3:
{
IIC0_IBCR &= 0XDF; // 1-0,产生STOP信号,进入从模式
IIC0_IBSR_IBIF = 1; // 清除标志位
// 从新启动IIC
while(IIC0_IBSR_IBB); // 等待总线空闲
IIC0_IBCR |= 0X30; // 主模式,选择发送,产生起始信号
while(IIC0_IBSR_IBB==0); // 等待总线忙
IIC0_IBDR = IIC_WADDR; // 写IBDR,启动发送
break;
}
case 4:
{
while(IIC0_IBSR_RXAK == 1); // 等待应答信号
IIC0_IBSR_IBIF = 1;
IIC0_IBDR = 0X00; // 地址为0x00
break;
}
case 5:
{
while(IIC0_IBSR_RXAK == 1); // 等待应答信号
IIC0_IBSR_IBIF = 1;
IIC0_IBDR = 0X00; // R = 0
break;
}
史海拾趣
|
ATM监控专业评标标准!!! 资质审查1. 数字录像设备和微型摄像机同时获得公安部安全防范报警系统产品质量监督检验测试中心出具的型式检验报告。 依据标准: A. 公安部关于贯彻实施《安全技术防范产品管理办法》有关问题的补充通知第二条 B. 《 ...… 查看全部问答> |
|
使用是HHARM2410的开发板。NFS服务器配置操作是正确的,PC与开发板之间相互能ping通,但是开发板正常启动后mount 不了PC机。我已经关了防火墙。我主机IP为192.168.2.222。/etc/exports文件设置的是(rw)。在minnicon里执行mount 192.168.2.222:/ /m ...… 查看全部问答> |
|
如题,本人两个月的经验~~希望对后来者有所帮助 总结STM32的I2C的缺陷与使用.pdf (92.94 KB) 下载次数:672 2010-12-1 08:49 … 查看全部问答> |
|
verilog中,一个always中如果含有好几个case语句,那么这些case语句是并发执行,还是顺序执行呢??如下 always begin case(a) ………… case(b) ………… case(c) ………… end … 查看全部问答> |
|
MSP430G2553串口连接12864显示,只用连接三个引脚,大大节省资源 #include <msp430g2553.h>#define uint unsigned int#define uchar unsigned char#define ulong unsigned longunsigned char a[]={\"波天神终于把12864学会了!\"};#define SID BIT1#define SCLK BIT2#define CS BIT3#define ...… 查看全部问答> |




