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;
}
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号