Форум программистов, компьютерный форум, киберфорум
Цифровая обработка сигналов
Войти
Регистрация
Восстановить пароль
 
0 / 0 / 0
Регистрация: 20.04.2017
Сообщений: 34
1

STM32+W5500 не работает

24.07.2020, 13:17. Просмотров 112. Ответов 0
Метки нет (Все метки)

Здравствуйте, пару лет назад писал программу на atmega32 и atmega328 для w5500, все работало отлично, сейчас пришлось пересесть на stm32 и тут начались проблемы. Первое что бросилось в глаза это, что в SPI нет передачи переменной длинны, но вопрос не об этом сейчас. Я написал программу используя примеры из интернета, библиотеки и даташит. Также пользовался старыми наработками работы с w5500 на atmega. Но он отказывается работать, ниже я приведу фотографии осциллограмма передачи и код настройки SPI и записи данных в w5500.

1. Код настройки и работы с SPI

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include"stdbool.h"
#include"stm32f1xx.h"
#include"SPI.h"
 
void SPI1_ini(void)
{
    RCC->APB2ENR |= RCC_APB2ENR_SPI1EN | RCC_APB2ENR_IOPAEN ; //Turn on clock PORTA and SPI1
    
    //---------------------Settings Altrnative function PORTA--------------------
    //---------------------------------------------------------------------------   
    //---------------------------------------------------------------------------   
    //SCK: PA5  
        GPIOA->CRL &= ~(GPIO_CRL_MODE5_0 | GPIO_CRL_MODE5_1);//reset
        GPIOA->CRL &= ~(GPIO_CRL_CNF5_0  | GPIO_CRL_CNF5_1 );//reset    
        GPIOA->CRL |=  (GPIO_CRL_MODE5_0 | GPIO_CRL_MODE5_1);// Mode output 50 MHz PA5  
        GPIOA->CRL |= GPIO_CRL_CNF5_1;//Alternate function  output Push-pull
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    //MISO: PA6 
        GPIOA->CRL &= ~(GPIO_CRL_MODE6_0 | GPIO_CRL_MODE6_1);//reset
        GPIOA->CRL &= ~(GPIO_CRL_CNF6_0  | GPIO_CRL_CNF6_1 );//reset
        GPIOA->CRL |= GPIO_CRL_CNF6_0;//Floating input
    //----------------------------------------------------------------------------
    //---------------------------------------------------------------------------   
    //MOSI: PA7 
        GPIOA->CRL &= ~(GPIO_CRL_MODE7_0 | GPIO_CRL_MODE7_1);//reset
        GPIOA->CRL &= ~(GPIO_CRL_CNF7_0  | GPIO_CRL_CNF7_1 );//reset
        GPIOA->CRL |= GPIO_CRL_MODE7_0 | GPIO_CRL_MODE7_1 ;
        GPIOA->CRL |= GPIO_CRL_CNF7_1 ;
    //---------------------------------------------------------------------------
    //CS: PA12
        GPIOA->CRH |= GPIO_CRH_MODE12_1 | GPIO_CRH_MODE12_0 ;// Output 50MHz
        GPIOA->CRH &= ~(GPIO_CRH_CNF12_1 | GPIO_CRH_CNF12_0 );// Output push-pull 
        GPIOA->BSRR |= GPIO_BSRR_BS12; //Up PINA12
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    
    //1. Select the BR[2:0] bits to define the serial clock baud rate (see SPI_CR1 register).
        SPI1->CR1 &= ~( SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0 ) ; // divider 2
        //Uncomment the necessary divisor
        SPI1->CR1 |= ( SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0 ) ; //divider 256
        //SPI1->CR1 |= ( SPI_CR1_BR_2 | SPI_CR1_BR_1 ) ;              //divider 128
        //SPI1->CR1 |= ( SPI_CR1_BR_2 | SPI_CR1_BR_0 ) ;              //divider 64
        //SPI1->CR1 |= ( SPI_CR1_BR_2 ) ;                             //divider 32
        //SPI1->CR1 |= ( SPI_CR1_BR_1 | SPI_CR1_BR_0 ) ;              //divider 16
        //SPI1->CR1 |= ( SPI_CR1_BR_1 ) ;                             //divider 8
        //SPI1->CR1 |= ( SPI_CR1_BR_0 ) ;                             //divider 4
    //---------------------------------------------------------------------------
    
    
    //2. Select the CPOL and CPHA bits to define one of the four relationships between the
    //data transfer and the serial clock
        //CPOL: Clock polarity 0: CK to 0 when idle
        //CPHA: Clock phase 0: The first clock transition is the first data capture edge
        SPI1->CR1 &= ~( SPI_CR1_CPOL | SPI_CR1_CPHA );
    //---------------------------------------------------------------------------
    
    
    //3. Set the DFF bit to define 8- or 16-bit data frame format
    //DFF: Data frame format 0: 8-bit data frame format is selected for transmission/reception
        SPI1->CR1 &= ~SPI_CR1_DFF ;
    //---------------------------------------------------------------------------
    
    
    //4. Configure the LSBFIRST bit in the SPI_CR1 register to define the frame format
    //LSBFIRST: Frame format 0: MSB transmitted first
        SPI1->CR1 &= ~SPI_CR1_LSBFIRST; 
    //---------------------------------------------------------------------------
    
    
    //5. If the NSS pin is required in input mode, in hardware mode, connect the NSS pin to a
    //high-level signal during the complete byte transmit sequence. In NSS software mode,
    //set the SSM and SSI bits in the SPI_CR1 register. If the NSS pin is required in output
    //mode, the SSOE bit only should be set.
    //We don't use this function
    //---------------------------------------------------------------------------
    
    
    //6. The MSTR and SPE bits must be set (they remain set only if the NSS pin is connected
    //to a high-level signal)
    //MSTR: Master selection 0: Slave configuration ; 1: Master configuration ;
        SPI1->CR1 &= ~SPI_CR1_MSTR ;
        SPI1->CR1 |= SPI_CR1_MSTR ;
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    
    
    //BIDIMODE: Bidirectional data mode enable 
    //0: 2-line unidirectional data mode selected
    //1: 1-line bidirectional data mode selected
        SPI1->CR1 &= ~SPI_CR1_BIDIMODE;
    //---------------------------------------------------------------------------
    
    
    //RXONLY: Receive only
    //This bit combined with the BIDImode bit selects the direction of transfer in 2-line
    //unidirectional mode. This bit is also useful in a multislave system in which this particular
    //slave is not accessed, the output from the accessed slave is not corrupted.
    //0: Full duplex (Transmit and receive)
    //1: Output disabled (Receive-only mode)
        //SPI1->CR1 &= ~SPI_CR1_RXONLY;
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    
    
        unsigned int count = 0;
        while(1)
        {
            count++;
            if(count == 25000) break;
            __NOP();
        }
    //---------------------------------------------------------------------------   
        // Set TX interrupt
        //SPI1->CR2 |= SPI_CR2_TXEIE;
        // Set RX interrupt
        //SPI1->CR2 |= SPI_CR2_RXNEIE;
        
        //Set SPE: SPI enable 0: Peripheral disabled ; 1: Peripheral enabled ;
        SPI1->CR1 &= ~SPI_CR1_SPE ;
        SPI1->CR1 |= SPI_CR1_SPE ;
    //---------------------------------------------------------------------------
}
///////////////////////////////////////////////////////////////////////////////
void SPI1_TX_8bit(uint8_t *data, uint8_t lengthData)
{
    //uint8_t count = 0;
    while(!(SPI1->SR & SPI_SR_TXE)){}
    while((SPI1->SR & SPI_SR_BSY) == SPI_SR_BSY_Msk){}
    //uint16_t read_ =  SPI1->DR;
    //while(!(SPI1->SR & SPI_SR_TXE)){count++;if(count == 240) return;}
    while(lengthData!=0) 
    {
        SPI1->DR = *data++;
        lengthData--;
    }
}
///////////////////////////////////////////////////////////////////////////////
void SPI1_DROP_CS(void)
{
    while(!(SPI1->SR & SPI_SR_TXE)){}
    GPIOA->BRR = GPIO_BRR_BR12;
}
///////////////////////////////////////////////////////////////////////////////
void SPI1_UP_CS(void)
{ 
    uint8_t count = 0;
    while((SPI1->SR & SPI_SR_TXE) == ~SPI_SR_TXE_Msk){}
    //while((SPI1->SR & SPI_SR_RXNE) == SPI_SR_RXNE_Msk){}
    while((SPI1->SR & SPI_SR_BSY) == SPI_SR_BSY_Msk){}
    while(1){count++;if(count == 75){ count = 0; break;}__NOP();}
    GPIOA->BSRR = GPIO_BSRR_BS12;
}
///////////////////////////////////////////////////////////////////////////////
uint8_t SPI1_Read(void)
{
 // SPI1->DR = 0; //запускаем обмен
  
  //Ждем, пока не появится новое значение 
  //в буфере приемника
  while(!(SPI1->SR & SPI_SR_RXNE))
    ;
  
  //возвращаем значение буфера приемника
  return SPI1->DR;
}



