LPC2478的硬件IIC使用
扫描二维码
随时随地手机看文章
LPC2478的IIC使用
LPC2478带有三个IIC接口,每个IIC都可以工作在主机或者从机模式下,LPC的IIC的架构是一种状态机的形式,在不同的的时间做不同的工作之后有不同的状态来表示,
简单来说,就是发送起始字节之后会有一个状态,接收到ACK之后会有一个状态,软件上根据已知的外设状态来进行下一步操作
具体的状态请查看数据手册,IIC的可用寄存器如下
对应不同的驱动方式,例如I2EN为1+STA为1,代表发送起始位+从机地址
将置位寄存器的数据清零,BIT一一对应
状态机的核心
数据发送缓存
从机地址,最高位读写位硬件自动加上
还有两个寄存器是SCL低电平占空比和高电平占空比,均为50%即可
具体代码如下所示
#ifndef__IIC0_H_
#define__IIC0_H_
#include"common.h"
#include"lpc24xx.h"
#include"clock.h"
#defineSTATUS_SENDSTART0X08
#defineSTATUS_REPEATSTART0X10
#defineSTATUS_SENDSLAVE_ACK0X18
#defineSTATUS_SENDSLAVE_NACK0X20
#defineSTATUS_SENDDATA_ACK0X28
#defineSTATUS_SENDDATA_NACK0X30
#defineSTATUS_LOSS0X38
#defineSTATUS_READADDR_NACK0X48
#defineSTATUS_READADDR_ACK0X40
#defineSTATUS_RECV_ACK0X50
#defineSTATUS_RECV_NACK0X58
voidIIC0Init(u32baud);
u8IIC0Start(void);
u8IIC0SendWriteAddr(u8addr);
u8IIC0SendData(u8data);
u8IIC0SendStop(void);
u8IIC0SendReadAddr(u8addr);
u8IIC0ReadData(u8*value,u8ack);
u8IIC0RepeatStart(void);
#endif
#include"iic.h"
#defineI20EN6//接口使能
#defineSTA5//起始标志
#defineSTO4//停止标志
#defineSI3//中断标志
#defineAA2//应答标志
#defineI20ENC6//
#defineSTAC5
#defineSIC3
#defineAAC2
#defineSTATE(I20STAT&0xf8)
voidIIC0Init(u32baud)
{
u32t=(SystemCoreClock/4)/baud;
//打开IIC时钟
PCONP|=(1<<7);
//配置IIC引脚sda
PINSEL1&=~(0x03<<22);
PINSEL1|=(0x01<<22);
PINMODE1&=~(0x03<<22);
PINMODE1|=(0x01<<22);
//scl
PINSEL1&=~(0x03<<24);
PINSEL1|=(0x01<<24);
PINMODE1&=~(0x03<<24);
PINMODE1|=(0x01<<24);
I20SCLL=t/2;
I20SCLH=t/2;
I20CONSET=(1< } //等待指定的状态 //失败返回1成功返回0 u8WaitResponse(u8response) { u8retry=200; while(--retry) { if(STATE==response)break; } if(retry)return0; elsereturn1; } u8IIC0Start(void) { I20CONCLR=(1< I20CONSET=(1< returnWaitResponse(STATUS_SENDSTART); } u8IIC0RepeatStart(void) { //repeatstart I20CONCLR=(1< I20CONSET=(1< returnWaitResponse(STATUS_REPEATSTART); } u8IIC0SendWriteAddr(u8addr) { //dev_addr I20DAT=addr; I20CONSET=(1< I20CONCLR=(1< returnWaitResponse(STATUS_SENDSLAVE_ACK); } u8IIC0SendData(u8data) { I20DAT=data; I20CONSET=(1< I20CONCLR=(1< returnWaitResponse(STATUS_SENDDATA_ACK); } u8IIC0SendStop(void) { I20CONCLR=(1< I20CONCLR=(1< return0; } u8IIC0SendReadAddr(u8addr) { I20DAT=addr; I20CONSET=(1< I20CONCLR=(1< returnWaitResponse(STATUS_READADDR_ACK); } u8IIC0ReadData(u8*value,u8ack) { if(ack) { I20CONSET=(1< I20CONCLR=(1< if(WaitResponse(STATUS_RECV_ACK))return1; } else { I20CONCLR=(1< if(WaitResponse(STATUS_RECV_NACK))return1; } *value=I20DAT; return0; }