?? avr2464.c
字號:
//*******************************************************************
//********File name :24C64 eeprom's write and read
//********File create date :2008/5/27
//********Design dept :ATE
//********Systm explain :Atmage 88 ,8m/8
//*******************************************************************
#include "C.h"
//*******************************************************************
//上位機發送:"AA+55+讀取字節數高字節+讀取字節數低字節+CHKSUM"后,
//下位機開始讀24C64,相應的字節數發送給上位機.
//*******************************************************************
//通信波特率:4800,N,8,1 內部時種分頻
//*******************************************************************
int Eepaddress=0x0000; //要讀取的24C64內部存貯器單元地址
int Eep_long; //保存上位機發數來的,將要讀取的字節個數數據
char Eepdata[32];
int read_byte=32;
int usart_bit=0; //計錄串口接收數據個數
int step_bit_0=0;
char command_dataH;
char command_dataL;
char RXD_chksum;
//*******************************************************************
void main()
{
Mcu_init();
initial_usart();
Sei();
while(1)
{
if(step_bit_0==0x01) //上位機發送的命今接收成功
{
step_bit_0=0x00;
char chksum_sum=0xAA+0X55+command_dataH+command_dataL;
if(RXD_chksum==chksum_sum) //whether the chksum is right of data,if the data is right for It's downflow,then return
{
Eepaddress=0x0000;
Eep_long=command_dataH*256+command_dataL;
// 以下程序如果上位機發送的要讀取的字節數小于32字節,程序單字節讀取.每次所讀取的數據放在Eepdata[0]中;
//如果大于32字節按塊讀取,先讀32倍數的字節數,余數按單節讀取.
//如果大于24C64的存貯器最大范圍(8192字節).下位機不讀取數取,也不發送.
//********************************************
if(Eep_long<=32) //小于32時,一位一位讀取
{
for(int b=0;b<Eep_long;b++)
{
AT24C64_R(Eepaddress);
UDR0=Eepdata[0];
while(!CHKBIT(UCSR0A,TXC0));//wait for sending
SETBIT(UCSR0A,TXC0);
}
}
else //大于32是按塊讀取
{
if(!(Eep_long>8192)) //大于24C64讀取范圍時,不讀取數據,也不回復給上位機
{
for(int a=0;a<(Eep_long/32);a++)
{
AT24C64_RB(Eepaddress,read_byte);
for(int b=0;b<read_byte;b++)
{
UDR0=Eepdata[b];
while(!CHKBIT(UCSR0A,TXC0));//wait for sending
SETBIT(UCSR0A,TXC0);
}
}
for(int b=0;b<(Eep_long%32);b++)
{
AT24C64_R(Eepaddress);
UDR0=Eepdata[0];
while(!CHKBIT(UCSR0A,TXC0));//wait for sending
SETBIT(UCSR0A,TXC0);
}
}
}
}
}
Nop();
}
}
//********************************************************************
//串口通信說明:
//串口通信:4800,N,8,1
//接收中斷使能,允許發送和接收
//********************************************************************
void initial_usart(void)
{
UBRR0H=0;
UBRR0L=12; //BAUD 4800
UCSR0B=(1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0);//ENABLE
UCSR0C=(3<<UCSZ00);//no check bit, 8 bits, 1 stop
}
//*******************************************************************
//引腳定義
//*******************************************************************
void Mcu_init()
{
OUT_SDA;
OUT_SCL;
}
//********************************************************************
//接收數據中斷:
//********************************************************************
#pragma vector=USART_RX_vect
__interrupt
void USART_RX(void)
{
unsigned char command=UDR0;
if(usart_bit==0)
{
if(command==0XAA)
usart_bit=1;
else
usart_bit=0;
}
else if(usart_bit==1)
{
if(command==0x55)
usart_bit=2;
else
usart_bit=0;
}
else if(usart_bit==2)
{
command_dataH=command;
usart_bit=3;
}
else if(usart_bit==3)
{
command_dataL=command;
usart_bit=4; //只接收4個字節,如還有數據則從數據頭開始檢測
}
else if(usart_bit==4)
{
RXD_chksum=command;
step_bit_0=0x01; //接收成功
usart_bit=0; //只接收5個字節,如還有數據則從數據頭開始檢測
}
}
//*******************************************************************
//單字節寫程序
//PartAdd_W 為器件地址+寫命今
//AT24C64_address為要操作的I2C芯片的內部存貯單元,為雙字節(24C64)
//Data 為要寫入的數據
//*******************************************************************
void AT24C64_W(int AT24C64_address,int Data)
{
I2C_Start();
I2C_Send_Byte(0xa0 );
I2C_Send_Byte(AT24C64_address/256 );
I2C_Send_Byte(AT24C64_address %256 );
I2C_Send_Byte(Data);
I2C_Stop();
Delay_N_mS(10);
}
//******************************************************************
//單字節讀程序:
//AT24C64_address為要操作的I2C芯片的內部存貯單元,為雙字節(24C64)
//******************************************************************
void AT24C64_R(int AT24C64_address)
{
I2C_Start();
I2C_Send_Byte(0xa0);
I2C_Send_Byte(AT24C64_address/256 );
I2C_Send_Byte(AT24C64_address % 256 );
I2C_Start();
I2C_Send_Byte(0xa1);
Eepdata[0]=I2C_Receive_Byte();
I2C_Nack();
I2C_Stop();
Eepaddress++; //讀取一個字節時不需此步.調用完此子程序后.你所要讀取單元字節的數據已放入Eepdata[0].直接用
}
//********************************************************************
//32字節(塊)讀程序
//********************************************************************
void AT24C64_RB(int AT24C64_address,int eep_byte)
{
I2C_Start();
I2C_Send_Byte(0xa0);
I2C_Send_Byte(AT24C64_address/256 );
I2C_Send_Byte(AT24C64_address%256 );
I2C_Start();
I2C_Send_Byte(0xa1);
for(int a=0;a<eep_byte;a++)
{
Eepdata[a]= I2C_Receive_Byte();
I2C_Ack();
Eepaddress++; //地址加1
}
I2C_Stop();
}
//********************************************************************
//接收數據:
//用來接收數據
//********************************************************************
char I2C_Receive_Byte(void)
{
char Data_C=0;
char Bitcont;
IN_SDA; //切換數據線為輸入狀態
for(Bitcont=0;Bitcont<8;Bitcont++)
{
Nop();
SCL_0;
Delay_10_uS();
SCL_1;
Delay_10_uS();
Data_C=Data_C<<1;
if(!(CHK_SDA==0))
Data_C=Data_C+1;
Nop();
Nop();
}
SCL_0;
Delay_10_uS();
OUT_SDA; //恢復數據線為輸出狀態
return Data_C;
}
//********************************************************************
//*起始說明: *
//*在時鐘為高時,數據線由高變低. *
//********************************************************************
void I2C_Start(void)
{
Delay_10_uS();
SDA_1;// I2C_SDA =1;
Delay_10_uS();
SCL_1;// I2C_SCK =1;
Delay_10_uS();
SDA_0;// I2C_SDA = 0;
Delay_10_uS();
SCL_0;// I2C_SCK = 0;
Delay_10_uS();
}
//********************************************************************
//*結束說明: *
//*在時鐘為高時,數據線由低變高 *
//********************************************************************
void I2C_Stop(void)
{
Delay_10_uS();
SDA_0;// I2C_SDA = 0;
Delay_10_uS();
SCL_1;// I2C_SCK = 1;
Delay_10_uS();
SDA_1;// I2C_SDA = 1;
Delay_10_uS();
}
//********************************************************************
//主機發送應答位
//********************************************************************
void I2C_Ack(void)
{
Delay_10_uS();
SDA_0;// I2C_SDA=0;
Delay_10_uS();
SCL_1;// I2C_SCK=1;
Delay_10_uS();
SCL_0;// I2C_SCK=0;
Delay_10_uS();
}
//********************************************************************
//主機發送非應答位
//********************************************************************
void I2C_Nack(void)
{
Delay_10_uS();
SDA_1;// I2C_SDA=1;
Delay_10_uS();
SCL_1;// I2C_SCK=1;
Delay_10_uS();
SCL_1;// I2C_SCK=0;
Delay_10_uS();
}
//********************************************************************
//*發送說明:
//*在發送數據時,時鐘線在高時,數據不能變化,只有在時鐘為低時,數據才可變*
//********************************************************************
void I2C_Send_Byte(char d)
{
char i = 8;
while( i-- )
{
Delay_10_uS();
if ( d &0x80 ) SDA_1;//I2C_SDA =1;
else SDA_0;//I2C_SDA =0;
Delay_10_uS();
SCL_1;// I2C_SCK = 1;
Delay_10_uS();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
SCL_0;// I2C_SCK = 0;
d = d << 1;
}
Delay_10_uS();
SDA_1;// I2C_SDA = 1;
Delay_10_uS();
SCL_1;// I2C_SCK = 1;
Delay_10_uS();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
SCL_0;// I2C_SCK =0;
//Delay_10_uS();
}
//********************************************************************
//延時
//********************************************************************
void Delay_10_uS(void)
{
Nop();
Nop();
}
//********************************************************************
//延時程序
//********************************************************************
void Delay_N_mS( int n_milisecond) /* n mS delay */
{
char i;
while(n_milisecond--)
{
i=8;
while(i--);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -