久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計實例 >> 瀏覽文章

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

作者:佚名   來源:本站原創(chuàng)   點擊數(shù):  更新時間:2011年01月29日   【字體:



 

/**************************************
硬件:單片機(jī)mega162,EEPROM 25256,晶振3.6864MHZ
編譯環(huán)境:ICC
****************************************/

#include<iom162v.h>

#define BAUD 9600   //波特率4800
#define CRYSTAL 3686400  //晶振3M
#define BAUD_set (unsigned int)( (unsigned long)CRYSTAL/(16*(unsigned long)BAUD)-1 ) //波特率計算
#define BAUD_H (unsigned char)(BAUD_set>>8) //波特率寄存器
#define BAUD_L (unsigned char)(BAUD_set)

/*
//GPRS
#define GPRS_ONOFFH  PORTA|=(1<<PA5)
#define GPRS_ONOFFL  PORTA&=~(1<<PA5)
#define GPRS_RSTH    PORTB|=(1<<PB1)
#define GPRS_RSTL    PORTB&=~(1<<PB1)


//通訊燈
#define LED1H  PORTC|=(1<<PC4)
#define LED1L  PORTC&=~(1<<PC4)
#define LED2H  PORTC|=(1<<PC6)
#define LED2L  PORTC&=~(1<<PC6)
#define LED3H  PORTC|=(1<<PC7)
#define LED3L  PORTC&=~(1<<PC7)
*/

//25256
#define EEPROM_CSH  PORTD|=(1<<PD5)   //
#define EEPROM_CSL  PORTD&=~(1<<PD5) 
#define EEPROM_WPH  PORTD|=(1<<PD2)
#define EEPROM_WPL  PORTD&=~(1<<PD2) 

#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個數(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個數(shù)據(jù)位*/
}


//串口0查詢方式發(fā)送數(shù)據(jù)
void USART0_Transmit(unsigned char data)
{
  while(!(UCSR0A&(1<<UDRE0))); 
   /*等待發(fā)送緩沖器為空。UDRE數(shù)據(jù)寄存器空標(biāo)志位,
   當(dāng)發(fā)送緩沖器空時被置1;發(fā)送緩沖器包含需要發(fā)送的數(shù)據(jù)時清零*/
  UDR0=data;  //將數(shù)據(jù)放入緩沖器,發(fā)送數(shù)據(jù)
}


//串口1查詢方式發(fā)送數(shù)據(jù)
void USART1_Transmit(unsigned char data)
{
  while(!(UCSR1A&(1<<UDRE1))); 
   /*等待發(fā)送緩沖器為空。UDRE數(shù)據(jù)寄存器空標(biāo)志位,
   當(dāng)發(fā)送緩沖器空時被置1;發(fā)送緩沖器包含需要發(fā)送的數(shù)據(jù)時清零*/
  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&(1<<RXC0)));  //等待接收數(shù)據(jù)
 return UDR0;    //從緩沖器中獲取并返回數(shù)據(jù)
}
*/

////////////////////////USRT1,USRT2 end///////////////////////


///////////////////////////////////////////GPRS begin////////////////////////////////////
//延時ms
/*
void delayms(unsigned int ms)
{
  unsigned int i,j;
  for(i=0;i<ms;i++)
    for(j=0;j<3500;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 =(1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0);
/*
使能SPI,選擇主機(jī)模式,SCK=fosc/128,選擇SPI模式CPOL=0,CPHA=0
*/
}

unsigned char SPI_MasterTransmit(unsigned char cData)
{
//啟動數(shù)據(jù)傳輸
  SPDR = cData;
//等待數(shù)據(jù)傳輸結(jié)束
  while(!(SPSR&(1<<SPIF)));
//發(fā)送完成后,清除發(fā)送標(biāo)志
//  SPSR&=~(1<<SPIF);
  return SPDR;
//每次發(fā)送數(shù)據(jù)的同時,也會接收到數(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ù)時,主機(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(),則讀出0x80
  EEPROM_CSL; //使能
  SPI_MasterTransmit(0x05); //0x05為讀狀態(tài)寄存器指令
  StatusReg=SPI_MasterTransmit(0x00); //給25256發(fā)送任意數(shù)據(jù)
/*
此處原為:
SPDR = 0x00;
while(!(SPSR&(1<<SPIF)));
StatusReg=SPDR;
時出錯,讀出數(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頁寫。試驗結(jié)果,只能連續(xù)寫入三個字節(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;i<NData;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輸出1
  PORTB=0xbf;
  DDRB=0xb7;    //PB1輸出1,PB2輸出1,PB3輸入0,PB4輸出1,PB0輸出1(用于新終端開關(guān)電源控制),PB5PB7為輸出1
  PORTC=0xff;
  DDRC=0xd0;    //PC4輸出1,PC6,PC7輸出1
  PORTD=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ù)0x48
   USART0_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,0x39
   USART0_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:20
void 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ù)時,此位為1,當(dāng)接收緩沖器空時為0(即不包含未讀出的數(shù)據(jù))。如果接收器被禁止(RXEN=0),
接收緩沖器會被刷新,從而使RXC清零。
   置位UCSRB的接收結(jié)束中斷使能位(RXCIE)后,只要RXC標(biāo)志置位(且全局中斷使能)就會產(chǎn)生USART
接收結(jié)束中斷。使用中斷方式進(jìn)行數(shù)據(jù)接收時,數(shù)據(jù)接收結(jié)束中斷服務(wù)程序必須從UDR讀取數(shù)據(jù)
以清除RXC標(biāo)志,否則只要中斷處理程序結(jié)束,一個新的中斷就會產(chǎn)生。

終上所述,RXC標(biāo)志未清零,導(dǎo)致中斷一直產(chǎn)生。
*/
#pragma interrupt_handler USART1Rx:21
void USART1Rx()
{
  unsigned char data1;
  data1=UDR1;
//  USART1_Transmit(data1);
}


關(guān)閉窗口

相關(guān)文章

主站蜘蛛池模板: 久久久噜噜噜www成人网 | 999久久久精品 | 在线观看免费av片 | 免费久久99精品国产婷婷六月 | 久草新在线| 狠狠操操| 日韩欧美亚洲综合 | 免费观看羞羞视频网站 | 日本福利一区 | 伊人在线| 中文字幕一区二区三区四区五区 | 日韩在线中文字幕 | 久热国产精品视频 | 久久国产精品99久久久大便 | 亚洲视频一区二区三区四区 | 九九久久国产 | 欧美中文一区 | 久久久www成人免费精品 | 国产精品福利视频 | 国产一区二区在线播放 | 欧美a区| 日韩激情在线 | 欧美精品在线免费 | 国产精品久久久久久妇女6080 | 久久精品中文字幕 | 日韩中文一区二区三区 | 欧美精品一二区 | 欧美激情精品久久久久 | 久久亚洲一区 | 国产美女视频黄a视频免费 国产精品福利视频 | 拍真实国产伦偷精品 | 国产精品99免费视频 | 日韩免费毛片 | 久久综合狠狠综合久久 | 免费久 | 精品久久久久国产 | 亚洲激情在线观看 | 狠狠狠色丁香婷婷综合久久五月 | 亚洲一区二区三区在线播放 | 欧美一级三级 | 亚洲福利 |