?? icc_m.c
字號(hào):
/**************************************************************************
文件名:icc_m.c
功 能;半雙工 同步 串行通訊 主機(jī)例程
不采用中斷
MCU :Mega16L
晶 振:內(nèi)部8MHz
硬 件:主機(jī) 從機(jī)
PC0(SCL)--- PC0(SCL)
PC1(SDA)--- PC1(SDA)
說(shuō) 明:從機(jī)地址0B00010000
連 線:主機(jī)PORTA與LED相連
運(yùn)行說(shuō)明:1)上位機(jī)通過(guò)串口向主機(jī)寫(xiě)(任意)一個(gè)字,以啟動(dòng)傳輸
主機(jī)首先向上位機(jī)回發(fā)來(lái)自上位機(jī)的數(shù)據(jù)
如果上位機(jī)向主機(jī)發(fā)送0x01,則主機(jī)從從機(jī)中讀取數(shù)據(jù),
并向上位機(jī)發(fā)送讀取的數(shù)據(jù)
否則向從機(jī)中寫(xiě)入來(lái)自上位機(jī)的數(shù)據(jù)
2)主機(jī)向從機(jī)發(fā)送數(shù)據(jù),每次發(fā)送后都點(diǎn)亮LED:
向從機(jī)寫(xiě)時(shí),LED的亮暗與主機(jī)接收到的來(lái)自上位機(jī)的數(shù)據(jù)對(duì)應(yīng);
從從機(jī)讀時(shí),LED的亮暗與主機(jī)接收到的來(lái)自從機(jī)的數(shù)據(jù)對(duì)應(yīng)。
已通過(guò)實(shí)驗(yàn)驗(yàn)證!
**************************************************************************/
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/delay.h>
#include <avr/wdt.h>
#include <compat/twi.h>
#define uchar unsigned char
#define uint unsigned int
#define ulint unsigned long int
#define slave 0x10
#define read 0x01
#define write 0xfe
uchar l,rv;
void Initial_IO(void)
{DDRC=0x00;
PORTC=(1<<PC0)|(1<<PC1); //TWI兩個(gè)端口帶上拉電阻輸入
DDRA=0xff; //A口輸出
PORTA=0xff;
}
void Initial(void)
{SREG&=0xEF; //關(guān)全局中斷
/*********串口設(shè)定***********/
UBRRH=0x00;
UBRRL=25; //波特率設(shè)定,19200bps
UCSRB=0x98; //RXCIE=1,開(kāi)USART接收結(jié)束中斷
//RXEN=1,接受使能
//TXEN=1,發(fā)送使能
//8位數(shù)據(jù)長(zhǎng)度
UCSRC=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1)|(1<<UPM1); //寫(xiě)UCSRC寄存器
//偶校驗(yàn)位
//1位停止位
//8位數(shù)據(jù)長(zhǎng)度
/********看門(mén)狗設(shè)置*********/
wdt_enable(WDTO_250MS);//看門(mén)狗定時(shí)器開(kāi)啟,定時(shí)時(shí)間1.0s
/*******全局中斷使能********/
SREG=SREG|0x80;
}
/**************TWI主機(jī)操作***************/
//初始化TWI主機(jī)
void Initial_TWI_m(void)
{TWBR=200;
}
//發(fā)送START信號(hào)
uchar twi_start(void)
{TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//清上一步動(dòng)作結(jié)束時(shí)置位的中斷標(biāo)志;
//置位TWSTA,準(zhǔn)備發(fā)送START:若總線空閑則發(fā)送START,
//若總線忙則等待,直到檢測(cè)到一個(gè)STOP,發(fā)送START
//發(fā)送START,聲明自己希望為主機(jī);
//發(fā)送START完畢后,必須軟件清零START
//使能TWI操作與激活TWI接口
while (!(TWCR & (1<<TWINT))); //等待START發(fā)送完成
//發(fā)送完成后TWINT置位,TWI數(shù)據(jù)傳輸被終止
return TW_STATUS; //在TWINT清零前完成對(duì)TWSR的訪問(wèn)
}
//寫(xiě)1個(gè)字節(jié)
uchar twi_write(uchar c)
{TWDR=c; //將1個(gè)字節(jié)(地址+方向,或者數(shù)據(jù))載入TWDR
TWCR=(1<<TWINT)|(1<<TWEN); //清上一步動(dòng)作結(jié)束時(shí)置位的中斷標(biāo)志;
//使能TWI操作與激活TWI接口,啟動(dòng)發(fā)送該字節(jié)
while (!(TWCR & (1<<TWINT))) ; //等待該字節(jié)發(fā)送完成
//發(fā)送完成后TWINT置位,TWI數(shù)據(jù)傳輸被終止
return TW_STATUS; //在TWINT清零前完成對(duì)TWSR的訪問(wèn)
}
//讀1個(gè)字節(jié),并根據(jù)ack給出相應(yīng)應(yīng)答: true時(shí)發(fā)ACK,false時(shí)發(fā)NACK
//uchar twi_read(uchar d,uchar ack)
uchar twi_read(uchar ack)
{uchar d,tmp=(1<<TWINT)|(1<<TWEN); //清上一步動(dòng)作結(jié)束時(shí)置位的中斷標(biāo)志;
//使能TWI操作與激活TWI接口,啟動(dòng)發(fā)送該字節(jié)
if(ack) tmp|=(1<<TWEA); //返回應(yīng)答ACK,表示接受到
//需要返回ACK,則置位TWEA,如果發(fā)生以下情況,發(fā)出ACK脈沖:
// 1)從機(jī)地址與主機(jī)發(fā)出的地址相符;
// 2)TWGCE置位時(shí)接收到廣播呼叫;
// 3)接收到一個(gè)字節(jié)
TWCR=tmp; //返回非應(yīng)答NACK,表示下一步不需再發(fā)送了
//需要返回NACK,不置位TWEA
while (!(TWCR & (1<<TWINT))) ; //等待接受字節(jié),返回ACK/NACK
//發(fā)送完成后TWINT置位,TWI數(shù)據(jù)傳輸被終止
d=TWDR; //在TWINT清零前完成對(duì)TWDR的訪問(wèn)
return d;
// return TW_STATUS; //在TWINT清零前完成對(duì)TWSR的訪問(wèn)
}
//發(fā)送STOP信號(hào)
void twi_stop(void)
{TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);//清上一步動(dòng)作結(jié)束時(shí)置位的中斷標(biāo)志;
//置位TWSTO,TWI接口將在總線上產(chǎn)生STOP,然后TWSTO自動(dòng)清零
//使能TWI操作與激活TWI接口
}
int main(void)
{Initial_IO();
Initial();
Initial_TWI_m();
while(1)
{wdt_reset();
_delay_ms(100);
}
}
SIGNAL(SIG_UART_RECV)
{l=UDR;//讀取接受的數(shù)據(jù),清接受完成標(biāo)志位RXC
wdt_reset();
while(!(UCSRA&(1<<UDRE)));UDR=l;
if(l==0x01){
twi_start();
twi_write(slave|read);
rv=twi_read(0);
twi_stop();
while(!(UCSRA&(1<<UDRE)));UDR=rv;
while(1)
{wdt_reset();
PORTA=rv;
_delay_ms(1000);
SREG=SREG|0x80;
}
}
else{
twi_start();
twi_write(slave&write);
twi_write(l);
twi_stop();
while(1)
{wdt_reset();
PORTA=l;
_delay_ms(1000);
SREG=SREG|0x80;
}
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -