用C语言写 RH850 IIC的驱动
时间: 2023-09-26 10:13:42 浏览: 196
下面是一个简单的用C语言写RH850 IIC驱动的例子,供参考:
```c
#include "iodefine.h"
// 定义IIC模块寄存器地址
#define IIC_BASE_ADDR (0xFFE88000) // IIC模块寄存器基地址
#define IIC_ICCR (IIC_BASE_ADDR + 0x00) // 控制寄存器
#define IIC_ICSR (IIC_BASE_ADDR + 0x04) // 状态寄存器
#define IIC_ICDR (IIC_BASE_ADDR + 0x08) // 数据寄存器
#define IIC_ICCR2 (IIC_BASE_ADDR + 0x0C) // 控制寄存器2
// 定义IIC控制寄存器ICCR的位掩码
#define ICCR_START_BIT (1 << 7) // 启动传输
#define ICCR_STOP_BIT (1 << 6) // 停止传输
#define ICCR_ACKE_BIT (1 << 5) // 确认位使能
#define ICCR_DTEE_BIT (1 << 4) // 数据输出使能
#define ICCR_WSEL_BIT (1 << 3) // 写选择
#define ICCR_IICBSY_BIT (1 << 0) // IIC忙标志
// 定义IIC状态寄存器ICSR的位掩码
#define ICSR_TEND_BIT (1 << 0) // 传输结束标志
#define ICSR_AL_BIT (1 << 3) // 碰撞检测标志
#define ICSR_STOP_BIT (1 << 4) // 停止检测标志
#define ICSR_NACKF_BIT (1 << 5) // 非确认检测标志
// 初始化IIC模块
void IIC_Init(void)
{
// 设置IIC控制寄存器ICCR和ICCR2
ICCR = 0x00; // 清空ICCR
ICCR2 = 0x00; // 清空ICCR2
ICCR |= (1 << 5); // 使能确认位
ICCR |= (1 << 4); // 使能数据输出
ICCR2 |= (1 << 0); // 使能IIC模块
// 设置IIC时钟频率
ICCR &= ~(0x0F << 0); // 清空时钟分频位
ICCR |= (0x01 << 0); // 设置时钟分频为1(实际时钟频率为PCLK/2)
// 设置IIC总线速率
ICCR &= ~(0x03 << 1); // 清空速率位
ICCR |= (0x02 << 1); // 设置速率为100Kbps
}
// 向IIC设备发送数据
int IIC_SendData(unsigned char addr, unsigned char *data, unsigned int len)
{
unsigned int i;
// 发送启动位
ICCR |= ICCR_START_BIT;
while ((ICSR & ICSR_TEND_BIT) == 0); // 等待传输结束
// 发送设备地址
IIC_ICDR = (unsigned int)(addr << 1);
while ((ICSR & ICSR_TEND_BIT) == 0); // 等待传输结束
if (ICSR & ICSR_NACKF_BIT) // 检查ACK
{
return -1; // 发送设备地址失败
}
// 发送数据
for (i = 0; i < len; i++)
{
IIC_ICDR = (unsigned int)data[i];
while ((ICSR & ICSR_TEND_BIT) == 0); // 等待传输结束
if (ICSR & ICSR_NACKF_BIT) // 检查ACK
{
return -1; // 发送数据失败
}
}
// 发送停止位
ICCR |= ICCR_STOP_BIT;
while ((ICSR & ICSR_TEND_BIT) == 0); // 等待传输结束
return len; // 返回发送的数据长度
}
```
上述代码中,我们首先定义了IIC模块的寄存器地址和相关的位掩码。然后我们定义了初始化IIC模块的函数IIC_Init(),其中设置了控制寄存器ICCR和ICCR2,以及IIC时钟频率和总线速率。最后我们定义了发送数据的函数IIC_SendData(),其中使用了控制寄存器ICCR和状态寄存器ICSR来实现数据的发送和ACK的检测。需要注意的是,这只是一个简单的例子,实际的IIC驱动需要根据具体的应用场景进行修改和优化。
阅读全文