<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > IAR For AVR 兩線(xiàn)串行接口 TWI 應用

IAR For AVR 兩線(xiàn)串行接口 TWI 應用

作者: 時(shí)間:2016-12-03 來(lái)源:網(wǎng)絡(luò ) 收藏
ATMEL的TWI 和 PHILIPS的IIC 基本上應該是算一個(gè)東西,但是他們在名義上是不同的,這樣誰(shuí)都不用支付給對方使用費。他們的協(xié)議是一樣的,所有我們作為使用者基本可以簡(jiǎn)單的看成 TWI就是IIC 。

廢話(huà)說(shuō)完,開(kāi)始正題。這次是關(guān)于在A(yíng)TMega16 平臺下的硬件IIC(還不太習慣說(shuō)TWI)的使用。在A(yíng)TMega16的Datasheet里我們可以看到很強大的功能,主從設置很多。本文只說(shuō)一種最常用的方式,那就是“ATMega16 硬件TWI 的 掃描發(fā)送 和 掃描讀取&rdquo;。

本文引用地址:http://dyxdggzs.com/article/201612/325112.htm

首先要明確TWI 發(fā)送和接受的流程:

發(fā)送:

1,設定數據傳輸波特率

2,發(fā)送START信號,等待應答 ==》 《== 應答信號

3,發(fā)送芯片地址,等待應答 ==》 《==應答信號

4,發(fā)送數據的絕對地址,等待應答 ==》 《==應答信號

5,發(fā)送要寫(xiě)入的數據,等待應答 ==》 《==應答信號

6,發(fā)送STOP信號,釋放總線(xiàn) ==》 數據寫(xiě)入成功

接收:

1,設定數據傳輸波特率

2,發(fā)送START信號,等待應答 ==》 《== 應答信號

3,發(fā)送芯片地址,等待應答 ==》 《==應答信號

4,發(fā)送數據的絕對地址,等待應答 ==》 《==應答信號

5,發(fā)送RESTART信號,等待應答 ==》 《==應答信號

6,發(fā)送芯片地址并注明讀操作,等待應答 ==》 《==應答信號

7,讀取數據,等待應答 ==》 《==應答信號

8,發(fā)送STOP信號,釋放總線(xiàn) ==》 數據讀操作成功

應用芯片 :ATMega 16 晶振 : 7.3728

代碼文件:Project

|___TWI.C

| |_____ IAR_DELAY.H

|___UART.C

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

IAR_DELAY.H

#ifndef __IAR_DELAY_H
#define __IAR_DELAY_H

#include

#define XTAL 7.3728 //可定義為你所用的晶振頻率(單位Mhz)


#define delay_us(x) __delay_cycles ( (unsigned long)(x * XTAL) )
#define delay_ms(x) __delay_cycles ( (unsigned long)(x * XTAL*1000) )
#define delay_s(x) __delay_cycles ( (unsigned long)(x * XTAL*1000000) )

#endif

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

UART.C

#include
#define uchar unsigned char
#define uint unsigned int

