您的位置 首页 元件

ATMEGA16经过TWI对24C02进行读写

ifndefTWI_HdefineTWI_H主机模式启动状态码defineTWI_START0X08defineTWI_RESTART0X10主机发送模式状态码defineTWI

#ifndef TWI_H
#define TWI_H

//主机形式发动状况码
#define TWI_START 0X08
#define TWI_RESTART 0X10
//主机发送形式状况码
#define TWI_MT_SLA_ACK 0X18 //SLA+W 已发送,接纳到ACK
#define TWI_MT_SLA_NACK 0X20 //SLA+W 已发送,接纳到NOT ACK
#define TWI_MT_DATA_ACK 0X28 //数据已发送,接纳到ACK
#define TWI_MT_DATA_NACK 0X30 //数据已发送,接纳到NOT ACK
#define TWI_MT_ARB_LOST 0X38 //SLA+W 或数据的裁定失利
//主机接纳形式状况码
#define TWI_MR_ARB_LOST 0X38 //SLA+R 或数据的裁定失利
#define TWI_MR_SLA_ACK 0X40 //SLA+R 已发送,接纳到ACK
#define TWI_MR_SLA_NACK 0X48 //SLA+R 已发送,接纳到NOT ACK
#define TWI_MR_DATA_ACK 0X50 //数据已接纳,接纳到ACK
#define TWI_MR_DATA_NACK 0X58 //数据已接纳,接纳到NOT ACK
//从机接纳形式状况码
#define TWI_SR_SLA_ACK 0X60 //自己的SLA+W 现已被接纳,ACK 已回来
#define TWI_SR_ARB_LOST_SLA_ACK 0X68 //SLA+R/W 作为主机的裁定失利;自己的SLA+W 现已被接纳,ACK 已回来
#define TWI_SR_GCALL_ACK 0X70 //接纳到播送地址,ACK 已回来
#define TWI_SR_ARB_LOST_GCALL_ACK 0X78 //SLA+R/W 作为主机的裁定失利;接纳到播送地址ACK 已回来
#define TWI_SR_DATA_ACK 0X80 //曾经以自己的 SLA+W 被寻址;数据现已被接纳ACK 已回来
#define TWI_SR_DATA_NACK 0X88 //曾经以自己的 SLA+W 被寻址;数据现已被接纳NOT ACK 已回来
#define TWI_SR_GCALL_DATA_ACK 0X90 //曾经以播送方法被寻址;数据现已被接纳ACK 已回来
#define TWI_SR_GCALL_DATA_NACK 0X98 //曾经以播送方法被寻址;数据现已被接纳NOT ACK 已回来
#define TWI_SR_STOP 0XA0 //在以从机作业时接纳到STOP或重复START
//从机发送形式状况码
#define TWI_ST_SLA_ACK 0XA8 //自己的SLA+R 现已被接纳ACK 已回来
#define TWI_ST_ARB_LOST_SLA_ACK 0XB0 //SLA+R/W 作为主机的裁定失利;自己的SLA+R 现已被接纳ACK 已回来
#define TWI_ST_DATA_ACK 0XB8 //TWDR 里数据现已发送,接纳到ACK
#define TWI_ST_DATA_NACK 0XC0 //TWDR 里数据现已发送,接纳到NOT ACK
#define TWI_ST_LAST_DATA 0XC8 //TWDR 的一字节数据现已发送(TWAE = “0”);接纳到ACK
//其他状况
#define TWI_NO_INFO 0xF8 //没有相关的状况信息,TWINT=0
#define TWI_BUS_ERROR 0x00 //因为不合法的START或STOP引起的总线过错
//TWI使用时的操控位
#define TWI_Start() TWCR = (1< //清零TWINT、清零start状况、使能TWI.宣布START 信号
#define TWI_Wait() while (!(TWCR & (1< //等候TWINT 置位, TWINT 置位表明START 信号已宣布
#define TWI_Status (TWSR & 0xF8) //查验TWI 状况寄存器,屏蔽预分频位
#define TWI_Stop() TWCR=(1< //发送STOP 信号
#define TWI_SendAck() (TWCR|=(1< //使能TWI应对
#define TWI_SendNoAck() (TWCR&=~(1< //不使能TWI应对
#define TWI_RcvNckByte() (TWCR=(1< //使能TWI不发生应对
#define TWI_RcvAckByte() (TWCR=(1< //使能TWI、发生应对
#define TWI_Writebyte(twi_d) {TWDR=(twi_d);TWCR=(1<// 界说TWI运转状况的极性
#define TWI_ERR 0
#define TWI_CRR 1