2. Код настройки w5500 (В нем много мусора, его можно упросить)

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
*/
#include"stdbool.h"
#include"w5500.h"
#include"stdint.h"
#include"SPI.h"
#include"math.h"
#include"stm32f1xx.h"
 
//Шлюз
static uint8_t GatewayAddress [4] = { 0xC0, 0xA8, 0x00, 0x01};//192.168.0.1
//static uint8_t *ptr_GatewayAddress = GatewayAddress;
//Маска подсети
static uint8_t SubnetMaskAddress [4] = {0xFF,0xFF,0xFF,0x00};//255.255.255.0
//static uint8_t *ptr_SubnetMaskAddress = SubnetMaskAddress;
//MAC адрес
// FF 23 5F 63 21 38
static uint8_t SourceHardwareAddress [6] =  { 0xFF, 0x23, 0x5F, 0x63, 0x21, 0x38 };
//static uint8_t *ptr_SourceHardwareAddress = SourceHardwareAddress;
//IP источника
static uint8_t SourceIPAddress [4] = { 0xC0, 0xA8, 0x00, 0x0F};// 192.168.0.40
////////////////////////////////////////////////////////////////////////////////
static uint8_t NUM_PORT_SOCKET_0_1 = 0x13;
static uint8_t NUM_PORT_SOCKET_0_0 = 0x88;
////////////////////////////////////////////////////////////////////////////////
 
 
 
 
 
 
//Функция отправки адреса и контрольной суммы режим отправки неограниченной длины
void WriteAddrPhaseANDControlPhase(uint16_t AddrPhase, uint8_t BSB, bool RorW)
{
    uint8_t data = 0;
    uint8_t *ptr_data = &data;
    data = AddrPhase>>8;
    SPI1_TX_8bit(ptr_data,sizeof(data));//TX Hight Bits Addr
    data = 0;
    data |= (uint8_t)AddrPhase;
    SPI1_TX_8bit(ptr_data,sizeof(data));//TX Low Bits Addr
    data = 0;
    data |= (BSB << 3);
    if(RorW == true) data |= 1 << 2;
    SPI1_TX_8bit(ptr_data,sizeof(data));
}
 
void W5500IniGARx_SUBRx_SHARx_SIPRx(void)
{
        //uint8_t count = 0;
    //--------------------------------------------------------------------------------
        SPI1_DROP_CS();
        WriteAddrPhaseANDControlPhase(GAR0, SelectsComonRegister, true);
    //Transmit GatewayAddress
        SPI1_TX_8bit(GatewayAddress, sizeof(GatewayAddress[0]));
        SPI1_TX_8bit(GatewayAddress+1, sizeof(GatewayAddress[1]));
        SPI1_TX_8bit(GatewayAddress+2, sizeof(GatewayAddress[2]));
        SPI1_TX_8bit(GatewayAddress+3, sizeof(GatewayAddress[3]));
        SPI1_UP_CS();
        //while(count != 240 ){count++;__NOP();__NOP();}
    //--------------------------------------------------------------------------------
    //Transmit SubnetMaskAddress
        //SPI1_DROP_CS();
        //WriteAddrPhaseANDControlPhase(SUBR0, SelectsComonRegister, true);
    /*  SPI1_TX_8bit(SubnetMaskAddress, sizeof(SubnetMaskAddress[0]));
        SPI1_TX_8bit(SubnetMaskAddress+1, sizeof(SubnetMaskAddress[1]));
        SPI1_TX_8bit(SubnetMaskAddress+2, sizeof(SubnetMaskAddress[2]));
        SPI1_TX_8bit(SubnetMaskAddress+3, sizeof(SubnetMaskAddress[3]));
        //SPI1_UP_CS();
        //while(count !=240 ){count++;__NOP();__NOP();}
    //--------------------------------------------------------------------------------
    //Transmit SourceHardwareAddress
        //SPI1_DROP_CS();
        //WriteAddrPhaseANDControlPhase(SHAR0, SelectsComonRegister, true);
        SPI1_TX_8bit(SourceHardwareAddress, sizeof(SourceHardwareAddress[0]));
        SPI1_TX_8bit(SourceHardwareAddress+1, sizeof(SourceHardwareAddress[1]));
        SPI1_TX_8bit(SourceHardwareAddress+2, sizeof(SourceHardwareAddress[2]));
        SPI1_TX_8bit(SourceHardwareAddress+3, sizeof(SourceHardwareAddress[3]));
        SPI1_TX_8bit(SourceHardwareAddress+4, sizeof(SourceHardwareAddress[4]));
        SPI1_TX_8bit(SourceHardwareAddress+5, sizeof(SourceHardwareAddress[5]));
        //SPI1_UP_CS();
        //while(count !=240 ){count++;__NOP();__NOP();}
    //--------------------------------------------------------------------------------
    //Transmit SourceHardwareAddres
        //SPI1_DROP_CS();
        //WriteAddrPhaseANDControlPhase(SIPRO0, SelectsComonRegister, true);
        SPI1_TX_8bit(SourceIPAddress, sizeof(SourceIPAddress[0]));
        SPI1_TX_8bit(SourceIPAddress+1, sizeof(SourceIPAddress[1]));
        SPI1_TX_8bit(SourceIPAddress+2, sizeof(SourceIPAddress[2]));
        SPI1_TX_8bit(SourceIPAddress+3, sizeof(SourceIPAddress[3]));
        SPI1_UP_CS();
        //while(count !=240 ){count++;__NOP();__NOP();}*/
    //--------------------------------------------------------------------------------
}
//////////////////////////////////////////////////////////////////////////////////////////
 
 
void W5500_SettingsSocket(void)
{
    SPI1_DROP_CS();
    WriteAddrPhaseANDControlPhase(Sn_PORT0,SelectsSoket0Register,true);
    SPI1_TX_8bit(&NUM_PORT_SOCKET_0_1,sizeof(NUM_PORT_SOCKET_0_1));
    SPI1_TX_8bit(&NUM_PORT_SOCKET_0_0,sizeof(NUM_PORT_SOCKET_0_0));
    SPI1_UP_CS();
}


