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