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"



#define STATUS_SENDSTART        0X08
#define STATUS_REPEATSTART      0X10
#define STATUS_SENDSLAVE_ACK    0X18
#define STATUS_SENDSLAVE_NACK   0X20
#define STATUS_SENDDATA_ACK     0X28
#define STATUS_SENDDATA_NACK    0X30
#define STATUS_LOSS             0X38
#define STATUS_READADDR_NACK    0X48
#define STATUS_READADDR_ACK     0X40
#define STATUS_RECV_ACK         0X50
#define STATUS_RECV_NACK         0X58



void IIC0Init(u32 baud);

u8 IIC0Start(void);

u8 IIC0SendWriteAddr(u8 addr);

u8 IIC0SendData(u8 data);

u8 IIC0SendStop(void);

u8 IIC0SendReadAddr(u8 addr);

u8 IIC0ReadData(u8* value,u8 ack);

u8 IIC0RepeatStart(void);

#endif







#include "iic.h"

#define I20EN  6		//接口使能
#define STA   5		//起始标志
#define STO   4		//停止标志
#define SI    3	    //中断标志
#define AA    2		//应答标志

#define I20ENC 6     //
#define STAC  5
#define SIC   3
#define AAC   2

#define STATE (I20STAT & 0xf8)

void IIC0Init(u32 baud)
{
    u32 t = (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<<I20EN);//接口使能
}
//等待指定的状态
//失败返回1 成功返回0
u8 WaitResponse(u8 response)
{
    u8 retry = 200;
    while(--retry)
    {
        if(STATE == response)break;
    }
    if(retry)return 0;
    else return 1;
}

u8 IIC0Start(void)
{
    I20CONCLR = (1<<SIC)|(1<<STAC)|(1<<AAC);
	//Start
	I20CONSET = (1<<STA);
    return WaitResponse(STATUS_SENDSTART);
}

u8 IIC0RepeatStart(void)
{
    //repeat start
	I20CONCLR = (1<<SIC);
	I20CONSET = (1<<STA);
    return WaitResponse(STATUS_REPEATSTART);
}

u8 IIC0SendWriteAddr(u8 addr)
{
    //dev_addr
	I20DAT = addr;
	I20CONSET = (1<<AA);
	I20CONCLR = (1<<SIC)|(1<<STAC);
    return WaitResponse(STATUS_SENDSLAVE_ACK);
}

u8 IIC0SendData(u8 data)
{
    I20DAT = data;
	I20CONSET = (1<<AA);
	I20CONCLR = (1<<SIC);
    return WaitResponse(STATUS_SENDDATA_ACK);
}

u8 IIC0SendStop(void)
{
    I20CONCLR = (1<<SIC)|(1<<STAC)|(1<<AAC);
    I20CONSET = (1<<STO);
	I20CONCLR = (1<<SIC);
    return 0;
}

u8 IIC0SendReadAddr(u8 addr)
{
    I20DAT = addr;
	I20CONSET = (1<<AA);
	I20CONCLR = (1<<SIC)|(1<<STAC);
    return WaitResponse(STATUS_READADDR_ACK);
}

u8 IIC0ReadData(u8* value,u8 ack)
{
    if(ack)
    {
        I20CONSET = (1<<AA);
		I20CONCLR = (1<<SIC);
        if( WaitResponse(STATUS_RECV_ACK))return 1;
    }
    else
    {
        I20CONCLR = (1<<AAC)|(1<<SIC);
        if(WaitResponse(STATUS_RECV_NACK))return 1;
    }    
    *value = I20DAT;
    return 0;
}





原文地址:https://www.cnblogs.com/dengxiaojun/p/4279397.html