⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 用STC89系列单片机的通用IO模拟SPI通信源码
💻 C
字号:
// Compiler : Keil uVision2
// Target : STC89LE516AD
// Crystal: 12Mhz
#include  <Reg52.h>
#include  <absacc.h>
#include  <stdio.h>
#include  <intrins.h>
#include  <stdlib.h>
#include  "main.h"

//***********delay subroutine**************
void delay(uchar temp_data)
{
	while(temp_data--);
}
//*****************************************

void main()
{
	uchar i = 255;
	LED1 = 0;
	//LED2 = 1;
	//initialzie for write AT25128
	SPI_once_end_flag = 1;
	//***********write the eeprom******************************
	eep_program_enable();					//enable AT25128
	while(!SPI_wrt_end_flag)
	{
    	put_spi_char();
		delay(255);
		delay(255);
		delay(255);
		delay(255);
    	SPI_write();
		if(!SPI_rx_flag)
			LED2 ^= 1;						//led2 flash display
    }
	while(i--)
    {
		delay(255);
		delay(255);
		delay(255);
		delay(255);
	}
	while(1)
	{
		//
		LED1 = 0;
		if(!verify_error_flag)
			LED2 = 0;					//NO ERROR
		else
			LED2 = 1;					//ERROR
		//
		//P2 = led_pp_data;
		//P0 = led_pp_data1;
 	}
}

