Hallo, ich rätsel gerade an einen Phänomän auf dem Stm32F030C herum und komme irgendwie nicht weiter. Ich habe 2 uCs mittels SPI2 und DMA auf dem STM32 miteinander verbunden und versuche zwischen beiden zu kommunizeren. Dei sendet der zweite uc alle 10ms eine Nachricht in Richtung STM (Mein Problem geht aber auch bei langsameren Zeiten nicht - nur mal so vorweg - hab das auch mit 1s probiert). In Richtung des anderen uC geht das auch Prächtig - allerdings ist der zurück kommenede Frame merkwürdig verschoben. Und zwar verschiebt sich das Ding von Nachricht zu Nachricht jeweils um 1 Byte nach vorne und wird hinten wieder aufgefüllt. Ankommmen sollte zum Beispiel: 0xF1 - 0xAA - 0x03 - 0xFF - 0xF2 das kommt beim erstem Mal dann auch. Dann kommt beim zweitem Durchlauf 0xAA - 0x03 - 0xFF - 0xF2 - 0xF1 in der nächsten Runde verschiebt sich das ganze wieder um ein Byte 0x03 - 0xFF - 0xF2 - 0xF1 - 0xAA SPI2 ist dabei als Master configuriert:
1 | void SPI2_Init_Master (void) |
2 | {
|
3 | /* init SPI 2 as master for nordic commincation */
|
4 | |
5 | GPIO_InitTypeDef GPIO_InitStructure; |
6 | SPI_InitTypeDef SPI_InitStructure; |
7 | |
8 | /* enable GPIO clock */
|
9 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); |
10 | |
11 | /*enable SPI1 clock*/
|
12 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); |
13 | |
14 | /* Configure SPI2 IO Pin's */
|
15 | GPIO_InitStructure.GPIO_Pin = SPI2_SCK | SPI2_MOSI | SPI2_MISO; |
16 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
17 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; |
18 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; |
19 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; |
20 | GPIO_Init(GPIOB, &GPIO_InitStructure); |
21 | |
22 | GPIO_StructInit (&GPIO_InitStructure); |
23 | |
24 | GPIO_PinAFConfig(GPIOB, SPI2_SCK_AF, GPIO_AF_0); |
25 | GPIO_PinAFConfig(GPIOB, SPI2_MISO_AF, GPIO_AF_0); |
26 | GPIO_PinAFConfig(GPIOB, SPI2_MOSI_AF, GPIO_AF_0); |
27 | |
28 | /*Configure SPI2*/
|
29 | SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; |
30 | SPI_InitStructure.SPI_Mode = SPI_Mode_Master; |
31 | |
32 | SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; |
33 | SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; |
34 | SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; |
35 | SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; |
36 | SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; |
37 | SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; |
38 | SPI_InitStructure.SPI_CRCPolynomial = 8; |
39 | |
40 | SPI_Init(SPI2, &SPI_InitStructure); |
41 | SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); |
42 | SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE); |
43 | }
|
dazu gehört dann natürlich noch DMA4/5:
1 | void SPI2_DMA_init (unsigned char* rx_buff,unsigned char* tx_buff) |
2 | {
|
3 | |
4 | DMA_InitTypeDef DMA_InitStructure; |
5 | NVIC_InitTypeDef NVIC_InitStructure; |
6 | |
7 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // enable DMA clock |
8 | |
9 | |
10 | /*Configure DMA channel 4 to SPI2 -> memory -> Rx*/
|
11 | DMA_DeInit(DMA1_Channel4); |
12 | DMA_InitStructure.DMA_PeripheralBaseAddr = SPI2_DR_Address; |
13 | DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) rx_buff; |
14 | DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; |
15 | DMA_InitStructure.DMA_BufferSize = SPI2_BUFFER_SIZE_RX+2; |
16 | DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; |
17 | DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; |
18 | DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; |
19 | DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; |
20 | DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; |
21 | DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; |
22 | DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; |
23 | DMA_Init(DMA1_Channel4, &DMA_InitStructure); |
24 | |
25 | DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE); // enable DMA interrupt |
26 | DMA_Cmd(DMA1_Channel4, DISABLE); // disenable DMA |
27 | |
28 | /*Configure NVIC for DMA interrupt*/
|
29 | NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_5_IRQn; |
30 | NVIC_InitStructure.NVIC_IRQChannelPriority = 0; |
31 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; |
32 | NVIC_Init(&NVIC_InitStructure); |
33 | |
34 | DMA_SetCurrDataCounter(DMA1_Channel4, 0); |
35 | DMA_Cmd(DMA1_Channel4, ENABLE); |
36 | |
37 | /*Configure DMA channel 5 to memory -> SPI2 -> Tx*/
|
38 | DMA_DeInit(DMA1_Channel5); |
39 | DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPI2_DR_Address; |
40 | DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)tx_buff; |
41 | DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; |
42 | DMA_InitStructure.DMA_BufferSize = SPI2_BUFFER_SIZE_TX+2; |
43 | DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; |
44 | DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; |
45 | DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; |
46 | DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; |
47 | DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; |
48 | DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; |
49 | DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; |
50 | DMA_Init(DMA1_Channel5, &DMA_InitStructure); |
51 | |
52 | DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE); |
53 | DMA_Cmd(DMA1_Channel5, DISABLE); |
54 | |
55 | NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_5_IRQn; |
56 | NVIC_InitStructure.NVIC_IRQChannelPriority = 0; |
57 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; |
58 | NVIC_Init(&NVIC_InitStructure); |
59 | |
60 | DMA_SetCurrDataCounter(DMA1_Channel5, 0); |
61 | DMA_Cmd(DMA1_Channel5, ENABLE); |
62 | }
|
Die auszlesenden Werte werden in den Übergabepointer geschrieben, der auf ein array von der Größe Buffer + 2 zeigt. Sobald der DMA Interrupt TC4 auslösst schreibe ich die Werte dann weg - fahre ein Deinit auf DMA4/5 und SPI2 und initalisere alles neu. Aber das Problem bleibt das selbe. Hat jemand eine Idee woran das liegen könnte? In die andere Richtung läuft alle sauber und die Daten die der andere Controller ausgibt sehen auf dem Osziloskop klasse aus - alles da wo es hin gehört. Grüße Jens