?? twi._c
字號:
#include "config.h"
volatile uint8 main_tmp=0;
//extern volatile uint8 main_tmp=0;
//TWI master initialize
// bit rate:100
void twi_master_init(void)
{
TWCR= 0x00; //disable twi
TWBR= 0x64; //set bit rate
TWSR= 0x00; //set prescale
TWAR= 0x00; //set slave address
TWCR= 0x04; //enable twi
}
//TWI slave initialize
// bit rate:100
void twi_slave_init(uint8 add)
{
TWCR= 0x00; //disable twi
TWBR= 0x64; //set bit rate
TWSR= 0x00; //set prescale
TWAR= add; //set slave address 從機(jī)地址為 0x01
TWCR= (1<<TWEN)|(1<<TWEA)|(1<<TWIE); //enable twi
//TWEN必須置位以使能TWI接口。TWEA也要置位以使主機(jī)尋址到自己(從機(jī)地址或廣播) 時(shí)返回確認(rèn)信息ACK
}
//總線上起動(dòng)開始條件
void i2c_start(void)
{
TWCR= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))); //等待START 信號成功發(fā)送
}
//把一個(gè)字節(jié)數(shù)據(jù)輸入器件, 返回TWI狀態(tài)
//發(fā)送地址和數(shù)據(jù)都可以使用本函數(shù)
uint8 i2c_write(uint8 data)
{
TWDR = data;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
_NOP();
return(TWSR&0b11111000); //TWSR高五位為I2C工作狀態(tài)。
}
//從器件讀出一個(gè)字節(jié)
uint8 i2c_read(void)
{
TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
return(TWDR);
}
//總線上起動(dòng)停止條件
void i2c_stop(void)
{
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}
//操作步驟: 啟動(dòng),發(fā)送地址,發(fā)送數(shù)據(jù),關(guān)閉總線
void i2c_maste_transt(uint8 addr, uint8 data)
{
i2c_start();
if(i2c_write(addr)==TW_MT_SLA_ACK) //發(fā)送地址成功并收到ACK
{
i2c_write(data);
}
i2c_stop();
}
#if TWI_MOD==0 //從機(jī)模式
#pragma interrupt_handler twi_isr:18
void twi_isr(void)
{
//twi event
switch (TWSR&0xF8)
{
//從接收
case TW_SR_SLA_ACK:
case TW_SR_ARB_LOST_SLA_ACK:
case TW_SR_GCALL_ACK:
case TW_SR_ARB_LOST_GCALL_ACK:
Twi_Ack(); //返回ACK
break;
case TW_SR_DATA_ACK:
case TW_SR_DATA_NACK:
main_tmp = TWDR;
PORTA = ~ TWDR; //接收數(shù)據(jù)并顯示
Twi_Ack(); //返回ACK
break;
case TW_SR_GCALL_DATA_ACK:
case TW_SR_GCALL_DATA_NACK:
Twi_Ack(); //返回ACK
break;
case TW_SR_STOP:
Twi_Ack();
break;
//從發(fā)送*****************************
case TW_ST_SLA_ACK: // 0xA8: 自己的SLA+R 已經(jīng)被接收,ACK 已返回
case TW_ST_ARB_LOST_SLA_ACK:// 0xB0: SLA+R/W 作為主機(jī)的仲裁失敗;自己的SLA+R 已經(jīng)被接收,ACK 已返回
// 被選中為從讀出 (數(shù)據(jù)將從傳回主機(jī))
TWDR=main_tmp; //發(fā)送全局變量中值
Twi_Ack();
break;
case TW_ST_DATA_ACK: // 0xB8: TWDR 里數(shù)據(jù)已經(jīng)發(fā)送,接收到ACK
//發(fā)送數(shù)據(jù)位
TWDR=main_tmp;
//Twi_Ack(); //一次只發(fā)一個(gè)數(shù),告訴主機(jī)結(jié)束
break;
case TW_ST_DATA_NACK: // 0xC0: TWDR 里數(shù)據(jù)已經(jīng)發(fā)送接收到NOT ACK
case TW_ST_LAST_DATA: // 0xC8: TWDR 的一字節(jié)數(shù)據(jù)已經(jīng)發(fā)送(TWAE = “0”);接收到ACK
// 全部完成
// 從方式開放
Twi_NoAcK();
twi_slave_init(0x50); //重新回到初始化狀態(tài)
break;
case TW_NO_INFO: // 0xF8: 沒有相關(guān)的狀態(tài)信息;TWINT = “0”
// 無操作
break;
case TW_BUS_ERROR: // 0x00: 由于非法的START 或STOP 引起的總線錯(cuò)誤
// 內(nèi)部硬件復(fù)位,釋放總線
TWCR=TWCR&TWCR_CMD_MASK|(1<<TWINT)|(1<<TWSTO)|(1<<TWEA);
break;
default:
break;
}
}
#endif
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -