This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

F28035如何透過spi存取外部記憶體

我要对外部的EEPROM进行数据的读写,有无范例程式可供参考?

我的DSP是F28035、EEPROM是25LC320A、界面是SPI

DSP与EEPROM的联接关系是

DSP的脚位配置如下

  • 你好,目前TI没有基于SPI的外部扩展存储例程,只有基于I2C的EEPROM外扩例程。这方面可能需要自己开发了
  • waveform1是写入的波形,感觉上,F28035在数据写入SPITXBUF后不久(有点延迟时间),就下拉CS,将数据发出后,就上拉CS,如此反复。我用的EEPROM是Michochip的25AA320A,它的写入波形式(waveform2),其clock是连续打出,请问是否是我设定的问题,造成F28035的SPI周边的CS是如此表现,(我曾经试图自行下拉CS,但无效果,CS信号还是由SPI周边所控制)

    该如何修正?

    main program

    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    #include "SI_GUI_Main.h"
    
    void main(void) {
        Uint16  eeprom_data = 0x55;
        Uint16  eeprom_d1;
        Uint16  eeprom_addr = 0x03;
    	setupDevice();		//will call setup_EEPROM_SPI
    	read_EEPROM_Status();
    
    	while (1){
    	    addrwrite_EEPROM(eeprom_addr,eeprom_data);
    	    eeprom_d1 = addrread_EEPROM(eeprom_addr);
     }
    }
    
    void Test() {
        char Message[9] = "W  Grid ";           //�dz��ഫ���ֺ�e�q�Ҧ�
    
        IBDC_PowerGeneration = 25 | 0x8000;     //MSB�]��1����F�o�q�q 25*0.1kW = 2.5kW
        INV_PowerGeneration  = 30 | 0x8000;     //MSB�]��1����F�o�q�q 30*0.1kW = 3.0kW
        PV_PowerGeneration   = 50;              //�S�����t���F�o�q�q 50*0.1kW = 5.0kW
        PVINV_ErrCode        = 123;             //���~�X�|�H10�i����ܡG123
        PVINV_WarningCode    = 567;             //ĵ�ܽX�|�H10�i����ܡG567
        IBDC_ErrCode         = 135;             //���~�X�|�H10�i����ܡG135
        IBDC_WarningCode     = 246;             //ĵ�ܽX�|�H10�i����ܡG246
    
        Display_Msg(Message);
    }
    
    void ErrCode(void){
        if (PVINV_ErrCode || IBDC_ErrCode) {//�p�G������o�X���~�X
            if (PVINV_ErrCode >= PVINV_ERROR_NUMBER-1)  PVINV_ErrCode = PVINV_ERROR_NUMBER-1;
            if (IBDC_ErrCode >= IBDC_ERROR_NUMBER-1)    IBDC_ErrCode  = IBDC_ERROR_NUMBER-1;
            LcmF=1;
            ErrCounter++;
        }
        else
            while(ErrCounter>=1 & PVINV_ErrCode==0 & IBDC_ErrCode==0){
                if(ErrCounter!=0)
                    LCD_Display(PVINV_ErrorMsg[PVINV_ErrCode], IBDC_ErrorMsg[IBDC_ErrCode]);
                if (!bScanKeyTrigger) {KeyEvent = KeyEvent_Shadow; KeyEvent_Shadow = KEYEVENT_NO_EVENT;}
                if(KeyEvent==6){
                    LcmF=0;
                    ErrCounter=0;
                    init_SI_GUI();
                    return;
                }
                if (KeyEvent != KEYEVENT_NO_EVENT) {bScanKeyTrigger = 1; KeyEvent = KEYEVENT_NO_EVENT;}
            }
    }
    
    void System_Oper(void){
        if(LcmF==1){return;}
         //���s����ƥ�A�h��s����ƥ�
        if (!bScanKeyTrigger) {KeyEvent = KeyEvent_Shadow; KeyEvent_Shadow = KEYEVENT_NO_EVENT;}
        if (ModeSel_Action_F) {
            if (KeyEvent != KEYEVENT_NO_EVENT) {//����LMenu_ModeSel_Action()�S���F����F
                ModeSel_Action_F = 0; bScanKeyTrigger = 1; KeyEvent = KEYEVENT_NO_EVENT;
            } else return;
        }
        switch (nFuntionIndex) {//���ާ@�G���n�M������ƥ�A���U�|�B�z
        case _Menu_EntryPoint_Index:    Menu_EntryPoint();  break;
        case _Menu_ModeParaSel_Index:   Menu_ModeParaSel(); break;
        case _Menu_ModeSel_Index:       Menu_ModeSel();     break;
        case _Menu_ParaSet_Index:       Menu_ParaSet();     break;
        }
        //����ƥ�B�z�����A���s�Ұʫ��䱽�y�òM������ƥ�
        if (KeyEvent != KEYEVENT_NO_EVENT) {bScanKeyTrigger = 1; KeyEvent = KEYEVENT_NO_EVENT;}
    
    }
    
    void UpdataLCMs(void){
        if(LcmF==1)
            LCD_Display(PVINV_ErrorMsg[PVINV_ErrCode], IBDC_ErrorMsg[IBDC_ErrCode]);
        else if(LcmF==0){return;}
    
    }
    
    void Display_Msg(char *dispMsg) {
        char    LCD01[17], LCD02[17];
        Uint16  index, remain_Value;
    
        LCD01[16] = LCD02[16] = '\0';   //�]�w�r�굲���Ÿ�
    
        for (index=0; index < 8; index++) LCD01[index] = dispMsg[index];    //�ƻs�B��Ҧ�
        LCD01[8] = ((PV_PowerGeneration & 0x7FFF)/10)+'0';                  //�ഫPV�o�q�q
        LCD01[9] = ((PV_PowerGeneration & 0x7FFF)%10)+'0';
    
        if ((IBDC_PowerGeneration & 0x8000) > 0)    LCD01[10] = '+';        //�M�wIBDC�o�q�q�����t��
        else                                        LCD01[10] = '-';
        LCD01[11] = ((IBDC_PowerGeneration & 0x7FFF)/10)+'0';               //�ഫIBDC�o�q�q
        LCD01[12] = ((IBDC_PowerGeneration & 0x7FFF)%10)+'0';
    
        if ((INV_PowerGeneration & 0x8000) > 0)     LCD01[13] = '+';        //�M�wINV�o�q�q�����t��
        else                                        LCD01[13] = '-';
        LCD01[14] = ((INV_PowerGeneration & 0x7FFF)/10)+'0';                //�ഫINV�o�q�q
        LCD01[15] = ((INV_PowerGeneration & 0x7FFF)%10)+'0';
    
        remain_Value = PVINV_ErrCode;                                       //�ഫPVINV�����~�X
        LCD02[2]  = remain_Value%10 + '0'; remain_Value = remain_Value/10;
        LCD02[1]  = remain_Value%10 + '0'; remain_Value = remain_Value/10;
        LCD02[0]  = remain_Value%10 + '0'; remain_Value = remain_Value/10;
        //LCD02[0]  = remain_Value%10 + '0'; remain_Value = remain_Value/10;
        LCD02[3]  = ' ';
    
        remain_Value = PVINV_WarningCode;                                   //�ഫPVINV��ĵ�ܽX
        LCD02[6]  = remain_Value%10 + '0'; remain_Value = remain_Value/10;
        LCD02[5]  = remain_Value%10 + '0'; remain_Value = remain_Value/10;
        LCD02[4]  = remain_Value%10 + '0'; remain_Value = remain_Value/10;
        //LCD02[4]  = remain_Value%10 + '0'; remain_Value = remain_Value/10;
        LCD02[7]  = ' ';
    
        remain_Value = IBDC_ErrCode;                                        //�ഫIBDC�����~�X
        LCD02[10]  = remain_Value%10 + '0'; remain_Value = remain_Value/10;
        LCD02[9]  = remain_Value%10 + '0'; remain_Value = remain_Value/10;
        LCD02[8]   = remain_Value%10 + '0'; remain_Value = remain_Value/10;
        //LCD02[8]   = remain_Value%10 + '0'; remain_Value = remain_Value/10;
        LCD02[11]  = ' ';
    
        remain_Value = IBDC_WarningCode;                                    //�ഫIBDC��ĵ�ܽX
        LCD02[14]  = remain_Value%10 + '0'; remain_Value = remain_Value/10;
        LCD02[13]  = remain_Value%10 + '0'; remain_Value = remain_Value/10;
        LCD02[12]  = remain_Value%10 + '0'; remain_Value = remain_Value/10;
        //LCD02[12]  = remain_Value%10 + '0'; remain_Value = remain_Value/10;
        LCD02[15]  = ' ';
        LCD_Display(LCD01, LCD02);
    }
    
    
    void UpdateLEDs(void) {//��sLED
        int Led_Green_On = 1;
    
    	//�����~�X�A�I�G���~���ܿO
    	if (PVINV_ErrCode || IBDC_ErrCode)          {LED_RED_ON; Led_Green_On=0;}
    	else								        {LED_RED_OFF;}
    
    	if (PVINV_WarningCode || IBDC_WarningCode)  {LED_YELLOW_ON; Led_Green_On=0;}
    	else										{LED_YELLOW_OFF;}
    
    	if (Led_Green_On)                           LED_GREEN_ON;
    	else                                        LED_GREEN_OFF;
    }
    
    void init_SI_GUI(void) {//�H���������骺��l�]�w
        //��������ܼ�
        bScanKeyTrigger     = 1;							//�Ұʫ��䱽�y
    	KeyEvent_Shadow     = KEYEVENT_NO_EVENT;			//�M�ū���ƥ�v�l
    	KeyEvent		    = KEYEVENT_NO_EVENT;			//�M�ū���ƥ�
    
        nFuntionIndex 	    = _Menu_EntryPoint_Index;		//�_�l�ާ@���
    	menu_state 		    = 1;							//����l���A
    	OpMode 			    = OpMode_StandBy;				//�]�w�t�Ϊ��B��Ҧ����ݾ����A
    	OpModeF			    = 0;							//�M�ŹB��Ҧ��P��X��
    	ModeSel_Action_F    = 0;                            //�M�żҦ��]�w����X��
    	PVINV_ErrCode 	    = GUI_ErrCode_NO_ERROR;			//�M��PVINV�^�������~�X
    	IBDC_ErrCode 	    = GUI_ErrCode_NO_ERROR;			//�M��IBDC�^�������~�X
    	PVINV_WarningCode   = GUI_WarningCode_NO_Waring;	//�M��IBDC�^����ĵ�T�X
    	IBDC_WarningCode    = GUI_WarningCode_NO_Waring;	//�M��IBDC�^����ĵ�T�X
    	PVINV_Report        = GUI_Report_NoAvailable;       //�M��PVINV�^����T
    	IBDC_Report         = GUI_Report_NoAvailable;       //�M��IBDC�^����T
    	PV_PowerGeneration  = 0;                            //MPPT�o�q�q�]�w��0kW
    	INV_PowerGeneration = 0;                            //INV�o�q�q�]�w��0kW
    	IBDC_PowerGeneration= 0;                            //IBDC�o�q�q�]�w��0kW
    
    	//��ܰ_�l�e��
    	LCD_Display("TATUNG Smart INV", "-------> PowerOn");
    	do_ParaSet_Done();	//�o���ѼơA�䤤OpMode_Enable=0��n����B�@
    
    	//�B�zLED�����A
    	LED_RED_OFF; LED_YELLOW_OFF; LED_GREEN_ON;
    }
    
    //�Τ��_�Ӷi����䪺���y�u�@
    //�`�N�G���ઽ����KeyEvent�A�]������C�����_��sKeyEvent�A��L�t��
    //      �֪���Ʒ����i��|�A���ܰʥ��A�q�ӨϨ�Ө�ƩΨ�L���L�k�o��
    //      �s�����쪺KeyEvent�A�Ӱ��X�����T������
    //      �ҥH�~�|�]�pKeyEvent_Shadow
    __interrupt void cpu_timer0_isr(void) {
    	 CpuTimer0.InterruptCount++;	//�L�q�A�ȬO���D���_���@��
    
    	if (bScanKeyTrigger) {//�O�_�n�i�汽�y����H
    	   KeyEvent_Shadow = ScanKey();		//�i�汽�y����
    	   if (KeyEvent_Shadow != KEYEVENT_NO_EVENT)
    		   bScanKeyTrigger = 0; //������䱽�y�A�������ƥ�Q�B�z����
       }
    
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;	//�A���Ұʤ��_
    }
    
    void Menu_EntryPoint(void) {//���i�J�I
    	if (KeyEvent == KEYEVENT_POWER_ON){
    		nFuntionIndex	= _Menu_ModeParaSel_Index;	//�������
    		menu_state 		= 1;						//��l�ƿ�檬�A
    	}
    }
    
    //LWG�G�������ѼҦ��M�Ѽƪ��]�w�\��
    //menu_state = 1(��ܰ���Ҧ��ΰѼƳ]�w�Ҧ��^�B2�]��ܨֺ�Ҧ��^�B3�]��ܥR�q�Ҧ��^�B4�]��ܫݾ��Ҧ��^�B5�]��ܰѼƳ]�w�Ҧ��^
    void Menu_ModeParaSel(void) {//�Ҧ��P�Ѽƿ�ܿ��
    	const Uint32 Max_menu_state = 5;	//����榳��ӿﶵ
    
    /* �e�\��
    	switch (KeyEvent) {//�ھ�Key Event�ӽվ�menu_state
    	case KEYEVENT_CANCEL:
    	case KEYEVENT_POWER_OFF:	init_SI_GUI();												return;
    	case KEYEVENT_UP:			menu_state--;												break;
    	case KEYEVENT_DOWN:			menu_state++; 												break;
    	case KEYEVENT_OK:			nFuntionIndex = (1 == menu_state)? _Menu_ModeSel_Index:_Menu_ParaSet_Index;	//�������
    								menu_state = 1; 											return;
    	default:																				break;
    	}
    */
    	//�������餤��menu_state�N����ܪ��Ҧ�
    	switch (KeyEvent) {//�ھ�Key Event�ӽվ�menu_state
    	case KEYEVENT_CANCEL:       menu_state = 1;     break;
    	case KEYEVENT_POWER_OFF:    init_SI_GUI();      return;
    	case KEYEVENT_GRID:         menu_state = 2;     break;
    	case KEYEVENT_CHARGER:      menu_state = 3;     break;
    	case KEYEVENT_STANDBY:      menu_state = 4;     break;
    	case KEYEVENT_PARAMETER:    menu_state = 5;     break;
    	case KEYEVENT_OK:           nFuntionIndex = (5 == menu_state)? _Menu_ParaSet_Index:_Menu_ModeSel_Index; //�������
    	                            if (5 == menu_state) menu_state = 1;    return;
    	default:                                        break;
    	}
    	//�B�zmenu_state�MKEYEVENT_CLEAR;
    	if (0 == menu_state) 			 menu_state = Max_menu_state;
    	if (Max_menu_state < menu_state) menu_state=1;
    
    	switch (menu_state) {//��ܰT��
    	case 1: LCD_Display("Sel  Oper/PARA","Press KEY ---> "); break;
    	case 2:	LCD_Display("Do GRID  Mode?","Press OK or ESC"); break;
    	case 3: LCD_Display("Do CHAR  Mode?","Press OK or ESC"); break;
    	case 4: LCD_Display("Do STBY  Mode?","Press OK or ESC"); break;
    	case 5: LCD_Display("Do PaSet Mode?","Press OK or ESC"); break;
    	default: break;
    	}
    }
    
    //menu_state = 1(��ܰ���Ҧ��ΰѼƳ]�w�Ҧ��^�B2�]��ܨֺ�Ҧ��^�B3�]��ܥR�q�Ҧ��^�B4�]��ܫݾ��Ҧ��^�B5�]��ܰѼƳ]�w�Ҧ��^
    void Menu_ModeSel(void) {//�Ҧ���ܿ��:�����w�g��ܦn�F
    
        //���t�X�e�����Ҧ��W�d�A���s�վ�menu_state���ƾ�
        switch (menu_state) {//��ܰT��
        case 2: menu_state = 1;   break;  //�ֺ�Ҧ�
        case 3: menu_state = 2;   break;  //�R�q�Ҧ�
        case 4: menu_state = 3;   break;  //�ݾ��Ҧ�
        default:                  break;
        }
        Menu_ModeSel_Action();
        nFuntionIndex = _Menu_ModeParaSel_Index;  //�������
        menu_state      = 1;                      //��l�ƿ�檬�A
    }
    /*
    void Menu_ModeSel(void) {//�Ҧ���ܿ��
    	const Uint32 Max_menu_state = 4;	//����榳���ӿﶵ
    
    	if (OpMode_CheckWarning < menu_state) {//�b�˵�ĵ�ܰT���ɡAmenu_state�|�Q�]�w��Max_menu_state+1�A�H�ϧO��
    		switch (KeyEvent) {//�ھ�Key Event�ӽվ�menu_state
    		case KEYEVENT_POWER_OFF:	init_SI_GUI();	return;
    		case KEYEVENT_CANCEL:		menu_state = 1; return;
    		default:					return;
    		}
    	}
    
    	switch (KeyEvent) {//�ھ�Key Event�ӽվ�menu_state
    	case KEYEVENT_POWER_OFF:	init_SI_GUI();	return;
    	case KEYEVENT_UP:			menu_state--;	break;
    	case KEYEVENT_DOWN:			menu_state++; break;
    	case KEYEVENT_OK:			Menu_ModeSel_Action();	return; //OpMode = menu_state; do_ModeSet();
    	case KEYEVENT_CANCEL:		menu_state = 1; nFuntionIndex = _Menu_ModeParaSel_Index; return;
    	default:					break;
    	}
    
    	//�B�zmenu_state�MKEYEVENT_CLEAR;
    	if (0 == menu_state) 			 menu_state = Max_menu_state;
    	if (Max_menu_state < menu_state) menu_state=1;
    
    	switch (menu_state) {//��ܰT���G�˵�ĵ�ܰT���n��b�̫�@�Ӫ��A
    	case 1:	LCD_Display("*Grid Discharger",	" Grid Charger");	break;
    	//case 2:	LCD_Display("*Grid Charger",	" Standalone");		break;
    	//case 3:	LCD_Display("*Standalone",		" Check Warning");	break;
    	case 2:   LCD_Display("*Grid Charger",    " StandBy");     break;
    	case 3:   LCD_Display("*StandBy",      " Check Warning");  break;
    	case 4:	LCD_Display("*Check Warning",	" Grid Discharger");break;
    	default: 													break;
    	}
    }
    */
    
    void Menu_ModeSel_Action(void) {//�˵�ĵ�ܰT���άO�]�w�B��Ҧ�..
        ModeSel_Action_F = 1;
        if (OpMode_CheckWarning == menu_state) {//�n�˵�ĵ�ܰT���ܡH
            if (PVINV_WarningCode >= PVINV_WARN_NUMBER-1)   PVINV_WarningCode = PVINV_WARN_NUMBER-1;
            if (IBDC_WarningCode  >= IBDC_WARN_NUMBER-1)    IBDC_WarningCode  = IBDC_WARN_NUMBER-1;
            LCD_Display(PVINV_WarnMsg[PVINV_ErrCode], IBDC_WarnMsg[IBDC_ErrCode]);
            menu_state = OpMode_CheckWarning + 1; //�T���u�n��ܤ@���Y�i�A�[1�O���F���n�A�i�J�����
            return;
        }
        //�]�w�B��Ҧ�
        OpMode = menu_state;
        /* ���Display_Msg�����
        switch (menu_state) {//��ܰT��
        case 1: LCD_Display("Grid Discharger ", "      Waiting");   break;  //�ݭn���@�ӹL��
        case 2: LCD_Display("Grid Charger    ", "      Waiting");   break;
        case 3: LCD_Display("StandBy         ", "      RUNNING");   break;
        default:                                                    break;
        }
        */
        switch (menu_state) {//��ܰT��
        case 1: Display_Msg("W  Grid ");    break;  //�����|�q��q��Ҧ��B��e���e�m�@�~
        case 2: Display_Msg("W  BatC ");    break;  //����R�q�q���Ҧ��B��e���e�m�@�~
        case 3: Display_Msg("R StandB");    break;  //����ݾ��Ҧ����B��
        default:                            break;
        }
        do_ModeSet();
    }
    
    void do_ModeSet() {//����Ҧ��]�w�����᪺�ʧ@
        Uint16 counter;
        unsigned short Imax_D_temp = Imax_D; //�p�G�OBoost Mode�A���]�wIBDC��X�q�y��0
    
        if (1 == OpMode) Imax_D = 0;        //�p�G�OBoost Mode�A�h���]�wIBDC��X�q�y��0
        if (3 == OpMode) OpMode = 0;        //�]��������Ҧ��A�Q�θӼҦ��A�R��Stand-bye�Ҧ�
        OpModeF = 0;    do_ParaSet_Done();              //�M�ŹB��Ҧ��P��X�СA���MPPT�MINVBDC�o���B��Ѽ�
        for (counter=0; counter < 30; counter++)        //����3s
            DELAY_US(100000L);                            //����100ms
        OpModeF = 1;    mailbox_send(GUI2CAN_MAX);  //�sMPPT�MINVBDC�̹B��Ҧ��A�Ұ�
    // �����աA�������A���ݥ��}
        if (0 != OpMode) {//�D�ݾ��Ҧ��A�h������IBDC�MPVINV���^��)
            LED_YELLOW_ON; counter = 0;
            while (1) {
                DELAY_US(100000L);
                if ((1==PVINV_Report)&&(1==IBDC_Report)) {
                    PVINV_Report = GUI_Report_NoAvailable;
                    IBDC_Report = GUI_Report_NoAvailable;
                    break;
                }
                if (10 == ++counter) {OpModeF = 0; OpMode = 0; break;} //1��L��A������^���A���^Stand-by�Ҧ�
            }
            Imax_D = Imax_D_temp; do_ParaSet_Done(); //�A�Ǥ@���Ѽ�
    
            if (0 == OpMode)    LCD_Display("Try Again or    ", "Call Service ");
            LED_YELLOW_OFF;
        }
     //
        /* ���Display_Msg�����
        if (1 == OpMode)    LCD_Display("Grid Discharger ", "      RUNNING");
        if (2 == OpMode)    LCD_Display("Grid Charger    ", "      RUNNING");
        */
        if (1 == OpMode)    Display_Msg("R  Grid ");
        if (2 == OpMode)    Display_Msg("R  BatC ");
    }
    
    void do_ParaSet_Done(void) {//�N�ѼƳz�LCAN Bus�o����MPPT�MInverter+BDC...
        Uint16 nMBXnbr;
    
        //change baud rate
        setupBaudRate(BaudRate);
        for (nMBXnbr=GUI2CAN_MIN; nMBXnbr<= GUI2CAN_MAX; nMBXnbr++) {
                mailbox_send(nMBXnbr);  //�o���Ѽ�
                DELAY_US(400L);
        }
    }
    
    //***�Ѽƣ�
    
    void Menu_ParaSet(void) {//�ѼƳ]�w���
    	unsigned short SI_Parameters_Shadow[ModbusAddrMax];
    	unsigned short index;
    	unsigned short data;
    	//const Uint32 Max_menu_state = ModbusAddrMax;	//����榳ModbusAddrMax�ӿﶵ
    	char ParaMsg[ModbusAddrMax][17] = {
    		    //0123456789ABCDEF
    			{" Imax_O = 14.0 A"},
    			{" Vmin_B = 42.0 V"},
    			{" Imax_C = 30.0 A"},
    			{" Vabsor = 56.0 V"},
    			{" Tabsor =  2.0 H"},
    			{" Vfloat = 55.5 V"},
    			{" Imax_D =  7.5 A"},
    			{" LVP    =100.0 V"},
    			{" VoutF  =    1  "},
    			{" FoutF  =    1  "},
    			{" ChargeF=    1  "},
    			{" MD_ID  =    1  "},
    			{" BaudRa =    5  "}
    	};
    
    	//1. �K�X�T�{
    	if (!Password_Check()) {menu_state = 1; nFuntionIndex = _Menu_ModeParaSel_Index; return;}
    	bScanKeyTrigger = 1; KeyEvent = KEYEVENT_NO_EVENT;
    
    	//2. ��l��SI_Parameters_Shado
    	for (index=0; index<ModbusAddrMax; index++) SI_Parameters_Shadow[index] = SI_Parameters[index];
    
    	//3. �L�a�j��A����]�w�n�άO����
    	while (1) {
    		Uint16 menu_second = menu_state;
    
    		//a. ��s��ܰT��
    		if (ModbusAddrMax==menu_state) menu_second = 0;
    		ParaMsg[menu_state-1][0] = '*'; ParaMsg[menu_second][0] = ' ';
    		updateDisplayMsg(ParaMsg[menu_state-1], SI_Parameters_Shadow[menu_state-1], menu_state);
    		updateDisplayMsg(ParaMsg[menu_second], SI_Parameters_Shadow[menu_second], menu_second+1);
    		LCD_Display(ParaMsg[menu_state-1], ParaMsg[menu_second]);
    
    		//b. //���s����ƥ�ܡH��s���A�M��ھ�Key Event�ӽվ�menu_state
    		if (!bScanKeyTrigger) {KeyEvent = KeyEvent_Shadow;	KeyEvent_Shadow = KEYEVENT_NO_EVENT;}
    		switch (KeyEvent) {
    		case KEYEVENT_POWER_OFF:	init_SI_GUI();								return;
    		case KEYEVENT_UP:			menu_state--;								break;
    		case KEYEVENT_DOWN:			menu_state++;								break;
    		case KEYEVENT_CANCEL:		menu_state = 1;
    									nFuntionIndex = _Menu_ModeParaSel_Index; 	return;
    		default:																break;
    		}
    		if (KEYEVENT_OK == KeyEvent) break;
    
    		//c. �B�zmenu_state
    		if (0 == menu_state)				menu_state = ModbusAddrMax;
    		if (ModbusAddrMax < menu_state) 	menu_state=1;
    
    		//d. �̾ګ���ƥ��s���
    		data = SI_Parameters_Shadow[menu_state-1];
    		switch (KeyEvent) {
    		case KEYEVENT_LEFT:			data += 1; 							break;
    		case KEYEVENT_RIGHT:		(data<=1)? data=0:data--; 			break;
    		case KEYEVENT_LEFT_LONG:	data += 3; 							break;
    		case KEYEVENT_RIGHT_LONG:	(data <= 3)? data=0:(data -= 3);	break;
    		}
    		if (KeyEvent != KEYEVENT_NO_EVENT) {bScanKeyTrigger = 1; KeyEvent = KEYEVENT_NO_EVENT;}
    
    		//e. �T�{�b�W�U����
    		if (data > SI_Parameters_MinMax[menu_state-1][1]) data = SI_Parameters_MinMax[menu_state-1][1];
    		if (data < SI_Parameters_MinMax[menu_state-1][0]) data = SI_Parameters_MinMax[menu_state-1][0];
    		//f. ��s
    		SI_Parameters_Shadow[menu_state-1] = data;
    	}
    
    	//��s���ҳ]�w���ѼơA�M��o����MPPT�BInverter+IBDC
    	for (index=0; index<ModbusAddrMax; index++)	SI_Parameters[index] = SI_Parameters_Shadow[index];
    	do_ParaSet_Done();	menu_state = 1; nFuntionIndex = _Menu_ModeParaSel_Index;
    }
    
    //��s��ܰT��
    void updateDisplayMsg(char* pmyMsg, unsigned short myData, unsigned short position) {
    	unsigned short data;
    	unsigned short curpos;
    
    	curpos = 13; data = myData;
    	*(pmyMsg+curpos) = '0'+ data%10; data = data/10; curpos--;
    	if (position <= ModbusAddrMax-5) {//��T���ѪR��1�A�e���Ҭ�0.1
    		*(pmyMsg+curpos)='.'; curpos--;
    		if (0==data) {*(pmyMsg+curpos) = '0'+ data%10; curpos--;}
    	}
    
    	//if ((0==data)&&(position != ModbusAddrMax)) {*(pmyMsg+curpos) = '0'+ data%10; curpos--;}
    	for (; curpos>8; curpos--) {
    		if (0==data) *(pmyMsg+curpos) = ' ';
    		else {*(pmyMsg+curpos) = '0'+ data%10; data = data/10;}
    	}
    }
    
    
    //�K�X�T�{�G�����T�^��0�F�Ϥ��^��1
    //Uint16  Password = 0x1234;		//�K�X
    //Uint16  Password_Length = 4;		//�K�X����
    //�W�� = 0x01�B�U�� = 0x02�B���� = 0x03�B�k�� = 0x04
    Uint16 Password_Check(void) {
    	char PasswordMsg[2][17] = {{"Password Check"}, {"-> "}};
    	Uint16  myPassword = 0x00;
    	Uint16	myPassword_Length = 0;
    
    	//���}���䰻������
    	bScanKeyTrigger = 1; KeyEvent = KEYEVENT_NO_EVENT;
    
    	while (1) {//��J�K�X
    		LCD_Display(PasswordMsg[0], PasswordMsg[1]);
    		if (!bScanKeyTrigger) 	{KeyEvent = KeyEvent_Shadow;	KeyEvent_Shadow = KEYEVENT_NO_EVENT;}
    		else					continue;
    
    		switch (KeyEvent) {
    		case KEYEVENT_POWER_OFF:	init_SI_GUI();	return 0;
    		case KEYEVENT_UP: 			myPassword = myPassword<<4 | 0x01; myPassword_Length++; break;//<<4
    		case KEYEVENT_DOWN:			myPassword = myPassword<<4 | 0x02; myPassword_Length++; break;
    		case KEYEVENT_LEFT: 		myPassword = myPassword<<4 | 0x03; myPassword_Length++; break;
    		case KEYEVENT_RIGHT:		myPassword = myPassword<<4 | 0x04; myPassword_Length++; break;
    		case KEYEVENT_CANCEL:		bScanKeyTrigger = 1; KeyEvent = KEYEVENT_NO_EVENT; 		return 0;
    		}
    
    		if (KeyEvent == KEYEVENT_OK) {
    			if ((myPassword_Length==Password_Length) && (myPassword == Password)) {
    				bScanKeyTrigger = 1; KeyEvent = KEYEVENT_NO_EVENT;
    				return 1;	//�K�X���T
    			}
    
    			//�K�X���~���B�m
    			LCD_Display(PasswordMsg[0], "Error,Try Again?");//�߰ݭn���n�~����աH
    			bScanKeyTrigger = 1; KeyEvent = KEYEVENT_NO_EVENT;
    			while (1) {
    				if (!bScanKeyTrigger) 	{
    					KeyEvent = KeyEvent_Shadow;	KeyEvent_Shadow = KEYEVENT_NO_EVENT;
    					if (KeyEvent == KEYEVENT_OK) 		{bScanKeyTrigger = 1; KeyEvent = KEYEVENT_NO_EVENT; break;}
    					if (KeyEvent == KEYEVENT_POWER_OFF) {init_SI_GUI(); return 0;}
    					if (KeyEvent == KEYEVENT_CANCEL) 	{bScanKeyTrigger = 1; KeyEvent = KEYEVENT_NO_EVENT; return 0;}
    				}
    				bScanKeyTrigger = 1; KeyEvent = KEYEVENT_NO_EVENT;
    				DELAY_US(400L); //while�j��ӧ֡A�L�k�A�ɱo����䵲�G�A�[�ө���A�T�O��
    			}
    			myPassword = 0x00; myPassword_Length = 0;			//��J�K�X�k�s
    			PasswordMsg[1][3] = '\0';							//�M�ŬP��
    			continue;
    		}
    		if (myPassword_Length < 14) {PasswordMsg[1][myPassword_Length+2] = '*'; PasswordMsg[1][myPassword_Length+3] = '\0';}
    		if (KeyEvent != KEYEVENT_NO_EVENT) {bScanKeyTrigger = 1; KeyEvent = KEYEVENT_NO_EVENT;}
    	}
    }
    /*
    void do_ParaSet_Done(void) {//�N�ѼƳz�LCAN Bus�o����MPPT�MInverter+BDC...
    
    }
    */
    
    
    /*org
     void do_ModeSet() {//����Ҧ��]�w�����᪺�ʧ@
        Uint16 counter;
        unsigned short Imax_D_temp = Imax_D; //�p�G�OBoost Mode�A���]�wIBDC��X�q�y��0
    
        if (1 == OpMode) Imax_D = 0;        //�p�G�OBoost Mode�A�h���]�wIBDC��X�q�y��0
        OpModeF = 0;    do_ParaSet_Done();              //�M�ŹB��Ҧ��P��X�СA���MPPT�MINVBDC�o���B��Ѽ�
        for (counter=0; counter < 30; counter++)        //����3s
            DELAY_US(100000L);                            //����100ms
        OpModeF = 1;    mailbox_send(GUI2CAN_MAX);  //�sMPPT�MINVBDC�̹B��Ҧ��A�Ұ�
    
        if (1 == OpMode) {//�p�G�OBoost Mode�A�h������IBDC�MPVINV���^��)
            LED_YELLOW_ON;
            while (1) {
                DELAY_US(100000L);
                if ((1==PVINV_Report)&&(1==IBDC_Report)) {
                    PVINV_Report = GUI_Report_NoAvailable;
                    IBDC_Report = GUI_Report_NoAvailable;
                    break;
                }
            }
            Imax_D = Imax_D_temp; do_ParaSet_Done(); //�A�Ǥ@���Ѽ�
            LCD_Display("Grid Discharger ", "      RUNNING");
            LED_YELLOW_OFF;
        }
    }
     */
    //===========================================================================
    // No more.
    //===========================================================================
    
    

    SPI API file

    #include "SI_GUI_Spi.h"
    
    #include "DSP2803x_Device.h"     // DSP28 Headerfile Include File
    #include "DSP2803x_Examples.h"   // DSP28 Examples Include File
    #include "common.h"
    
    #define EEPROM_CS GpioDataRegs.GPADAT.bit.GPIO19
    
    #define RDSR        0b00000101          // RDSR  command 
    #define WREN        0b00000110          // WREN  command 
    #define WRITE       0b00000010          // WRITE command
    #define READ        0b00000011          // READ  command
    
    void spi_init(void);
    Uint16 spi_xmit(int a);
    
    void setup_EEPROM_SPI(void) {
        InitSpiaGpio();
        spi_init();
    }
    
    void spi_init(void) {
        SpiaRegs.SPICCR.all         = 0x0007; 	//Data is ready on rising edge), loopback is off, 8-bit data
        SpiaRegs.SPICTL.all         = 0x000E;   //Normal SPI clocking scheme(Data in latch on rising edge)master, 4-pin option, No interrupt
        SpiaRegs.SPIBRR             = 0x0077;   //BateRate 0.5MHz
        SpiaRegs.SPICCR.all         = 0x0087;   //SPI is ready to transmit or receive the next character.
        SpiaRegs.SPIPRI.bit.FREE    = 1;
    
        //EEPROM_CS                   = 1;
    }
    
    void read_EEPROM_Status(void) {
        //EEPROM_CS = 0;
        DELAY_US(1);
        spi_xmit(RDSR);
        //EEPROM_CS = 1;
        DELAY_US(100);
    }
    
    Uint16 spi_xmit(int a) {
        Uint16 Ret_var = 0;
    
        SpiaRegs.SPITXBUF = (a<<8);
        while(SpiaRegs.SPISTS.bit.INT_FLAG == 0);
        Ret_var = SpiaRegs.SPIRXBUF<<8;
    
        return Ret_var;
    }
    
    void addrwrite_EEPROM(Uint16 address,Uint16 Data) {
        int addrH,addrL;
        addrH = 0;
        addrL = 0;
        addrH = (address>>8);
        addrL = (address&0x00FF);
    
    //write sequence..
    //    EEPROM_CS = 0;
        DELAY_US(1);
        spi_xmit(WREN);
    //    EEPROM_CS = 1;
        DELAY_US(1);
    
     //   EEPROM_CS = 0;
        DELAY_US(1);
        spi_xmit(WRITE);
        spi_xmit(addrH);
        spi_xmit(addrL);
        spi_xmit(Data);
    
        DELAY_US(1);
    //    EEPROM_CS = 1;
        DELAY_US(10);
    }
    
    Uint16 addrread_EEPROM(Uint16 address) {
        Uint16 Ret_var=0;
    
        int addrH,addrL;
    
        addrH = 0;
        addrL = 0;
        addrH = (address>>8);
        addrL = (address&0x00FF);
    
      //  EEPROM_CS = 0;
        DELAY_US(1);
        spi_xmit(READ);
        spi_xmit(addrH);
        spi_xmit(addrL);
        Ret_var = spi_xmit(0);
        DELAY_US(1);
     //   EEPROM_CS = 1;
        DELAY_US(100);
    
        return Ret_var;
    }
    

    waveform1

    waveform2

  • 非常抱歉,本人没有SPI读写外部存储器的操作经验。建议你前往E2E英文论坛咨询相关问题:e2e.ti.com/.../171