LPC2478的硬件IIC使用
LPC2478的IIC使用
LPC2478帶有三個(gè)IIC接口,每個(gè)IIC都可以工作在主機(jī)或者從機(jī)模式下,LPC的IIC的架構(gòu)是一種狀態(tài)機(jī)的形式,在不同的的時(shí)間做不同的工作之后有不同的狀態(tài)來(lái)表示,
簡(jiǎn)單來(lái)說(shuō),就是發(fā)送起始字節(jié)之后會(huì)有一個(gè)狀態(tài),接收到ACK之后會(huì)有一個(gè)狀態(tài),軟件上根據(jù)已知的外設(shè)狀態(tài)來(lái)進(jìn)行下一步操作
具體的狀態(tài)請(qǐng)查看數(shù)據(jù)手冊(cè),IIC的可用寄存器如下
對(duì)應(yīng)不同的驅(qū)動(dòng)方式,例如I2EN為1+STA為1,代表發(fā)送起始位+從機(jī)地址
將置位寄存器的數(shù)據(jù)清零,BIT一一對(duì)應(yīng)
狀態(tài)機(jī)的核心
數(shù)據(jù)發(fā)送緩存
從機(jī)地址,最高位讀寫(xiě)位硬件自動(dòng)加上
還有兩個(gè)寄存器是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//起始標(biāo)志
#defineSTO4//停止標(biāo)志
#defineSI3//中斷標(biāo)志
#defineAA2//應(yīng)答標(biāo)志
#defineI20ENC6//
#defineSTAC5
#defineSIC3
#defineAAC2
#defineSTATE(I20STAT&0xf8)
voidIIC0Init(u32baud)
{
u32t=(SystemCoreClock/4)/baud;
//打開(kāi)IIC時(shí)鐘
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< } //等待指定的狀態(tài) //失敗返回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; }