//subroutine
//****************************************
//****************************************
//signal CS and SCK must be set attention
void   write_byte(uchar wrt_data)
{
	uchar i;
	for(i = 0;i < 8;i++ )
	{
		SCK = 0;
		if(wrt_data & 0x80)
			SI = 1;
		else 
			SI = 0;
		wrt_data = (wrt_data << 1);
		delay(10);
		SCK = 1;
		delay(10);
	}
	SCK = 0;
}
//*****************************************
//there is a question in here,
//up SCK or down SCK first?
//are all ok?
uchar 	read_byte()
{
	uchar i;
	uchar temp_data = 0x00;
	for(i = 0;i < 8; i++)
	{
		if(i >= 1)
			temp_data = temp_data << 1;
		SCK = 0;						//up SCK
		delay(10);
		if(SO)
		{
			temp_data |= 0x01;
		}
		SCK = 1;						//down SCK
		delay(10);
	}
	SCK = 0;
	return temp_data;
}
//*****************************************
void write_64byte()
{
	
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//transmit array data byte,
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void put_spi_char()
{
  	uchar 	i;
	uint	temp_pointer;	
	uchar 	temp_dataw;
    uchar	temp_dataf;
    if((!SPI_wrt_end_flag) && (SPI_once_end_flag))			//transmit not end ,one row datas in tx buffer are transmitted
    {
		SPI_once_end_flag = 0;								//clear the flag,for interrupt transmit
  		if(!SPI_start_flag)                      			//at the beginning of transmit
        {
      		SPI_start_flag = 1;                      		//set the flag
            P_SPI_tx = 0x0000;                         		//piont at the first data,
		}
    	else
        {
            //temp_dataw = (*P_SPI_tx) + 3;
			//temp_pointer = (uint)temp_dataw;
			//tmep_pointer = P_SPI_tx + temp_pointer;
			temp_dataw = (dspcode[P_SPI_tx] + 3);
			temp_pointer = (uint)temp_dataw;
        	P_SPI_tx += temp_pointer;							//set the piont
        }
        if(SPI_all_end_flag)
        {
       		SPI_wrt_end_flag = 1;								//set the data are all transmit flag
           	SPI_Rstatus_flag = 0;								//clear the read status flag ***
        }
       	else
        {
    		if(dspcode[P_SPI_tx] != 0x00)                  			//not at the end of transmition
    		{
      			for(i = 0; i < dspcode[P_SPI_tx]; i++)				//data number,first data
				{
        			SPI_tx_buffer[i] = dspcode[P_SPI_tx + i + 3]; 	//write the buffer
				}
      			SPI_tx_counter = 0x00;                  			//clear the number counter
                SPI_Rstatus_flag = 0x00;							//clear the read status flag
                SPI_tx_addl = dspcode[P_SPI_tx + 2];
            	SPI_tx_addh = dspcode[P_SPI_tx + 1];
  			}
   	 		else											//transmit end
            {
	            SPI_all_end_flag = 0x01;					//set all data transfer end flag
				SPI_tx_buffer[0] = 0x00;
                SPI_tx_buffer[1] = 0x00;					//write end flag data

   			 	temp_dataf = SPI_tx_addl;					//ajust the address
                SPI_tx_addl += SPI_tx_counter;
                if(SPI_tx_addl < temp_dataf)
                {
                  	SPI_tx_addh += 1;						//high address +1
                }
                P_SPI_tx -= (SPI_tx_counter + 3);			//ajust the value of (*P_SPI_tx)
			  
                SPI_tx_counter = 0x00;                  	//clear the number counter
                SPI_Rstatus_flag = 0x00;					//clear the read status flag
            }
		}
	}
}

//*********************************************************
//when the data number equal to 64, need adjust change the
//page
//*********************************************************
void	write_address_ajust()
{
	uchar temp_address;
	temp_address = SPI_tx_addl;
	SPI_tx_addl += SPI_tx_counter;						//adjust the write address
	if(SPI_tx_addl < temp_address)
	{
		SPI_tx_addh += 1;
	}
	//SPI_address_count = 0x00;							//clear the data num counter
}
//*****************************************
void SPI_write()                  												//
{
	uchar 	i;
	uchar 	temp_data;
	uint	temp_pointer;	
	uchar 	temp_dataw;
  	if(!SPI_rx_flag)														//write at25128 (not read)
	{
		if(!SPI_wrt_end_flag)													//not all data transmit
        {
  			if(!SPI_once_end_flag)												//start write(at begin of one row)
  			{
    			if((!SPI_Rstatus_flag) || ((SPI_status & 0x01) == 0x01)) 		//need to read status register or eep busy
    			{
   					CS = 1;
     				SPI_Rstatus_flag = 1;										//set flag for read the status register
     				CS = 0;											
     				write_byte(RDSR);											//read the status
      				SPI_status = read_byte();									//read status register						
      				CS = 1;														//pull up the SS,end the transmit										
    			}
    			if(((SPI_status & 0x01) == 0x00) && (SPI_Rstatus_flag))			//eeprom in ready state(not busy)
            	{	
                	row_data_num = dspcode[P_SPI_tx];
					if(SPI_all_end_flag)
						row_data_num = 2;
                    while(SPI_tx_counter < row_data_num)						//this array transmition not end
        			{
						temp_data = (SPI_tx_addl + SPI_tx_counter);
        				if((SPI_tx_counter == 0x00) || ((temp_data & 0x3f) == 0x00))
        				{
							if(SPI_tx_counter == 0x00)
							{
								;
							}
							else
        					{	
        						if(!b64_enable_flag)
        						{
        							b64_enable_flag = 1;						//wait until reading the status register
        							SPI_Rstatus_flag = 0;
									CS = 1;
									delay(255);
									delay(255);
									delay(255);
									delay(255);
									delay(255);
									delay(255);
									delay(255);
									delay(255);
        							return;										//ret
        						}
        						else	
        						{
        							b64_enable_flag = 0;
        							write_address_ajust();						//
									delay(255);
									delay(255);
									delay(255);
									delay(255);
        						}
        					}
        					CS = 1;												//pull up SS		
							delay(5);
                    		CS = 0;												//pull down the SS
        					write_byte(WREN);
							delay(5);
							CS = 1;
							delay(5);
							CS = 0;
							delay(5);
							write_byte(WRITE);
                   			write_byte(SPI_tx_addh);
               				write_byte(SPI_tx_addl);
        				}
              			write_byte(SPI_tx_buffer[SPI_tx_counter]);
              			SPI_tx_counter++;
    				}
    				CS = 1;								
					delay(255);													//delay time are not enough
					delay(255);
					delay(255);
					delay(255);
					delay(255);
					delay(255);
					delay(255);
					delay(255);
					delay(255);
					delay(255);
					if(row_data_num <= 0x15)
					{
						delay(255);
						delay(255);
						delay(255);
						delay(255);
						delay(255);
						delay(255);
					}
    				SPI_once_end_flag = 1;										//a row data transmit end
                }
        		else															//one row data transmit end
        			SPI_Rstatus_flag = 0;										//continue read status register
         	}
        }
    	else																	//send protected code
    	{
		    CS = 1;																//pull up SS		
			delay(5);
            CS = 0;																//pull down the SS
        	write_byte(WREN);
			delay(5);
			CS = 1;
      		delay(5);
      		CS = 0;
      		write_byte(WRSR);
			write_byte(ALL_PROTECTED);			
    		CS = 1;
    		delay(5);
    		CS = 0;
    		write_byte(WRDI);													//disable all programming modes
    		CS = 1;
            SPI_rx_flag = 1;
    	}
	}		
//*************verify the eeprom data***********************************
  	if(SPI_rx_flag)												//read and verify at25128
  	{
		while(!verify_on_flag)
		{	
			LED2 ^= 1;											//led2 flash display
			LED3 = 0;											//it is verify time

			if(!SPI_read_flag)                      			//at the beginning of transmit
        	{
      			SPI_read_flag = 1;                      		//set the flag
            	P_SPI_rx = 0x0000;                         		//piont at the first data,
			}
    		else
        	{
        	    //temp_dataw = (*P_SPI_rx) + 3;
				//temp_pointer = (uint)temp_dataw;
				//tmep_pointer = P_SPI_rx + temp_pointer;
				temp_dataw = (dspcode[P_SPI_rx] + 3);
				temp_pointer = (uint)temp_dataw;
        		P_SPI_rx += temp_pointer;						//set the piont
        	}
			if(dspcode[P_SPI_rx] == 0)							
			{

				CS = 1;											//reset write enable latch
    			delay(5);
    			CS = 0;
    			write_byte(WRDI);								//disable all programming modes
    			CS = 1;

				CS = 1;
				delay(5);
				CS = 0;
				delay(5);
				write_byte(RDSR);								//read the status register
				temp_dataw = read_byte();
				CS = 1;
				if(temp_dataw != 0x8C)
				{
					verify_error_flag = 1;						//status register set not right
				}
				verify_on_flag = 1;								//verify end
			}
			//
			else
			{
				SPI_rx_addl = dspcode[P_SPI_rx + 2];			//address low byte
        		SPI_rx_addh = dspcode[P_SPI_rx + 1];			//address high byte
				CS = 1;											//pull up SS		
				delay(5);
            	CS = 0;											//pull down the SS
        		write_byte(WREN);								//reset write enable latch
				delay(5);
				CS = 1;
				delay(5);
				CS = 0;
				delay(5);
				write_byte(READ);
            	write_byte(SPI_rx_addh);
            	write_byte(SPI_rx_addl);
				for(i = 0; i < dspcode[P_SPI_rx] ; i++)
				{
					SPI_rx_buffer[i] =	read_byte();			//read data from eeprom
				}
				CS = 1;
				for(i = 0; i < dspcode[P_SPI_rx]; i++)			//verify if the data right
				{
					if(SPI_rx_buffer[i] != dspcode[P_SPI_rx + 3 + i])	
					{
						verify_on_flag = 1;						//stop verify set alarm signal
						verify_error_flag = 1;					//verify not pass
						break;
					}
				}
			}
			//
		}
    }		
    //***********************************************************************
}

//*************************************************************************
//write the eeprom enable,
//*************************************************************************
void eep_program_enable()
{
	CS = 1;
	delay(5);
	CS = 0;
    write_byte(WREN);                     					//set write enable latch
    CS = 1;													//pull up the SS
   	delay(5);
	CS = 0;													//pull down the SS
    write_byte(WRSR);                  						//send the write Status register op_code
	write_byte(ALL_NOT_PRO);								//send not protected blocks op_code
	CS = 1;													//pull up the SS
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -