Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
0 / 0 / 0
Регистрация: 15.12.2019
Сообщений: 53
1

Stm32f4 cmsis

15.12.2019, 23:21. Просмотров 1034. Ответов 17
Метки нет (Все метки)

как настроить таймер stm32f4 cmsis
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.12.2019, 23:21
Ответы с готовыми решениями:

CMSIS и STM32F4
Имеется Dyscovery c STM32F4 на борту. От SPL решил отказаться и использовать только CMSIS. CMSIS...

ADC через CMSIS на STM32F4
Всем привет Пытаюсь запустить ADC через CMSIS на STM32F4 и не идут данные с АЦП в чем может быть...

Использование функций CMSIS-DSP в STM32f4
Приветствую. Проблема такова, написал я программу с использованием DSP функций, входящих в CMSIS,...

I2C CMSIS
всем привет кто работал с модулем I2C на STM32F103 используя только CMSIS скиньте пример...

17
1778 / 1108 / 109
Регистрация: 04.01.2010
Сообщений: 3,885
16.12.2019, 08:59 2
подсмотрите в драйвер от ST
0
0 / 0 / 0
Регистрация: 15.12.2019
Сообщений: 53
16.12.2019, 19:18  [ТС] 3
драйвер HAL,я имею ввиду что на stm32f103b cmsis у меня настроить таймер в прерываниях удаётся.И что я увижу разницу в драйверах?
0
811 / 493 / 160
Регистрация: 30.07.2015
Сообщений: 1,623
17.12.2019, 08:34 4
ivan rusev, ну вы там хоть код который надо портировать под CMSIS скиньте, а то таймер у STM можно сконфигурировать в десятки рабочих режимов
0
1778 / 1108 / 109
Регистрация: 04.01.2010
Сообщений: 3,885
17.12.2019, 10:41 5
ivan rusev, поставьте Cube MX, в принципе в нем визуально вы выставите все клоки и настроите таймер как вам нужно. Потом он сгенерит код (есть опция генерить в отдельном файле по всем перифериям) и вы увидите какие регистры нужно ставить.
0
0 / 0 / 0
Регистрация: 15.12.2019
Сообщений: 53
17.12.2019, 20:49  [ТС] 6
Меня интересует режим internal clock.И куда скинуть?

Добавлено через 1 час 39 минут
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*
 * main.c
 *
 *  Created on: 2 лист. 2019 р.
 *      Author: Ivan
 */
 
 
#include "main.h"
//#define TIM_EnableIT_UPDATE(TIMx) SET_BIT(TIMx->DIER, TIM_DIER_UIE)
//#define TIM_EnableCounter(TIMx) SET_BIT(TIMx->CR1, TIM_CR1_CEN)
//#define TIM_DisableCounter(TIMx) CLEAR_BIT(TIMx->CR1, TIM_CR1_CEN)
//#define  NVIC_EnableIRQ ( TIM2_IRQn  )
 volatile unsigned char flag=0;
 volatile unsigned char program=0;
 volatile unsigned char adc_data=0;
 volatile unsigned int pauza1=0;
 volatile unsigned int pauza2=0;
 void pauza (int T)//ввод самой паузы(программы) она написана отдельно и введеннием #include "paua.h"можно писать в основном цыкле pauza()с вводом целой переменной T
 {
    int i=0;//введение целойперемменой i
    char t=0;// введение вещественной переменной t считает такты микроконтролера
    for(i=0;i<T;t++) //програмама в цыкле
   {
    if(t==255)i=i+1;// условия одного цыкла счёта пределитель i определяется регистром TCCR2 определяется 0.1.2 битами это делителем частоты работы таймера
   }
 }
 void TIM1_IRQHandler(void)
 {
    // TIM1->DIER&=~TIM_DIER_UIE;
     TIM2->SR &= ~ TIM_SR_UIF;
     pauza1++;
      if(pauza1>10)
             {
                  GPIOC-> BSRR |=GPIO_BSRR_BS13;
             }
             if(pauza1>20)
              {
                  GPIOC-> BSRR |=GPIO_BSRR_BR13;
                  pauza2=0;
               }
 
     //  GPIOC->ODR ^= GPIO_ODR_OD1;
 }