#define TWI_WRITE 0
#define TWI_READ 1
void delay(uint ms)
{
uint i,j;
for(i=ms;i>0;i–)
for(j=1141;j>0;j–);
}

void TWI_Init(void)
{
TWBR=0X0F;
TWSR=0;
}

uchar TWIWait(void)
{
uchar i=100;
while(!(TWCR&(1< //等候TWINT置1
{
if((–i)==0)
return TWI_ERR;
}
return TWI_CRR;
}

uchar TWIStart(void)
{
TWI_Start();
if(TWIWait()==TWI_ERR)
return TWI_ERR;
if(TWI_Status!=TWI_START)
return TWI_ERR;
return TWI_CRR;
}

uchar TWIREStart(void)
{
TWI_Start();
if(TWIWait()==TWI_ERR)
return TWI_ERR;
if(TWI_Status!=TWI_RESTART)
return TWI_ERR;
return TWI_CRR;
}

uchar TWI_Write_WADDR(uchar addr)
{
TWI_Writebyte(addr);
if(TWIWait()==TWI_ERR)
return TWI_ERR;
if(TWI_Status!=TWI_MT_SLA_ACK)
return TWI_ERR;
return TWI_CRR;
}

uchar TWI_Write_RADDR(uchar addr)
{
TWI_Writebyte(addr);
if(TWIWait()==TWI_ERR)
return TWI_ERR;
if(TWI_Status!=TWI_MR_SLA_ACK)
return TWI_ERR;
return TWI_CRR;
}

uchar TWI_SendData(uchar data)
{
TWI_Writebyte(data);
if(TWIWait()==TWI_ERR)
return TWI_ERR;
if(TWI_Status!=TWI_MT_DATA_ACK)
return TWI_ERR;
return TWI_CRR;
}

uchar TWI_ReciveDATA_ACK(uchar *pdata)
{
TWI_RcvAckByte();
if(TWIWait()==TWI_ERR)
return TWI_ERR;
if(TWI_Status!=TWI_MR_DATA_ACK)
return TWI_ERR;
*pdata=TWDR;
return TWI_CRR;
}

uchar TWI_ReciveDATA_NACK(uchar *pdata)
{
TWI_RcvNckByte();
if(TWIWait()==TWI_ERR)
return TWI_ERR;
if(TWI_Status!=TWI_MR_DATA_NACK)
return TWI_ERR;
*pdata=TWDR;
return TWI_CRR;
}

uchar TWI_W_Byte(uchar Maddr,uchar Saddr,uchar data)
{
if(TWIStart()==TWI_ERR)
return TWI_ERR;
if(TWI_Write_WADDR((Maddr&0xfe)|TWI_WRITE)==TWI_ERR) //确保写入的SLA+W正确
return TWI_ERR;
if(TWI_SendData(Saddr)==TWI_ERR) //器材内寄存器的地址作为一般数据发送
return TWI_ERR;
if(TWI_SendData(data)==TWI_ERR) //发送要写入的数据
return TWI_ERR;
TWI_Stop();
return TWI_CRR;
}

uchar TWI_W_Data(uchar Maddr,uchar Saddr,uchar *pdata,uchar num)
{
uchar i;
if(TWIStart()==TWI_ERR)
return TWI_ERR;
if(TWI_Write_WADDR((Maddr&0xfe)|TWI_WRITE)==TWI_ERR) //确保写入的SLA+W正确
return TWI_ERR;
if(TWI_SendData(Saddr)==TWI_ERR) //器材内寄存器的地址作为一般数据发送
return TWI_ERR;
for(i=0;i {
if(TWI_SendData(*(pdata++))==TWI_ERR)
return TWI_ERR;
}
TWI_Stop();
return TWI_CRR;
}

uchar TWI_R_Byte(uchar Maddr,uchar Saddr,uchar *pdata)
{
if(TWIStart()==TWI_ERR)
return TWI_ERR;
if(TWI_Write_WADDR((Maddr&0xfe)|TWI_WRITE)==TWI_ERR) //确保写入的SLA+W正确
return TWI_ERR;
if(TWI_SendData(Saddr)==TWI_ERR) ////器材内寄存器的地址作为一般数据发送
return TWI_ERR;
if(TWIREStart()==TWI_ERR) //这儿的从头发送start很重要,这儿咱们的主机不想抛弃TWI的使用权 参看《浅显易懂AVR单片机》289页
return TWI_ERR;
if(TWI_Write_RADDR((Maddr&0xfe)|TWI_READ)==TWI_ERR) //参看《浅显易懂AVR单片机》289页
return TWI_ERR;
if(TWI_ReciveDATA_NACK(pdata)==TWI_ERR) //读取数据时,最终1字节的数据读取完结今后发送NAK而不是ACK
return TWI_ERR;
TWI_Stop();
return TWI_CRR;
}

uchar TWI_R_Data(uint Maddr,uchar Saddr,uchar *pdata,uchar num)
{
uchar i;
if(TWIStart()==TWI_ERR)
return TWI_ERR;
if(TWI_Write_WADDR((Maddr&0xfe)|TWI_WRITE)==TWI_ERR)
return TWI_ERR;
if(TWI_SendData(Saddr)==TWI_ERR)
return TWI_ERR;
if(TWIREStart()==TWI_ERR)
return TWI_ERR;
if(TWI_Write_RADDR((Maddr&0xfe)|TWI_READ)==TWI_ERR)
return TWI_ERR;
for(i=0;i {
if(TWI_ReciveDATA_ACK(pdata+i)==TWI_ERR)
return TWI_ERR;
}
if(TWI_ReciveDATA_NACK(pdata+i)==TWI_ERR) //读取数据时,最终1字节的数据读取完结今后发送NAK而不是ACK,这点很重要
return TWI_ERR;
TWI_Stop();
return TWI_CRR;
}

uchar TWI_W_NAddr(uchar addr,uchar data)
{
if(TWIStart()==TWI_ERR)
return TWI_ERR;
if(TWI_Write_WADDR(addr)==TWI_ERR)
return TWI_ERR;
if(TWI_SendData(data)==TWI_ERR)
return TWI_ERR;
TWI_Stop();
return TWI_CRR;
}

uchar TWI_R_NAddr(uchar addr,uchar *pdata)
{
if(TWIStart()==TWI_ERR)
return TWI_ERR;
if(TWI_Write_RADDR(addr)==TWI_ERR)
return TWI_ERR;
if(TWI_ReciveDATA_NACK(pdata)==TWI_ERR)
return TWI_ERR;
TWI_Stop();
return TWI_CRR;
}
#endif

#include
#include “IIC.h”
void port_init(void)
{
DDRB=0XFF;
PORTB=0XFF;
TWCR=0X44;
DDRD=0XFF;
PORTD=0XFF;
}

uchar temp1[8]={18,17,16,15,14,13,12,11};
uchar temp2[8]={0};
uchar temp3[8]={0,0,0,0,0,0,0,0};
void main(void)
{
TWI_Init();
port_init();
if(TWI_W_Data(0Xa0,0x00,temp1,8)==TWI_ERR)
PORTD&=~(BIT(PD0));
delay(5); //这儿的延时很重要,假如不加,读出来的数据很是匪夷所思
if((TWI_R_Data(0Xa1,0x00,temp2,8))==TWI_ERR)
PORTD&=~BIT(PD7);
if(temp2[1]==17)
PORTB=0X00;
while(1)
{
if(temp2[0]==18)
{
PORTB=0XFE;
delay(100);
PORTB=0XFF;
delay(50);
}
if(temp2[1]==17)
{
PORTB=0XFD;
delay(100);
PORTB=0XFF;
delay(50);
}
if(temp2[2]==16)
{
PORTB=0XFB;
delay(100);
PORTB=0XFF;
delay(50);
}

if(temp2[3]==15)
{
PORTB=0XF7;
delay(100);
PORTB=0XFF;
delay(50);
}

if(temp2[4]==14)
{
PORTB=0XEF;
delay(100);
PORTB=0XFF;
delay(50);
}

if(temp2[5]==13)
{
PORTB=0XDF;
delay(100);
PORTB=0XFF;
delay(50);
}

if(temp2[6]==12)
{
PORTB=0XBF;
delay(100);
PORTB=0XFF;
delay(50);
}

if(temp2[7]==11)
{
PORTB=0X7F;
delay(100);
PORTB=0XFF;
delay(50);
}
}
}

仿真PROTUES7.5图如下


示波器检查波形如图

I%&&&&&%接纳数据检查如图

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/xinpin/yuanjian/261064.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部