新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > AVR單片機(jī)SPI的應(yīng)用(AT25256)

AVR單片機(jī)SPI的應(yīng)用(AT25256)

作者: 時(shí)間:2012-08-29 來源:網(wǎng)絡(luò) 收藏

點(diǎn)擊瀏覽下一頁

/**************************************硬件:單片機(jī)mega162,EEPROM 25256,晶振3.6864MHZ編譯環(huán)境:ICC****************************************/#includeiom162v.h>#define BAUD 9600   //波特率4800#define CRYSTAL 3686400  //晶振3M#define BAUD_set (unsigned int)( (unsigned long)CRYSTAL/
(16*(unsigned long)BAUD)-1 ) //波特率計(jì)算#define BAUD_H (unsigned char)(BAUD_set>>8) //波特率寄存器#define BAUD_L (unsigned char)(BAUD_set)/*//GPRS#define GPRS_ONOFFH  PORTA|=(1PA5)#define GPRS_ONOFFL  PORTA=~(1PA5)#define GPRS_RSTH    PORTB|=(1PB1)#define GPRS_RSTL    PORTB=~(1PB1)//通訊燈#define LED1H  PORTC|=(1PC4)#define LED1L  PORTC=~(1PC4)#define LED2H  PORTC|=(1PC6)#define LED2L  PORTC=~(1PC6)#define LED3H  PORTC|=(1PC7)#define LED3L  PORTC=~(1PC7)*///25256#define EEPROM_CSH  PORTD|=(1PD5)   //#define EEPROM_CSL  PORTD=~(1PD5) #define EEPROM_WPH  PORTD|=(1PD2)#define EEPROM_WPL  PORTD=~(1PD2) #define F 7 /////////////////USRT0,USTR1  begin////////////////////////////////////////////串口begin/////////////////////////////////////////////串口0初始化void USART0_Init(){UCSR0B  =  (1  RXCIE0) |   /*接收完成中斷允許*/ // (1  TXCIE0) |   /*發(fā)送完成中斷允許*/(1  RXEN0)  |   /*接收允許*/(1  TXEN0);   /*發(fā)送允許*/UBRR0H = BAUD_H;   //設(shè)置波特率UBRR0L = BAUD_L;UCSR0C = (1  URSEL0) |  /*選擇訪問UCSRC寄存器*/(3  UCSZ00);  /*UCSZ2 UCSZ1 UCSZ0=3  8個(gè)數(shù)據(jù)位*/}//串口1初始化void USART1_Init(){UCSR1B  =  (1  RXCIE1) |   /*接收完成中斷允許*/ // (1  TXCIE1) |   /*發(fā)送完成中斷允許*/(1  RXEN0)  |   /*接收允許*/(1  TXEN0);   /*發(fā)送允許*/UBRR1H = BAUD_H;    //設(shè)置波特率UBRR1L = BAUD_L;UCSR1C = (1  URSEL1) |  /*選擇訪問UCSRC寄存器*/(3  UCSZ10);  /*UCSZ2 UCSZ1 UCSZ0=3  8個(gè)數(shù)據(jù)位*/}//串口0查詢方式發(fā)送數(shù)據(jù)void USART0_Transmit(unsigned char data){while(!(UCSR0A(1UDRE0))); /*等待發(fā)送緩沖器為空。UDRE數(shù)據(jù)寄存器空標(biāo)志位,當(dāng)發(fā)送緩沖器空時(shí)被置1;發(fā)送緩沖器包含需要發(fā)送的數(shù)據(jù)時(shí)清零*/UDR0=data;  //將數(shù)據(jù)放入緩沖器,發(fā)送數(shù)據(jù)}//串口1查詢方式發(fā)送數(shù)據(jù)void USART1_Transmit(unsigned char data){while(!(UCSR1A(1UDRE1))); /*等待發(fā)送緩沖器為空。UDRE數(shù)據(jù)寄存器空標(biāo)志位,當(dāng)發(fā)送緩沖器空時(shí)被置1;發(fā)送緩沖器包含需要發(fā)送的數(shù)據(jù)時(shí)清零*/UDR1=data;  //將數(shù)據(jù)放入緩沖器,發(fā)送數(shù)據(jù)}/*//發(fā)送GPRS命令給手機(jī)模塊void USART1_Tx_Str(char *s,unsigned char cnt){while(cnt--){USART1_Transmit(*s);s++;}}*///////////////////////////串口end//////////////////////////////////////*unsigned char usart0_receive(void){while(!(UCSR0A(1RXC0)));  //等待接收數(shù)據(jù)return UDR0;    //從緩沖器中獲取并返回?cái)?shù)據(jù)}*/////////////USRT1,USRT2 end//////////////////////////////////////////GPRS begin//////////////////////////////////////延時(shí)ms/*void delayms(unsigned int ms){unsigned int i,j;for(i=0;ims;i++)for(j=0;j3500;j++) ;}//GPRS開機(jī)void GPRS_On(){GPRS_RSTH;  GPRS_ONOFFH; delayms(20);GPRS_RSTL;  delayms(10);GPRS_ONOFFL;LED1L;LED2L;LED3L;delayms(1800);GPRS_ONOFFH;LED1H;LED2H;LED3H;delayms(200);LED1L;LED2L;}//GPRS關(guān)機(jī)void GPRS_Off(){GPRS_ONOFFL;delayms(1800);GPRS_ONOFFH;delayms(5000);GPRS_RSTL;}//GPRS復(fù)位void GPRS_Rst(){GPRS_Off();GPRS_On();}*//////////////////GPRS end////////////////////////////////////////////////////////////eeprom  begin//////////////////////////////////////void _MasterInit(void){EEPROM_WPH;delayms(20);SPCR =(1SPE)|(1MSTR)|(1SPR1)|(1SPR0);/*使能,選擇主機(jī)模式,SCK=fosc/128,選擇SPI模式CPOL=0,CPHA=0*/}unsigned char SPI_MasterTransmit(unsigned char cData){//啟動(dòng)數(shù)據(jù)傳輸SPDR = cData;//等待數(shù)據(jù)傳輸結(jié)束while(!(SPSR(1SPIF)));//發(fā)送完成后,清除發(fā)送標(biāo)志//  SPSR=~(1SPIF);return SPDR;//每次發(fā)送數(shù)據(jù)的同時(shí),也會接收到數(shù)據(jù)。}//EEPROM寫使能void EEPROM_WREN(){EEPROM_CSL; //拉低片選端SPI_MasterTransmit(0x06); //0x06為寫使能的指令EEPROM_CSH; //抬高片選端,結(jié)束}//EEPROM寫禁止void EEPROM_WRDI(){EEPROM_CSL;//delayms(20);SPI_MasterTransmit(0x04); //0x04為寫禁止的指令EEPROM_CSH;//delayms(20);}//寫狀態(tài)寄存器void EEPROM_WRSR(){EEPROM_WREN();EEPROM_CSL; //使能SPI_MasterTransmit(0x01);  //0x01為寫狀態(tài)寄存器的指令SPI_MasterTransmit(0x82);  //把0x82寫入狀態(tài)寄存器EEPROM_CSH; //抬高片選,結(jié)束}/*讀狀態(tài)寄存器。讀SPI從機(jī)數(shù)據(jù)時(shí),主機(jī)要給從機(jī)發(fā)送任意數(shù)據(jù),才能收到從機(jī)返回的數(shù)據(jù).即0x00可以是任何數(shù)據(jù)(但是不能是25256的指令,例如0x01,0x04之類的)*/unsigned char EEPROM_RDSR(){unsigned char StatusReg;EEPROM_WREN();//  EEPROM_WRDI();  //如使用此句,不使用EEPROM_WREN(),則讀出0x80EEPROM_CSL; //使能SPI_MasterTransmit(0x05); //0x05為讀狀態(tài)寄存器指令StatusReg=SPI_MasterTransmit(0x00); //給25256發(fā)送任意數(shù)據(jù)/*此處原為:SPDR = 0x00;while(!(SPSR(1SPIF)));StatusReg=SPDR;時(shí)出錯(cuò),讀出數(shù)據(jù)都為0xff。想不清楚為什么*/EEPROM_CSH;return StatusReg;}//25256字節(jié)寫void EEPROM_ByteWrite(unsigned int Address,unsigned char Data){EEPROM_WREN();EEPROM_CSL; //使能SPI_MasterTransmit(0x02); //0x02為寫指令SPI_MasterTransmit(Address/256); //地址高位SPI_MasterTransmit(Address%256); //地址低位SPI_MasterTransmit(Data); //寫入數(shù)據(jù)  EEPROM_CSH;delayms(50);}//25256頁寫。試驗(yàn)結(jié)果,只能連續(xù)寫入三個(gè)字節(jié)void EEPROM_PageWrite(unsigned int Address,
unsigned char *Data,unsigned char NData){unsigned char i;EEPROM_WREN();EEPROM_CSL;SPI_MasterTransmit(0x02);//頁寫指令SPI_MasterTransmit(Address/256); //地址高位SPI_MasterTransmit(Address%256); //地址低位for(i=0;iNData;i++){SPI_MasterTransmit(*Data); //寫入數(shù)據(jù) Data++;} EEPROM_CSH;}//25256讀unsigned char EEPROM_Read(unsigned int Address){unsigned char dataa;EEPROM_CSL; //使能SPI_MasterTransmit(0x03); //0x03為讀25256的指令SPI_MasterTransmit(Address/256); //地址高位SPI_MasterTransmit(Address%256); //地址低位dataa=SPI_MasterTransmit(0x00);//發(fā)送任意數(shù)據(jù)EEPROM_CSH;return dataa;  //返回讀到的數(shù)據(jù)}///////////////////eeprom  end//////////////////////////////////////////端口初始化void Port_Init(){PORTA=0xff;DDRA=0x30;    //PA4,PA5輸出1PORTB=0xbf;DDRB=0xb7;    
//PB1輸出1,PB2輸出1,PB3輸入0,PB4輸出1,PB0輸出1(用于新終端開關(guān)電源控制),
PB5PB7為輸出1PORTC=0xff;DDRC=0xd0;    //PC4輸出1,PC6,PC7輸出1PORTD=0xff;DDRD=0x26;    //PD0輸入0,PD1輸出1,PD5PD2輸出1}void main(void){// unsigned char dataa,i,j;SREG=0x80;  //開放全局中斷Port_Init();USART0_Init();USART1_Init();//  GPRS_On();SPI_MasterInit();EEPROM_WRSR();while(1){USART0_Transmit(0x22);USART0_Transmit(0x33);EEPROM_ByteWrite(0x2030,0x48); //給25256地址0x2030寫入數(shù)據(jù)0x48USART0_Transmit(EEPROM_Read(0x2010)); USART0_Transmit(EEPROM_Read(0x2030));
//讀出地址0x2030中數(shù)據(jù),從串口0發(fā)送出來USART0_Transmit(0x44);USART0_Transmit(0x55);USART0_Transmit(EEPROM_RDSR());EEPROM_PageWrite(0x1001,"456789",6); 
//輸出結(jié)果0xff,0xff,0xff,0x37,0x38,0x39USART0_Transmit(EEPROM_Read(0x1001));USART0_Transmit(EEPROM_Read(0x1002));USART0_Transmit(EEPROM_Read(0x1003));USART0_Transmit(EEPROM_Read(0x1004));USART0_Transmit(EEPROM_Read(0x1005));USART0_Transmit(EEPROM_Read(0x1006));USART0_Transmit(0x11);}}/* //IAR中中斷的寫法#pragma vector=USART0_RXD_vect__interrupt void Usart0Rx(void){unsigned char dataa;dataa=UDR0;usart0_transmit(dataa);}*///串行0通信接收完成中斷//ICC中中斷的寫法#pragma interrupt_handler USART0Rx:20void USART0Rx(){unsigned char data0;data0=UDR0;USART0_Transmit(data0);}/*串行1通信接收完成中斷分析燈不亮原因,開了串口1中斷,但是沒有加入中斷函數(shù),導(dǎo)致其他地方不能工作。串口中斷0能執(zhí)行,是由于其優(yōu)先級比串口中斷1高以下是書上的說法:接收結(jié)束標(biāo)志位(RXC)用來說明接收緩沖器中是否有未讀出的數(shù)據(jù)。
當(dāng)接收緩沖器中有未讀出的數(shù)據(jù)時(shí),此位為1,當(dāng)接收緩沖器空時(shí)為0(即不包含未讀出的數(shù)據(jù))。
如果接收器被禁止(RXEN=0),接收緩沖器會被刷新,從而使RXC清零。置位UCSRB的接收結(jié)束中斷使能位(RXCIE)后,
只要RXC標(biāo)志置位(且全局中斷使能)就會產(chǎn)生USART接收結(jié)束中斷。使用中斷方式進(jìn)行數(shù)據(jù)接收時(shí),數(shù)據(jù)接收結(jié)束中斷服務(wù)程序必須從UDR讀取數(shù)據(jù)以清除RXC標(biāo)志,否則只要中斷處理程序結(jié)束,一個(gè)新的中斷就會產(chǎn)生。終上所述,RXC標(biāo)志未清零,導(dǎo)致中斷一直產(chǎn)生。*/#pragma interrupt_handler USART1Rx:21void USART1Rx(){unsigned char data1;data1=UDR1;//  USART1_Transmit(data1);}


關(guān)鍵詞: AVR單片機(jī) SPI AT25256

評論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