void TIM2_IRQHandler(void)
{
    //TIM2->DIER&=~TIM_DIER_UIE;
    if(TIM2->SR& TIM_SR_UIF)
    {
     TIM2->SR &= ~ TIM_SR_UIF;
      pauza2++;
    //if(!(GPIOC->IDR& GPIO_IDR_ID0))
    //{
    //  pauza(20);
         if(pauza2>10)
         {
              GPIOC-> BSRR |=GPIO_BSRR_BS13;
         }
         if(pauza2>20)
          {
              GPIOC-> BSRR |=GPIO_BSRR_BR13;
              pauza2=0;
           }
    }
 }
 
 
 
void PROGRAM(void)
{
    //GPIOC-> BSRR |=GPIO_BSRR_BS1;
        //      pauza(2000);
        //     GPIOC-> BSRR |=GPIO_BSRR_BR1;
        //       pauza(2000);
}
void inits_timer1(void)
{
    RCC->APB2ENR |=RCC_APB2ENR_TIM1EN;
    NVIC_EnableIRQ (TIM1_UP_TIM10_IRQn   );
        TIM1->PSC = 2000-1;//24000 - 1; // Настраиваем делитель что таймер тикал 1000 раз в секунду
              TIM1->ARR = 10 ;
              TIM1->DIER |= TIM_DIER_UIE;//устанавливаем флаг 1по таймеру
              TIM1->CR1|= TIM_CR1_CEN;//разрешаем работу таймера
 
}
void inits_timer2(void)
{
    RCC->APB1ENR |=RCC_APB1ENR_TIM2EN;
 
    TIM2->PSC = 2400 - 1; // Настраиваем делитель что таймер тикал 1000 раз в секунду
 
          TIM2->ARR = 10 ;
          TIM2->CR1&=~TIM_CR1_ARPE;
          TIM2->SMCR|=TIM_SMCR_SMS|TIM_SMCR_ECE;;
          TIM2->SMCR&=~TIM_SMCR_MSM;
          TIM2->EGR&=~TIM_EGR_UG;
          TIM2->DIER |= TIM_DIER_UIE;//устанавливаем флаг 1по таймеру
          NVIC_EnableIRQ ( TIM2_IRQn  );
          TIM2->CR1|=   TIM_CR1_CEN;//разрешаем работу таймера
 
 
 
}
void inits_adc1(void)
{
    RCC->AHB2ENR |= RCC_APB2ENR_ADC1EN;
    ADC1->CR2 &= ~ ADC_CR2_EXTEN;//external trigger disconnection
      ADC1->SQR3  &= ~ ADC_SQR3_SQ1;//enable channel 0 first conversion //  right edge
      ADC1->CR2 |= ADC_CR2_CONT;// continuous conversion
      ADC1->CR2 |= ADC_CR2_ADON;//
}
//void adc_program(void)
//{
//   ADC1->CR2 |= ADC_CR2_SWSTART;
    //       while (!(ADC1->SR & ADC_SR_EOC)); //ждем пока первое преобразование завершится
    //               ADC1->SR &=~ ADC_SR_EOC;
    //                adc_data = ADC1->DR;
    //                //ADC1->SR = 0;
    //                if(adc_data > 2024)
        //            {
                        //  GPIOC->ODR|=1<<13;
                         // GPIOE->BSRR |= GPIO_BSRR_BS1;
             //         }
            //          else
               //       {
                        //  GPIOC->ODR&=~1<<13;
                        // GPIOE->BSRR |= GPIO_BSRR_BR1;
             //        }
//}
 