//###########################################################
/*串口初始化函數*/
voidUart_Init(void)
{
UCSRB = (1<UCSRC = (1<

UBRRH=0x00; //設置波特率寄存器低位字節
UBRRL=47; //9600 //設置波特率寄存器高位字節

DDRD_Bit1=1; //配置TX為輸出(很重要)
}
//###########################################################
/*發(fā)送一個(gè)字符數據,查詢(xún)方式*/
voidUart_Transmit(uchar data)
{
while(!(UCSRA&(1< //while(UCSRA_UDRE==0); /* 等待發(fā)送緩沖器為空*/
UDR = data; /* 發(fā)送數據*/
}

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

#include
#include "IAR_DELAY.H"
#define uchar unsigned char
#define uint unsigned int

void Uart_Init(void);
void Uart_Transmit(uchar data);


//變量聲明
#define EEPROM_BUS_ADDRESS 0xA0 //器件地址
/*#####################################################################*/
/*從器件地址位定義:______________________________________-------------*/
/* AT24C02 | 1 | 0 | 1 | 0 | A2 | A1 | A0 | R/~W |------------*/
/* ---------------------------------------------------*/
/*#####################################################################*/
//主機發(fā)送模式時(shí)各狀態(tài)字的后續動(dòng)作
#define TW_START 0x08 //開(kāi)始信號已發(fā)出
#define TW_REP_START 0x10 //重復開(kāi)始信號已發(fā)出
#define TW_MT_SLA_ACK 0x18 //寫(xiě)字節已發(fā)出并受到ACK信號
#define TW_MT_SLA_NACK 0x20 //寫(xiě)字節已發(fā)出并受到NACK信號
#define TW_MT_DATA_ACK 0x28 //數據已發(fā)出并受到ACK 信號
#define TW_MT_DATA_NACK 0x30 //數據已發(fā)出并受到NACK 信號
#define TW_MT_ARB_LOST 0x38 //丟失總線(xiàn)控制權
//主機接收模式時(shí)各狀態(tài)字的后續動(dòng)作
#define TW_MR_ARB_LOST 0x38 //丟失總線(xiàn)控制權,未收到應答信號
#define TW_MR_SLA_ACK 0x40 //讀命令已發(fā)出并受到ACK
#define TW_MR_SLA_NACK 0x48 //讀命令已發(fā)出并受到NACK
#define TW_MR_DATA_ACK 0x50 //數據已收到,ACK已發(fā)出
#define TW_MR_DATA_NACK 0x58 //數據已收到,NACK已發(fā)出

#define IIC_Start() TWCR =(1< // TWSTA位 會(huì )讓硬件在總線(xiàn)上產(chǎn)生一個(gè)START的信號 , 聲明自己希望成為主機
// TWEN 位 使能TWI功能,將 PC0 和 PC1 管腳切換到第二功能上來(lái), 如果清零則為中斷 TWI的傳輸
#define IIC_Stop() TWCR =(1<

#define IIC_Wait() while(!(TWCR&(1<

//##############################################################################
/*I2C總線(xiàn)單字節寫(xiě)入*/
unsigned char twi_write(unsigned char addr, unsigned char dd)
{
TWBR = 10; //設定波特率

/*start 啟動(dòng)*/
IIC_Start(); //硬件發(fā)送START信號,并且清零TWINT位,使能硬件TWI,使TWI開(kāi)始工作
IIC_Wait(); //等待 發(fā)送START完成 TWINT位置位
if ((TWSR & 0xF8) != 0x08) return 0;//檢測到TWINT位置位,比對TWSR寄存器內的狀態(tài)量,如果正確則向下進(jìn)行數據傳輸,錯誤返回 0

/*SLA_W 芯片地址*/
TWDR = EEPROM_BUS_ADDRESS ; //芯片地址 0xA0 ,賦值給數據寄存器 TWDR ,等待發(fā)送
TWCR = (1 << TWINT) | (1 << TWEN); //對控制寄存器TWCR的 TWINT 位軟件寫(xiě)1進(jìn)行清零,然后 使能TWI硬件接口 ,讓TWI進(jìn)行工作,發(fā)送 TWDR寄存器 中的數據
IIC_Wait(); //等待數據發(fā)送完畢 TWINT重新置位
if ((TWSR & 0xF8) != 0x18) return 0;//檢測到TWINT位置位,比對TWSR寄存器內的狀態(tài)量 , 如果正確則向下進(jìn)行數據傳輸,錯誤返回 0

/*addr 操作地址*/
TWDR = addr; //將寫(xiě)入數據的絕對地址 ,賦值給數據寄存器 TWDR ,等待發(fā)送
TWCR = (1 << TWINT) | (1 << TWEN); //對控制寄存器TWCR的 TWINT 位軟件寫(xiě)1進(jìn)行清零,然后 使能TWI硬件接口 ,讓TWI進(jìn)行工作,發(fā)送 TWDR寄存器 中的數據
IIC_Wait(); //等待數據發(fā)送完畢 TWINT重新置位
if ((TWSR & 0xF8) != 0x28) return 0;//檢測到TWINT位置位,比對TWSR寄存器內的狀態(tài)量 , 如果正確則向下進(jìn)行數據傳輸,錯誤返回 0

/*dd 寫(xiě)入數據*/
TWDR = dd; //將要寫(xiě)入的數據 ,賦值給數據寄存器 TWDR ,等待發(fā)送
TWCR = (1 << TWINT) | (1 << TWEN); //對控制寄存器TWCR的 TWINT 位軟件寫(xiě)1進(jìn)行清零,然后 使能TWI硬件接口 ,讓TWI進(jìn)行工作,發(fā)送 TWDR寄存器 中的數據
IIC_Wait(); //等待數據發(fā)送完畢 TWINT重新置位
if ((TWSR & 0xF8) != 0x28) return 0;//檢測到TWINT位置位,比對TWSR寄存器內的狀態(tài)量 , 如果正確則向下進(jìn)行數據傳輸,錯誤返回 0

/*stop 停止*/
IIC_Stop(); //數據傳輸完成,發(fā)送STOP信號,釋放對總線(xiàn)的控制
return 1; //寫(xiě)入數據成功 ,返回1 ,用來(lái)判斷是否成功寫(xiě)入數據

}
//##############################################################################
/*I2C總線(xiàn)單字節讀取*/
unsigned char twi_read(unsigned char addr)
{

unsigned char Receive_Byte ;
TWBR = 2; //設定波特率

/*start 啟動(dòng)*/
IIC_Start(); //硬件發(fā)送START信號,并且清零TWINT位,使能硬件TWI,使TWI開(kāi)始工作
IIC_Wait(); //等待 發(fā)送START完成 TWINT位置位
if ((TWSR & 0xF8) != 0x08) return 0;//檢測到TWINT位置位,比對TWSR寄存器內的狀態(tài)量,如果正確則向下進(jìn)行數據傳輸,錯誤返回 0

/*SLA_W 芯片地址*/
TWDR = EEPROM_BUS_ADDRESS; //芯片地址 0xA0 ,賦值給數據寄存器 TWDR ,等待發(fā)送
TWCR = (1 << TWINT) | (1 << TWEN); //對控制寄存器TWCR的 TWINT 位軟件寫(xiě)1進(jìn)行清零,然后 使能TWI硬件接口 ,讓TWI進(jìn)行工作,發(fā)送 TWDR寄存器 中的數據
IIC_Wait(); //等待數據發(fā)送完畢 TWINT重新置位
if ((TWSR & 0xF8) != 0x18) return 0;//檢測到TWINT位置位,比對TWSR寄存器內的狀態(tài)量 , 如果正確則向下進(jìn)行數據傳輸,錯誤返回 0

/*addr 操作地址*/
TWDR = addr; //將寫(xiě)入數據的絕對地址 ,賦值給數據寄存器 TWDR ,等待發(fā)送
TWCR = (1 << TWINT) | (1 << TWEN); //對控制寄存器TWCR的 TWINT 位軟件寫(xiě)1進(jìn)行清零,然后 使能TWI硬件接口 ,讓TWI進(jìn)行工作,發(fā)送 TWDR寄存器 中的數據
IIC_Wait(); //等待數據發(fā)送完畢 TWINT重新置位
if ((TWSR & 0xF8) != 0x28) return 0;//檢測到TWINT位置位,比對TWSR寄存器內的狀態(tài)量 , 如果正確則向下進(jìn)行數據傳輸,錯誤返回 0

/*restart 重啟動(dòng)*/
IIC_Start(); //硬件發(fā)送 RESTART 信號,并且清零TWINT位,使能硬件TWI,使TWI開(kāi)始工作
IIC_Wait(); //等待數據發(fā)送完畢 TWINT重新置位
if ((TWSR & 0xF8) != 0x10) return 0;//檢測到TWINT位置位,比對TWSR寄存器內的狀態(tài)量 , 如果正確則向下進(jìn)行數據傳輸,錯誤返回 0

/*SLA_R 芯片地址*/
TWDR = 0xA1; //芯片地址 0xA0 并注明是讀取操作(最后一位為 1 ),賦值給數據寄存器 TWDR ,等待發(fā)送
TWCR = (1 << TWINT) | (1 << TWEN); //對控制寄存器TWCR的 TWINT 位軟件寫(xiě)1進(jìn)行清零,然后 使能TWI硬件接口 ,讓TWI進(jìn)行工作,發(fā)送 TWDR寄存器 中的數據
IIC_Wait(); //等待數據發(fā)送完畢 TWINT重新置位
if ((TWSR & 0xF8) != 0x40) return 0;//檢測到TWINT位置位,比對TWSR寄存器內的狀態(tài)量 , 如果正確則向下進(jìn)行數據傳輸,錯誤返回 0

/*讀取數據*/
TWCR = (1 << TWINT) | (1 << TWEN); //對控制寄存器TWCR的 TWINT 位軟件寫(xiě)1進(jìn)行清零,然后 使能TWI硬件接口 ,讓TWI進(jìn)行工作,發(fā)送 TWDR寄存器 中的數據
IIC_Wait(); //等待數據發(fā)送完畢 TWINT重新置位
if ((TWSR & 0xF8) != 0x58) return 0;//檢測到TWINT位置位,比對TWSR寄存器內的狀態(tài)量 , 如果正確則向下進(jìn)行數據傳輸,錯誤返回 0
Receive_Byte = TWDR; //讀取到的數據放到局部變量里

/*stop 停止*/
IIC_Stop(); //數據傳輸完成,發(fā)送STOP信號,釋放對總線(xiàn)的控制

return Receive_Byte; //將讀取到的數據作為函數的輸出


}
//##############################################################################
/*主函數*/
void main(void)
{
uchar c,d;
Uart_Init(); //串口初始化
delay_us(20);
Uart_Transmit(0x55); //測試串口

c = twi_write(0x51,0xf8); //在地址0x51里寫(xiě)入數據0x22
Uart_Transmit(c); //將返回值發(fā)送到串口測試是否寫(xiě)入成功

delay_ms(2);

d = twi_read(0x51); //將地址0x51里的數據讀出來(lái)
Uart_Transmit(d); //將讀取到的數據發(fā)送串口
while(1);
}



評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>