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的间隔

//等待发送完成

浙公网安备 33010602011771号