void inits_adc2(void)
{
 
}
 void inits_GPIOC(void)
 {
     RCC->AHB1ENR|=RCC_AHB1ENR_GPIOCEN;
 
 
          GPIOC->MODER &=~ GPIO_MODER_MODER13_1;
          GPIOC->MODER |= GPIO_MODER_MODER13_0;
          GPIOE ->OTYPER &=~GPIO_OTYPER_OT1;
          //бит0 определяет скорость работы GPIO
           GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR13_1; //бит1
           GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR13_0;
           GPIOC->PUPDR |=GPIO_PUPDR_PUPDR13_1;
           GPIOC->PUPDR &=~ GPIO_PUPDR_PUPDR13_0;
           /*     настройка на вход     */
 
         // RCC->AHB1ENR|=RCC_AHB1ENR_GPIOCEN;
 
          GPIOC->MODER &=~ GPIO_MODER_MODER0_1;
                  GPIOC->MODER &=~ GPIO_MODER_MODER0_0;
                  GPIOC ->OTYPER &=~GPIO_OTYPER_OT0;
                  //бит0 определяет скорость работы GPIO
                   GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR1_1; //бит1
                   GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR1_0;
                   GPIOC->PUPDR &=~ GPIO_PUPDR_PUPDR1_1;
                   GPIOC->PUPDR |= GPIO_PUPDR_PUPDR1_0;
 
 }
 void inits_GPIOA(void)
 {
     RCC->AHB1ENR|=RCC_AHB1ENR_GPIOAEN;
               GPIOA->MODER |= GPIO_MODER_MODER0_1;
             GPIOA->MODER |= GPIO_MODER_MODER0_0;
             GPIOA->PUPDR &=~GPIO_PUPDR_PUPDR0_1;
             GPIOA->PUPDR &=~ GPIO_PUPDR_PUPDR0_0;
 
 }
 
int main(void)
{
    inits_GPIOC();
    //inits_adc1();
    //inits_timer1();
    inits_timer2();
 
//   NVIC_EnableIRQ ( TIM2_IRQn  );
    while(1)
    {
        //ADC1->CR2 |= ADC_CR2_SWSTART; //Запуск преобразований
        //while (!(ADC1->SR & ADC_SR_EOC)); //ждем пока первое преобразование завершится
        //ADC1->SR = 0;
        //res = ADC1->DR;
         // GPIOC->ODR ^= GPIO_ODR_OD1;
        //GPIOC-> BSRR |=GPIO_BSRR_BS13;
            //    pauza(2000);
    }
}
вот исходник я любител вы профи меня интересует таймер 2 прерывания по выходу я проверял работают а вот по тайму не выходит.

Добавлено через 4 минуты
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*
 * main.c
 *
 *  Created on: 2 лист. 2019 р.
 *      Author: Ivan
 */
 
 
#include "main.h"
//#define TIM_EnableIT_UPDATE(TIMx) SET_BIT(TIMx->DIER, TIM_DIER_UIE)
//#define TIM_EnableCounter(TIMx) SET_BIT(TIMx->CR1, TIM_CR1_CEN)
//#define TIM_DisableCounter(TIMx) CLEAR_BIT(TIMx->CR1, TIM_CR1_CEN)
//#define  NVIC_EnableIRQ ( TIM2_IRQn  )
 volatile unsigned char flag=0;
 volatile unsigned char program=0;
 volatile unsigned char adc_data=0;
 volatile unsigned int pauza1=0;
 volatile unsigned int pauza2=0;
 void pauza (int T)//ввод самой паузы(программы) она написана отдельно и введеннием #include "paua.h"можно писать в основном цыкле pauza()с вводом целой переменной T
 {
    int i=0;//введение целойперемменой i
    char t=0;// введение вещественной переменной t считает такты микроконтролера
    for(i=0;i<T;t++) //програмама в цыкле
   {
    if(t==255)i=i+1;// условия одного цыкла счёта пределитель i определяется регистром TCCR2 определяется 0.1.2 битами это делителем частоты работы таймера
   }
 }
 void TIM1_IRQHandler(void)
 {
    // TIM1->DIER&=~TIM_DIER_UIE;
     TIM1->SR &= ~ TIM_SR_UIF;
     pauza1++;
     // if(pauza1>10)
           // {
                //  GPIOC-> BSRR |=GPIO_BSRR_BS13;
           //  }
          //   if(pauza1>20)
           //   {
                //  GPIOC-> BSRR |=GPIO_BSRR_BR13;
            //    pauza2=0;
              // }
 
     //  GPIOC->ODR ^= GPIO_ODR_OD1;
 }
