/**************************************硬件:單片機(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 SPIF 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 SPI_MasterInit(void){EEPROM_WPH;delayms(20);SPCR =(1SPE)|(1MSTR)|(1SPR1)|(1SPR0);/*使能SPI,選擇主機(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);}
評論