N76E003 SPI MASTER

最近用到SPI,调试一下N76E003的SPI

首先下最新的BSP,旧的没SPI例程,我现在的是 N76E003_BSP_Keil_C51_V1.0.6

 

直接撸代码  SPI_Interrupt_Master

 

初始化:

CSS:P15

P10:SCLK

P00:MOSI

P01:MISO

 

关闭错误侦测

CSS手动

MSB First

CPOL=0 空闲低电平

CPHA=1 第一个沿(上升)发送数据,第二个沿(下降)采样

 

时钟 DIV8 =16M/8=2M

 

 1 void SPI_Initial(void)
 2 {              
 3     P15_Quasi_Mode;                                                        // P15 (SS) Quasi mode
 4     P10_Quasi_Mode;                                                        // P10(SPCLK) Quasi mode
 5     P00_Quasi_Mode;                                                        // P00 (MOSI) Quasi mode
 6     P01_Quasi_Mode;                                                        // P22 (MISO) Quasi mode
 7 
 8     set_DISMODF;                                                            // 错误侦测关闭SS General purpose I/O ( No Mode Fault ) 
 9     clr_SSOE;                                                              //CSS自己不自动
10 
11     clr_LSBFE;                                                                // MSB first         
12 
13     clr_CPOL;                                                                // The SPI clock is low in idle mode
14     set_CPHA;                                                                // The data is sample on the second edge of SPI clock 
15 
16     set_MSTR;                                                                // SPI in Master mode 
17 
18     SPICLK_DIV8;                                                            // Select SPI clock
19     Enable_SPI_Interrupt;                                                    // Enable SPI interrupt
20     set_SPIEN;                                                                // Enable SPI function 
21 }

 

 

只有一个中断,发送完成 

1 //-----------------------------------------------------------------------------------------------------------
2 void SPI_ISR(void) interrupt 9                  // Vecotr @  0x4B
3 {
4     clr_SPIF;
5     spi_send_ok=1;
6    // Timer3_Delay10us(1); 
7 }

 

main 循环发送

 1 //-----------------------------------------------------------------------------------------------------------
 2 UINT8 test_data=0;
 3 UINT8 spi_send_ok=1;
 4 void main(void)
 5 {      
 6     UINT8 u8MID,u8DID;
 7     
 8     Set_All_GPIO_Quasi_Mode;
 9     InitialUART0_Timer1(115200);             /* 115200 Baud Rate*/
10 
11     SPI_Initial();
12 
13     printf ("\nSPI Start Transmit...\n");
14     clr_SPIF;
15     while(1)
16     {
17         SS = 0;
18         spi_send_ok=0;
19         SPDR = test_data;                             
20         while(!spi_send_ok);
21         SS=1;
22         test_data+=1;
23         
24         printf ("\r\n");
25         P12=!P12;
26         Timer0_Delay1ms(500);
27         
28     }
29     
30     #if 0
31     Start_Sending_SPI(&u8MID,&u8DID);
32         
33     if((u8MID != 0x4F)&&(u8DID != 0x4E))
34         SPI_Error();
35 
36     printf ("\nSPI Test OK!\n");
37     while(1)                                    // SPI transmission finish
38     {
39         P12 = 1;
40         Timer0_Delay1ms(500);
41         P12 = 0;
42         Timer0_Delay1ms(500);
43     }
44     #endif
45 }

 

 

逻辑分析 (我这里 MOSI 和MISO 选错了 懒得改了)

 

 

 

2.6S 后cs 拉高了,

 

 

 

 

若连续发送3个数据 中间有3.8us的延迟

 1         spi_send_ok=0;
 2         SPDR = test_data;                                // Send 0x90 to Slave 
 3         while(!spi_send_ok);
 4         test_data+=1;
 5 
 6         spi_send_ok=0;
 7         SPDR = test_data;                                // Send 0x90 to Slave 
 8         while(!spi_send_ok);
 9         test_data+=1;
10         
11         spi_send_ok=0;
12         SPDR = test_data;                                // Send 0x90 to Slave 
13         while(!spi_send_ok);
14         test_data+=1;
15         
16         spi_send_ok=0;
17         SPDR = test_data;                                // Send 0x90 to Slave 
18         while(!spi_send_ok);
19         test_data+=1;

 

 

 

 

 

 

 

 

若中断里面直接做连续发送,效果更差

 

 1 void SPI_ISR(void) interrupt 9                  // Vecotr @  0x4B
 2 {
 3     clr_SPIF;
 4    // spi_send_ok=1;
 5     
 6     
 7     
 8     if(test_data<10)
 9     {
10         SPDR = test_data++;
11     }
12     else
13     {
14            spi_send_ok=1;
15     }
16     
17    // Timer3_Delay10us(1); 
18 }

 

 