void TIM2_IRQHandler(void)
{
    //TIM2->DIER&=~TIM_DIER_UIE;
    if(TIM2->SR& TIM_SR_UIF)
    {
     TIM2->SR &= ~ TIM_SR_UIF;
      pauza2++;
    //if(!(GPIOC->IDR& GPIO_IDR_ID0))
    //{
    //  pauza(20);
         if(pauza2>10)
         {
              GPIOC-> BSRR |=GPIO_BSRR_BS13;
         }
         if(pauza2>20)
          {
              GPIOC-> BSRR |=GPIO_BSRR_BR13;
              pauza2=0;
           }
    }
 }
 
 
 
void PROGRAM(void)
{
    //GPIOC-> BSRR |=GPIO_BSRR_BS1;
        //      pauza(2000);
        //     GPIOC-> BSRR |=GPIO_BSRR_BR1;
        //       pauza(2000);
}
void inits_timer1(void)
{
    RCC->APB2ENR |=RCC_APB2ENR_TIM1EN;
    NVIC_EnableIRQ (TIM1_UP_TIM10_IRQn   );
        TIM1->PSC = 2000-1;//24000 - 1; // Настраиваем делитель что таймер тикал 1000 раз в секунду
              TIM1->ARR = 10 ;
              TIM1->DIER |= TIM_DIER_UIE;//устанавливаем флаг 1по таймеру
              TIM1->CR1|= TIM_CR1_CEN;//разрешаем работу таймера
 
}
void inits_timer2(void)
{
    RCC->APB1ENR |=RCC_APB1ENR_TIM2EN;
 
    TIM2->PSC = 2400 - 1; // Настраиваем делитель что таймер тикал 1000 раз в секунду
 
          TIM2->ARR = 10 ;
          TIM2->CR1&=~TIM_CR1_ARPE;
          TIM2->SMCR|=TIM_SMCR_SMS|TIM_SMCR_ECE;;
          TIM2->SMCR&=~TIM_SMCR_MSM;
          TIM2->EGR&=~TIM_EGR_UG;
          TIM2->DIER |= TIM_DIER_UIE;//устанавливаем флаг 1по таймеру
          NVIC_EnableIRQ ( TIM2_IRQn  );
          TIM2->CR1|=   TIM_CR1_CEN;//разрешаем работу таймера
 
 
 
}
void inits_adc1(void)
{
    RCC->AHB2ENR |= RCC_APB2ENR_ADC1EN;
    ADC1->CR2 &= ~ ADC_CR2_EXTEN;//external trigger disconnection
      ADC1->SQR3  &= ~ ADC_SQR3_SQ1;//enable channel 0 first conversion //  right edge
      ADC1->CR2 |= ADC_CR2_CONT;// continuous conversion
      ADC1->CR2 |= ADC_CR2_ADON;//
}
//void adc_program(void)
//{
//   ADC1->CR2 |= ADC_CR2_SWSTART;
    //       while (!(ADC1->SR & ADC_SR_EOC)); //ждем пока первое преобразование завершится
    //               ADC1->SR &=~ ADC_SR_EOC;
    //                adc_data = ADC1->DR;
    //                //ADC1->SR = 0;
    //                if(adc_data > 2024)
        //            {
                        //  GPIOC->ODR|=1<<13;
                         // GPIOE->BSRR |= GPIO_BSRR_BS1;
             //         }
            //          else
               //       {
                        //  GPIOC->ODR&=~1<<13;
                        // GPIOE->BSRR |= GPIO_BSRR_BR1;
             //        }