3. Осциллограммы на первой картинке показаны синхроимпульсы
На первом рисунке показаны синхроимпульсы желтым цветом, а данные которые я передаю красным.
На второй картинке красным синхроимпульсы, а желтым CS. У осциллографа два входа поэтому пришлось делать две фотографии. я там передаю GatewayAddress [4] = { 0xC0, 0xA8, 0x00, 0x01};//192.168.0.1 это данные ну, а в начале идет передача служебных данных.
Общая длина посылки 56 бита, я считал все совпадает, когда я пытаюсь прочитать из w5500, я ничего не получаю.


За ответы заранее спасибо, с Уважением NiKit_A
0
Миниатюры
STM32+W5500 не работает   STM32+W5500 не работает  
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.07.2020, 13:17
Ответы с готовыми решениями:

Работа с W5500
Доброго времени суток. Пытаюсь запустить Ethernet микруху W5500. Настройки работают, IP и порт...

STM32. SD карта работает в release, но не работает в debug
Здравствуйте. У меня следующая проблема: SD карта инициализируется только в release сборке. Если...

TrueStudio + w5500 Ethrnet
по мотивам описанного http://www.nazim.ru/2386 пытаюсь соединится с модулем w5500 использую...

W5500 и arduino NANO
Всем привет. Привязываю китайский модуль W5500 к arduino NANO. Пишу в Atmel Studio на Си....

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.07.2020, 13:17

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Что вы думаете о W5500?
цена вопроса 2-3 доллара. полное решение для скажем сервера на камне. стоит ли мутить стеки на...

Как работает ADC в STM32 ?
Добрый день ! Я тут балуюсь с Нуклео бордом и хочу замерить напряжение через ADC. Недолго думая...

В IAR не работает код UART STM32
Добрый день, программа 100% рабочая, проверено в CooIDE. В IAR она собирается но не работает,...

STM32:TIM6-DMA-DAC не работает связка :-(
Добрый вечер, вроде бы все по даташитам делаю, но запустить связку не могу... int main(void)...

STM32 F103C8 не работает вывод на пин MCO (Решено)
Добрый день. Столкнулся с проблемой. Хочу посмотреть частоту на пине МСО (PA8), но никак не могу...

Плата STM32 F4 Discovery. Не работает при включении внешнего резонатора
Плата STM32 F4 Discovery. В CubeMX создаю проект и выбираю в RCC режим HSE (внешнее тактирование)...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.