1         SS = 0;
2         spi_send_ok=0;
3         SPDR = test_data++;
4         
5         while(1)
6         {
7             if(spi_send_ok)SS=1;
8         }

 

 

 

若加上读取

 

这里就不在中断里面清除了

 

 

等读取了数据,再清除

 

  1 /*---------------------------------------------------------------------------------------------------------*/
  2 /*                                                                                                         */
  3 /* Copyright(c) 2017 Nuvoton Technology Corp. All rights reserved.                                         */
  4 /*                                                                                                         */
  5 /*---------------------------------------------------------------------------------------------------------*/
  6 
  7 //***********************************************************************************************************
  8 //  Website: http://www.nuvoton.com
  9 //  E-Mail : MicroC-8bit@nuvoton.com
 10 //  Date   : Jan/21/2017
 11 //***********************************************************************************************************
 12 
 13 //***********************************************************************************************************
 14 //  File Function: N76E003 SPI in Master mode demo code
 15 //***********************************************************************************************************
 16 
 17 #include "N76E003.h"
 18 #include "SFR_Macro.h"
 19 #include "Function_define.h"
 20 #include "Common.h"
 21 #include "Delay.h"
 22 
 23 //***********************************************************************************************************
 24 //  Application: SPI Function 
 25 //  Master send 0x90 and recevie 0x4E
 26 //  Master send 0x01 and recevie 0x55
 27 //  Master send 0x02 and recevie 0x56
 28 //  Master send 0x03 and recevie 0x4F
 29 //  Master send 0x04 and recevie 0x54
 30 //
 31 //  Master recevie 0x4E and 0x4F form slave after transmitting
 32 //
 33 //  Output : P1.4 & P2.1 flash when SPI pass
 34 //           UART show result on hyper-terminal
 35 //           P0.7 flash when SPI error
 36 //***********************************************************************************************************
 37 
 38 #if 0
 39 ///*****************************************************************************************
 40 //* For ADC INIT setting 
 41 //*****************************************************************************************/
 42 //#define        SPICLK_DIV2            clr_SPR0;clr_SPR1
 43 //#define        SPICLK_DIV4            set_SPR0;clr_SPR1
 44 //#define        SPICLK_DIV8            clr_SPR0;set_SPR1
 45 //#define        SPICLK_DIV16        set_SPR0;set_SPR1
 46 //#define        Enable_SPI_Interrupt        set_ESPI;set_EA
 47 //#define        SS        P15
 48 #endif
 49 
 50 UINT8 spi_send_ok=1;
 51 
 52 //-----------------------------------------------------------------------------------------------------------
 53 void SPI_Error(void)
 54 {
 55     printf ("\nSPI error.\n");
 56     while(1)                                    // SPI error and P0.7 flash/
 57     {
 58         P07 = 1;
 59         Timer0_Delay1ms(500);
 60         P07 = 0;
 61         Timer0_Delay1ms(500);
 62     }
 63 }
 64 //-----------------------------------------------------------------------------------------------------------
 65 void SPI_Initial(void)
 66 {              
 67     P15_Quasi_Mode;                                                        // P15 (SS) Quasi mode
 68     P10_Quasi_Mode;                                                        // P10(SPCLK) Quasi mode
 69     P00_Quasi_Mode;                                                        // P00 (MOSI) Quasi mode
 70     P01_Quasi_Mode;                                                        // P22 (MISO) Quasi mode
 71 
 72     set_DISMODF;                                                            // ½ûÖ¹´íÎóÕì²â SS General purpose I/O ( No Mode Fault ) 
 73     clr_SSOE;                                                           //CSS²»×Ô¶¯À­µÍ ×Ô¼ºÑ¡Ôñ
 74 
 75     clr_LSBFE;                                                                // MSB first         
 76 
 77     clr_CPOL;                                                                // The SPI clock is low in idle mode
 78     set_CPHA;                                                                // The data is sample on the second edge of SPI clock 
 79 
 80     set_MSTR;                                                                // SPI in Master mode 
 81 
 82     SPICLK_DIV8;                                                            // Select SPI clock
 83     Enable_SPI_Interrupt;                                                    // Enable SPI interrupt
 84     set_SPIEN;                                                                // Enable SPI function 
 85 }
 86 //-----------------------------------------------------------------------------------------------------------
 87 void Start_Sending_SPI(UINT8 *pu8MID,UINT8 *pu8DID)
 88 {
 89     SS = 0;
 90 
 91     SPDR = 0x90;                                // Send 0x90 to Slave 
 92     PCON |= SET_BIT0;                           // Enter idle mode
 93     if(SPDR != 0x4E)                            // Receive slave 1st DATA 
 94        SPI_Error(); 
 95     printf ("\nSlave Return %c!\n",SPDR);
 96                                           
 97     SPDR = 0x01;                                // Send 0x01 to Slave 
 98     PCON |= SET_BIT0;                           // Enter idle mode
 99     if(SPDR != 0x55)                            // Receive slave 2nd DATA  
100        SPI_Error();
101     printf ("\nSlave Return %c!\n",SPDR);
102 
103     SPDR = 0x02;                                // Send 0x02 to Slave 
104     PCON |= SET_BIT0;                           // Enter idle mode
105     if(SPDR != 0x56)                            // Receive slave 3rd DATA 
106        SPI_Error();
107     printf ("\nSlave Return %c!\n",SPDR);
108 
109     SPDR = 0x03;                                // Send 0x03 to Slave 
110     PCON |= SET_BIT0;                           // Enter idle mode
111     if(SPDR != 0x4F)                            // Receive slave 4th DATA
112        SPI_Error();
113     printf ("\nSlave Return %c!\n",SPDR);
114 
115     SPDR = 0x04;                                // Send 0x04 to Slave 
116     PCON |= SET_BIT0;                           // Enter idle mode
117     if(SPDR != 0x54)                            // Receive slave 5th DATA 
118        SPI_Error();
119     printf ("\nSlave Return %c!\n",SPDR);
120 
121     SPDR = 0x4F;                   
122     PCON |= SET_BIT0;                           // Enter idle mode
123     *pu8MID = SPDR;                             // Receive Slave 1st DATA fron Slave       
124     printf ("\nSlave Return %c!\n",SPDR);
125 
126     SPDR = 0x4E;                   
127     PCON |= SET_BIT0;                           // Enter idle mode             
128     *pu8DID = SPDR;                             // Receive Slave 2nd DATA from Slave 
129     printf ("\nSlave Return %c!\n",SPDR);
130 
131     SS = 1;    
132 }
133 
134 void spi_send(uint8_t *tdata,uint8_t *rdata,uint8_t len)
135 {
136     uint8_t i;
137     uint8_t *p;
138     SS=0;
139     for(i=0;i<len;i++)
140     {
141         spi_send_ok=0;
142         SPDR = *(tdata+i); //轮训发送数据
143         while(!spi_send_ok);//等待发送完成
144         *(rdata+i)=SPDR;//接收数据
145         clr_SPIF; //接收完了再清标志
146         //printf ("data[%02x] %02x\r\n",i,rdata);
147        // Timer3_Delay10us(10);
148     }
149     SS=1;
150 }
151 
152 //-----------------------------------------------------------------------------------------------------------
153 
154 uint8_t test_data_s[11]="0123456789";
155 uint8_t test_data_r[11]="";
156 void main(void)
157 {      
158     UINT8 u8MID,u8DID;
159     
160     Set_All_GPIO_Quasi_Mode;
161     InitialUART0_Timer1(115200);             /* 115200 Baud Rate*/
162 
163     SPI_Initial();
164 
165     printf ("\nSPI Start Transmit...\n");
166     clr_SPIF;
167     
168     while(1)
169     {
170 
171         spi_send(test_data_s,test_data_r,10);
172         
173         printf ("\r\n");
174         P12=!P12;
175         Timer0_Delay1ms(500);
176         
177     }
178     
179     #if 0
180     Start_Sending_SPI(&u8MID,&u8DID);
181         
182     if((u8MID != 0x4F)&&(u8DID != 0x4E))
183         SPI_Error();
184 
185     printf ("\nSPI Test OK!\n");
186     while(1)                                    // SPI transmission finish
187     {
188         P12 = 1;
189         Timer0_Delay1ms(500);
190         P12 = 0;
191         Timer0_Delay1ms(500);
192     }
193     #endif
194 }
195 //-----------------------------------------------------------------------------------------------------------
196 void SPI_ISR(void) interrupt 9                  // Vecotr @  0x4B
197 {
198     //clr_SPIF;
199     spi_send_ok=1;
200    // Timer3_Delay10us(1); 
201 }
202 //-----------------------------------------------------------------------------------------------------------

 

 

算力有限,8位数据中间27.5us的间隔

 

//等待发送完成
posted @ 2020-06-04 12:22  XZHDJH  阅读(710)  评论(0)    收藏  举报