//}
 
void inits_adc2(void)
{
 
}
 void inits_GPIOC(void)
 {
     RCC->AHB1ENR|=RCC_AHB1ENR_GPIOCEN;
 
 
          GPIOC->MODER &=~ GPIO_MODER_MODER13_1;
          GPIOC->MODER |= GPIO_MODER_MODER13_0;
          GPIOE ->OTYPER &=~GPIO_OTYPER_OT1;
          //бит0 определяет скорость работы GPIO
           GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR13_1; //бит1
           GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR13_0;
           GPIOC->PUPDR |=GPIO_PUPDR_PUPDR13_1;
           GPIOC->PUPDR &=~ GPIO_PUPDR_PUPDR13_0;
           /*     настройка на вход     */
 
         // RCC->AHB1ENR|=RCC_AHB1ENR_GPIOCEN;
 
          GPIOC->MODER &=~ GPIO_MODER_MODER0_1;
                  GPIOC->MODER &=~ GPIO_MODER_MODER0_0;
                  GPIOC ->OTYPER &=~GPIO_OTYPER_OT0;
                  //бит0 определяет скорость работы GPIO
                   GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR1_1; //бит1
                   GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR1_0;
                   GPIOC->PUPDR &=~ GPIO_PUPDR_PUPDR1_1;
                   GPIOC->PUPDR |= GPIO_PUPDR_PUPDR1_0;
 
 }
 void inits_GPIOA(void)
 {
     RCC->AHB1ENR|=RCC_AHB1ENR_GPIOAEN;
               GPIOA->MODER |= GPIO_MODER_MODER0_1;
             GPIOA->MODER |= GPIO_MODER_MODER0_0;
             GPIOA->PUPDR &=~GPIO_PUPDR_PUPDR0_1;
             GPIOA->PUPDR &=~ GPIO_PUPDR_PUPDR0_0;
 
 }
 
int main(void)
{
    inits_GPIOC();
    //inits_adc1();
    //inits_timer1();
    inits_timer2();
 
//   NVIC_EnableIRQ ( TIM2_IRQn  );
    while(1)
    {
        //ADC1->CR2 |= ADC_CR2_SWSTART; //Запуск преобразований
        //while (!(ADC1->SR & ADC_SR_EOC)); //ждем пока первое преобразование завершится
        //ADC1->SR = 0;
        //res = ADC1->DR;
         // GPIOC->ODR ^= GPIO_ODR_OD1;
        //GPIOC-> BSRR |=GPIO_BSRR_BS13;
            //    pauza(2000);
    }
}
я изеняюсь вот этот исходник там ошибки.
0
18 / 17 / 2
Регистрация: 29.03.2019
Сообщений: 234
18.12.2019, 10:00 7
Цитата Сообщение от Voland_ Посмотреть сообщение
Потом он сгенерит код (есть опция генерить в отдельном файле по всем перифериям) и вы увидите какие регистры нужно ставить.
Это он в CMSIS сгенерирует?
0
1778 / 1108 / 109
Регистрация: 04.01.2010
Сообщений: 3,885
18.12.2019, 12:09 8
ну там получится набор из HAL + CMSIS. Все в исходниках. То есть добрать до регистров - без проблем.
1
0 / 0 / 0
Регистрация: 15.12.2019
Сообщений: 53
18.12.2019, 21:23  [ТС] 9
Регистры те же только настраиваются по разному?

Добавлено через 34 минуты
Вообще я хотел бы что б вы показали кусок кода в генерации куда и в какую дырку смотреть.Я свой код показал и прошу учитела показать мне пример вы согласны со мной вы понимаете я еслиб увидел понял.Да и это касается не только таймера и всей перефирии.Я имею ввиду что она по другому настраивается.

