新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > AVR单片机SPI的应用(AT25256)

AVR单片机SPI的应用(AT25256)

作者:时间:2012-08-29来源:网络收藏

点击浏览下一页

/**************************************硬件:单片机mega162,EEPROM 25256,晶振3.6864MHZ编译环境:ICC****************************************/#includeiom162v.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|=(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) |   /*发送完成中断允许*/(1  RXEN0)  |   /*接收允许*/(1  TXEN0);   /*发送允许*/UBRR0H = BAUD_H;   //设置波特率UBRR0L = BAUD_L;UCSR0C = (1  URSEL0) |  /*选择访问UCSRC寄存器*/(3  UCSZ00);  /*UCSZ2 UCSZ1 UCSZ0=3  8个数据位*/}//串口1初始化void USART1_Init(){UCSR1B  =  (1  RXCIE1) |   /*接收完成中断允许*/ // (1  TXCIE1) |   /*发送完成中断允许*/(1  RXEN0)  |   /*接收允许*/(1  TXEN0);   /*发送允许*/UBRR1H = BAUD_H;    //设置波特率UBRR1L = BAUD_L;UCSR1C = (1  URSEL1) |  /*选择访问UCSRC寄存器*/(3  UCSZ10);  /*UCSZ2 UCSZ1 UCSZ0=3  8个数据位*/}//串口0查询方式发送数据void USART0_Transmit(unsigned char data){while(!(UCSR0A(1UDRE0))); /*等待发送缓冲器为空。UDRE数据寄存器空标志位,当发送缓冲器空时被置1;发送缓冲器包含需要发送的数据时清零*/UDR0=data;  //将数据放入缓冲器,发送数据}//串口1查询方式发送数据void USART1_Transmit(unsigned char data){while(!(UCSR1A(1UDRE1))); /*等待发送缓冲器为空。UDRE数据寄存器空标志位,当发送缓冲器空时被置1;发送缓冲器包含需要发送的数据时清零*/UDR1=data;  //将数据放入缓冲器,发送数据}/*//发送GPRS命令给手机模块void USART1_Tx_Str(char *s,unsigned char cnt){while(cnt--){USART1_Transmit(*s);s++;}}*///////////////////////////串口end//////////////////////////////////////*unsigned char usart0_receive(void){while(!(UCSR0A(1RXC0)));  //等待接收数据return UDR0;    //从缓冲器中获取并返回数据}*/////////////USRT1,USRT2 end//////////////////////////////////////////GPRS begin//////////////////////////////////////延时ms/*void delayms(unsigned int ms){unsigned int i,j;for(i=0;ims;i++)for(j=0;j3500;j++) ;}//GPRS开机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关机void GPRS_Off(){GPRS_ONOFFL;delayms(1800);GPRS_ONOFFH;delayms(5000);GPRS_RSTL;}//GPRS复位void GPRS_Rst(){GPRS_Off();GPRS_On();}*//////////////////GPRS end////////////////////////////////////////////////////////////eeprom  begin//////////////////////////////////////void _MasterInit(void){EEPROM_WPH;delayms(20);SPCR =(1SPE)|(1MSTR)|(1SPR1)|(1SPR0);/*使能,选择主机模式,SCK=fosc/128,选择SPI模式CPOL=0,CPHA=0*/}unsigned char SPI_MasterTransmit(unsigned char cData){//启动数据传输SPDR = cData;//等待数据传输结束while(!(SPSR(1SPIF)));//发送完成后,清除发送标志//  SPSR=~(1SPIF);return SPDR;//每次发送数据的同时,也会接收到数据。}//EEPROM写使能void EEPROM_WREN(){EEPROM_CSL; //拉低片选端SPI_MasterTransmit(0x06); //0x06为写使能的指令EEPROM_CSH; //抬高片选端,结束}//EEPROM写禁止void EEPROM_WRDI(){EEPROM_CSL;//delayms(20);SPI_MasterTransmit(0x04); //0x04为写禁止的指令EEPROM_CSH;//delayms(20);}//写状态寄存器void EEPROM_WRSR(){EEPROM_WREN();EEPROM_CSL; //使能SPI_MasterTransmit(0x01);  //0x01为写状态寄存器的指令SPI_MasterTransmit(0x82);  //把0x82写入状态寄存器EEPROM_CSH; //抬高片选,结束}/*读状态寄存器。读SPI从机数据时,主机要给从机发送任意数据,才能收到从机返回的数据.即0x00可以是任何数据(但是不能是25256的指令,例如0x01,0x04之类的)*/unsigned char EEPROM_RDSR(){unsigned char StatusReg;EEPROM_WREN();//  EEPROM_WRDI();  //如使用此句,不使用EEPROM_WREN(),则读出0x80EEPROM_CSL; //使能SPI_MasterTransmit(0x05); //0x05为读状态寄存器指令StatusReg=SPI_MasterTransmit(0x00); //给25256发送任意数据/*此处原为:SPDR = 0x00;while(!(SPSR(1SPIF)));StatusReg=SPDR;时出错,读出数据都为0xff。想不清楚为什么*/EEPROM_CSH;return StatusReg;}//25256字节写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); //写入数据  EEPROM_CSH;delayms(50);}//25256页写。试验结果,只能连续写入三个字节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); //写入数据 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);//发送任意数据EEPROM_CSH;return dataa;  //返回读到的数据}///////////////////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(用于新终端开关电源控制),
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写入数据0x48USART0_Transmit(EEPROM_Read(0x2010)); USART0_Transmit(EEPROM_Read(0x2030));
//读出地址0x2030中数据,从串口0发送出来USART0_Transmit(0x44);USART0_Transmit(0x55);USART0_Transmit(EEPROM_RDSR());EEPROM_PageWrite(0x1001,"456789",6); 
//输出结果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中断,但是没有加入中断函数,导致其他地方不能工作。串口中断0能执行,是由于其优先级比串口中断1高以下是书上的说法:接收结束标志位(RXC)用来说明接收缓冲器中是否有未读出的数据。
当接收缓冲器中有未读出的数据时,此位为1,当接收缓冲器空时为0(即不包含未读出的数据)。
如果接收器被禁止(RXEN=0),接收缓冲器会被刷新,从而使RXC清零。置位UCSRB的接收结束中断使能位(RXCIE)后,
只要RXC标志置位(且全局中断使能)就会产生USART接收结束中断。使用中断方式进行数据接收时,数据接收结束中断服务程序必须从UDR读取数据以清除RXC标志,否则只要中断处理程序结束,一个新的中断就会产生。终上所述,RXC标志未清零,导致中断一直产生。*/#pragma interrupt_handler USART1Rx:21void USART1Rx(){unsigned char data1;data1=UDR1;//  USART1_Transmit(data1);}


关键词: AVR单片机 SPI AT25256

评论


相关推荐

技术专区

关闭