Добавлено через 43 минуты
опция в кубе или в atolica studio?

Добавлено через 36 минут
если в кубе то я эти регистры прописывал и полный ноль
0
1778 / 1108 / 109
Регистрация: 04.01.2010
Сообщений: 3,885
18.12.2019, 23:41 10
если Вы конкретно меня спрашиваете, то я не знаю как Вам помочь, а в потоке сообщения выше - так вообще ничего не понял...

Что касается Cube, то он, конечно, сгенерит Вам тулчейн "api -> hal" по умолчанию. Каждую строчку инициализации функции, отвечающей за таймер, что вы ищете, придется от-трейсить от элементов структуры до регистров и выписать их последовательность. Это можно сделать, скажем, в любом IDE, например, в Eclipse или в VS Code - их тьма тьмущая доступных. Нужно только следить какие оффсеты имеются элементы структур HAL по отношению к регистрам. Они имеют близкие названия, но естесно, не совпадают по именам.

PS: я попробовал выкинуть файлы после препроцессора, добавив строчку в Makefile, там где генерятся *.o:
PowerShell
1
    $(CC) -c $(CFLAGS) -E -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $(@:.o=.i)
и в папке появились файлы с предпроцессингом, с разрешением ".i". Вот примерно что он выдает при компиляции (из огромного файла "main.i":
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static void MX_SPI1_Init(void)
{
# 182 "Core/Src/main.c"
  hspi1.Instance = ((SPI_TypeDef *)((0x40000000UL + 0x00010000UL) + 0x00003000UL));
  hspi1.Init.Mode = ((0x1UL << (2U)) | (0x1UL << (8U)));
  hspi1.Init.Direction = (0x00000000U);
  hspi1.Init.DataSize = (0x1UL << (11U));
  hspi1.Init.CLKPolarity = (0x00000000U);
  hspi1.Init.CLKPhase = (0x00000000U);
  hspi1.Init.NSS = ((0x1UL << (2U)) << 16U);
  hspi1.Init.BaudRatePrescaler = ((0x2UL << (3U)));
  hspi1.Init.FirstBit = (0x00000000U);
  hspi1.Init.TIMode = (0x00000000U);
  hspi1.Init.CRCCalculation = (0x1UL << (13U));
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
 
}
Исходник, до препроцессинга этой функции:
Кликните здесь для просмотра всего текста

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
static void MX_SPI1_Init(void)
{
 
  /* USER CODE BEGIN SPI1_Init 0 */
 
  /* USER CODE END SPI1_Init 0 */
 
  /* USER CODE BEGIN SPI1_Init 1 */
 
  /* USER CODE END SPI1_Init 1 */
  /* SPI1 parameter configuration*/
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */
 
  /* USER CODE END SPI1_Init 2 */
 
}


То есть расчетные значения видны сразу - остается только совместить поля структура Init с тем, как это используется в SPI_Init().

PS: SPI выбран в качестве примера - для таймера нужны другие настройки. Это я дернул пример на реальном проекте.
PPS: Cube поможет Вам изучить "на пальцах" реальные зависимости - от чьих настроек зависит работа таймера. Потому что просто включить таймер, и сразу работать с известными настройками - так не получится. Обычно в кортексах этому предшествует относительно обширная система настройки тактования. Как таймера, так и процессора вцелом. Поэтому, даже изучив полностью периферию таймера (а это не мало!) Вы скорее всего, не найдете даже однозначный ответ - на какой же частоте конкретно, она работает. Для этого нужно понять что от чего зависит, и что на что влияет. И куб для такого изучения замечательно подойдет, имхо.
0
0 / 0 / 0
Регистрация: 15.12.2019
Сообщений: 53
19.12.2019, 06:56  [ТС] 11
Вы хотите сказать что без организации системы тактирования в кортексах серии М4 и выше я не запущу таймер и др переферии?

Добавлено через 4 минуты
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
oid inits_timer3(void)
{
    //TIM3->CR1&=~  TIM_CR1_CEN;
      RCC->APB1RSTR|=RCC_APB1RSTR_TIM3RST;
     RCC->APB1RSTR&=~RCC_APB1RSTR_TIM3RST;
 
    //TIM3->CNT|= 0x00000000;
 
    TIM3->PSC|= (uint16_t)0x0000;
     TIM3->CR1&=~TIM_CR1_DIR;
    TIM3->ARR|= 0xFFFFFFFFU;
    TIM3->CR1&=~TIM_CR1_CKD;
    //TIM3->RCR|=0x0000;
     RCC->APB1RSTR&=~RCC_APB1RSTR_TIM3RST;
      RCC->APB1ENR |=RCC_APB1ENR_TIM3EN;
 
      NVIC_SetPriority(TIM3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
        NVIC_EnableIRQ(TIM3_IRQn);
 //TIM3->CR1&=~  TIM_CR1_CEN;
 
 
        TIM3->PSC|=3500 - 1; // Настраиваем делитель что таймер тикал 1000 раз в секунду
        TIM3->CR1&=~TIM_CR1_DIR;
        TIM3->ARR|= 10;
        TIM3->CR1&=~TIM_CR1_CKD;
        TIM3->CR1&=~TIM_CR1_ARPE;
        TIM3->SMCR|=TIM_SMCR_SMS|TIM_SMCR_ECE;
        TIM3->CR2|=TIM_CR2_MMS;
        TIM2->SMCR&=~TIM_SMCR_MSM;
        TIM3->DIER |= TIM_DIER_UIE;
 
 
       // NVIC_SetPriority(TIM3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
        //  NVIC_EnableIRQ(TIM3_IRQn);
         TIM3->CR1|=   TIM_CR1_CEN;
}
вот кусок кода в кубе LL я нашёл регистры записал.Я пытаюсь запустить таймер без организации системы тактирования пока не выходит. Где ошибка?
0
Модератор
8195 / 6067 / 809
Регистрация: 14.02.2011
Сообщений: 21,034
19.12.2019, 07:04 12
ivan rusev, последний раз предупреждаю, дальше буду наказывать, ставьте тэги для кода

Цитата Сообщение от ivan rusev Посмотреть сообщение
TIM3->PSC|= (uint16_t)0x0000;
что это? и к чему приведет? и такие куски по всему коду

Добавлено через 1 минуту
Цитата Сообщение от ivan rusev Посмотреть сообщение
TIM3->ARR|= 0xFFFFFFFFU;
????????????
1
1778 / 1108 / 109
Регистрация: 04.01.2010
Сообщений: 3,885
19.12.2019, 12:26 13
Цитата Сообщение от ivan rusev Посмотреть сообщение
Вы хотите сказать
Нет, я не это сказал.
Кстати,
C
1
2
     RCC->APB1RSTR|=RCC_APB1RSTR_TIM3RST;
     RCC->APB1RSTR&=~RCC_APB1RSTR_TIM3RST;
Такие конструкции МОГУТ не работать ( а могут и работать ). Это связано с асинхронностью шины клока таймера и процессора. Процессор может выполнить две инструкции за два своих такта, когда как более медленная шина APB1 (если она так настроена) - может не успеть "заметить" этот импульс.
0
22 / 22 / 5
Регистрация: 18.03.2010
Сообщений: 329
19.12.2019, 19:10 14
Такие конструкции МОГУТ не работать ( а могут и работать ). Это связано с асинхронностью шины клока таймера и процессора. Процессор может выполнить две инструкции за два своих такта, когда как более медленная шина APB1 (если она так настроена) - может не успеть "заметить" этот импульс.
А вот это интересно, но как же решать сложившуюся проблему, которую Вы описали? Будет полезна данная информация.
0
0 / 0 / 0
Регистрация: 15.12.2019
Сообщений: 53
19.12.2019, 21:53  [ТС] 15
Ребята всё это я нарыл с HAL вот код
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void MX_TIM3_Init(void)
{
  LL_TIM_InitTypeDef TIM_InitStruct = {0};
 
  /* Peripheral clock enable */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);
 
  /* TIM3 interrupt Init */
  NVIC_SetPriority(TIM3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
  NVIC_EnableIRQ(TIM3_IRQn);
 
  TIM_InitStruct.Prescaler = 3500;
  TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
  TIM_InitStruct.Autoreload = 10;
  TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
  LL_TIM_Init(TIM3, &TIM_InitStruct);
  LL_TIM_DisableARRPreload(TIM3);
  LL_TIM_SetClockSource(TIM3, LL_TIM_CLOCKSOURCE_INTERNAL);
  LL_TIM_SetTriggerOutput(TIM3, LL_TIM_TRGO_RESET);
  LL_TIM_DisableMasterSlaveMode(TIM3);
 
}
LL_TIM_InitTypeDef TIM_InitStruct = {0}; вот эта строчка меня заинтересовала.

Добавлено через 5 минут
C
1
2
RCC->APB1RSTR|=RCC_APB1RSTR_TIM3RST;
     RCC->APB1RSTR&=~RCC_APB1RSTR_TIM3RST;
и это есть в хале

Добавлено через 1 час 24 минуты
Что такое теги я не русский я не понимаю.Если не хотите отвечать не отвечайте.Форум итак мёртвый
0
1778 / 1108 / 109
Регистрация: 04.01.2010
Сообщений: 3,885
19.12.2019, 23:50 16
Цитата Сообщение от GaFBich Посмотреть сообщение
А вот это интересно, но как же решать сложившуюся проблему, которую Вы описали?
Обычно решается NOP'ами ). В крайних случаях оборачивается паузами ожидания какого-нить статуса.

Не по теме:

PS: я с такой проблемой столкнулся при работе с RTC (или еще какой-то низкочастотной периферией). В STM32F1 он тактируется либо внутренним 40кГц, либо внешним - тоже низкой частоты. В итоге иногда бывало, что надо ЖДАТЬ переключение состояния таймера, потому что он не поспевал. Ситуация обычно усугубляется еще и тем, что FLASH имеет Wait-state'ы, а еще есть pipeline кортекса, а еще есть Prefetch... Так что комбинация кода, которую накомпилит компилятор напрямую влияет на результат. В одном случае, где-то Wait-stat'е придержат код, где-то прерывание, где-то pipe-line перегружается - и задержка в результате есть. А в другом случае компилятор так оптимизирует код, что паузы почти нет, и периферия может не успеть.

0
0 / 0 / 0
Регистрация: 15.12.2019
Сообщений: 53
26.12.2019, 21:28  [ТС] 17
voland вы не можете показать работающий код на cmsis настройки ацп в STM32f407

Добавлено через 4 минуты
или и это секрет?
0
0 / 0 / 0
Регистрация: 15.12.2019
Сообщений: 53
22.07.2020, 22:02  [ТС] 18
пользуюсь кнопками все кнопки нажимаю результат получаю.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.07.2020, 22:02

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

CMSIS-DAP
Кто-нибудь пробовал ? У меня в Keil проходит 50% программирование и останавливается....

Вопрос о CMSIS
Здравствуйте ! В CMSIS запись в регистры делается так: 0x40010C10 адрес GPIOB_BSRR...

CMSIS, TIM6 и DMA1
На плате F429Dyscovery настроил TIM6 чтоб генерил реквесты к DMA1 Stream1 Channel7, согласно...

openocd + cmsis-svd
В openocd, кроме встроенного gdb сервера, есть также встроенные telnet сервер и скриптовый язык...


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

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

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