Jump to content
Тимур1992

STM32F1 проблемы с приемом по UART

Recommended Posts

Доброго времени суток.

Решил пробудить свои скилы по написанию программ под stm32f103. Поигрался с SMT32CUDEMX и HAL, но вернулся к SLP библиотеке.  Начал постепенно наращивать программу по примерам, начиная с GPIO, тактирования и на работе c USART встал. Суть в том что передача по UART идет нормально, а вот прием приводит к "зависанию". Устанавливая бесконечные while с мигалками внутри, я выяснил что по все видимости МК не переходит в прерывания USART1_IRQHandler. Я не могу понять в чем ошибка, раньше с таким не сталкивался, хотя написал несколько программ для stm32f100 .____.

Среда разработки Atollic TrusStudio 9.0.0.

 

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_usart.h"
#include "misc.h"
#include <string.h>
// тактовый светодиод для индикации
#define LED GPIO_Pin_5
#define RX_BUF_SIZE 80
volatile char RX_FLAG_END_LINE = 0;
volatile char RXi;
volatile char RXc;
volatile char RX_BUF[RX_BUF_SIZE] = {'\0'};
volatile char buffer[80] = {'\0'};

void init_GPIO(void);
void SetSysClockTo72(void);
void init_uart(void);
void clear_RXBuffer(void);
void USARTSend(const char *pucBuffer);


void USART1_IRQHandler(void) {
	GPIO_ResetBits(GPIOA, LED);
	//GPIOA->ODR ^= LED;
	//USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
	//if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
    //if ((USART1->SR & USART_FLAG_RXNE) != RESET) {
	//if ((USART1->SR & USART_SR_RXNE) != (u16)RESET) {
	if (USART1->SR & USART_SR_RXNE) {

			// Сбрасываем флаг прерывания

		    USART1->SR &=~ USART_SR_RXNE;
            //RXc = USART_ReceiveData(USART1);

            //RX_BUF[RXi] = RXc;
            //RXi++;

            //if (RXc != 13) {
            //    if (RXi > RX_BUF_SIZE-1) {
            //        clear_RXBuffer();
            //    }
            //}
            //else {
            //    RX_FLAG_END_LINE = 1;
            //}

            //Echo
            //USARTSend("Interrapt_UART1\r\n");
            //USART_SendData(USART1, RXc);
    }
	//return
}


int main(void) {
	int i;
	//SetSysClockTo72();
	init_GPIO();
	init_uart();
	USARTSend("Test USART1\r\n");

	while (1) {

		//if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9) != 0) {
			/* Toggle LED which connected to PC13*/
			GPIOA->ODR ^= LED; // Invert C13

			/* delay */
			for(i=0;i<0x100000;i++);

			/* Toggle LED which connected to PC13*/
			GPIOA->ODR ^= LED;

			/* delay */
			for(i=0;i<0x100000;i++);
			USARTSend("Test USART1\r\n");
		//}
		//else {
			//GPIO_SetBits(GPIOA, LED);
		//}
	}
}

void init_GPIO(void) {
	// Создаем класс для постепенной настройки параметров и единовременного применени¤
	GPIO_InitTypeDef GPIO_InitStructure;

	//Настрайваем светодиод, включаем тактирование GPIOA
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	// Конфигурация для светодиода, режим работы, максимальная скорость
	GPIO_InitStructure.GPIO_Pin = LED;
	// GPIO_Mode_Out_OD выход с открытым стоком, GPIO_Mode_Out_PP выход двумя состояниями
	// GPIO_Mode_AF_OD выход с открытым стоком для альтернативных функций, GPIO_Mode_AF_PP то же самое, но с двумя состояниями
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	// Устанавливаем начальное значение SetBits -> High level ("1"), ResetBits -> Low level ("0")
	GPIO_ResetBits(GPIOA, LED);

	// Настрайваем пин 9, регистра B на вход, для отладки, включаем тактирование регистра B
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	// Настрайваем для кнопку, пин, режим, максимальная частота входного сигнала
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	// GPIO_Mode_AIN аналоговый вход, GPIO_Mode_IN_FLOATING вход без подтяжки, болтающийся
	// GPIO_Mode_IPD вход с подтяжкой к земле, GPIO_Mode_IPU вход с подтяжкой к питанию
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}


void SetSysClockTo72(void) {
	ErrorStatus HSEStartUpStatus;
	/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration -----------------------------*/
    /* Системный RESET RCC (делать не обязательно, но полезно на этапе отладки) */
    RCC_DeInit();

    /* Включаем HSE (внешний кварц) */
    RCC_HSEConfig( RCC_HSE_ON);

    /* Ждем пока HSE будет готов */
    HSEStartUpStatus = RCC_WaitForHSEStartUp();

    /* Если с HSE все в порядке */
    if (HSEStartUpStatus == SUCCESS) {

        /* HCLK = SYSCLK */ /* Смотри на схеме AHB Prescaler. Частота не делится (RCC_SYSCLK_Div1) */
        RCC_HCLKConfig( RCC_SYSCLK_Div1);

        /* PCLK2 = HCLK */ /* Смотри на схеме APB2 Prescaler. Частота не делится (RCC_HCLK_Div1)  */
        RCC_PCLK2Config( RCC_HCLK_Div1);

        /* PCLK1 = HCLK/2 */ /* Смотри на схеме APB1 Prescaler. Частота делится на 2 (RCC_HCLK_Div2)
        потому что на выходе APB1 должно быть не более 36МГц (смотри схему) */
        RCC_PCLK1Config( RCC_HCLK_Div2);

        /* PLLCLK = 8MHz * 9 = 72 MHz */
        /* Указываем PLL от куда брать частоту (RCC_PLLSource_HSE_Div1) и на сколько ее умножать (RCC_PLLMul_9) */
        /* PLL может брать частоту с кварца как есть (RCC_PLLSource_HSE_Div1) или поделенную на 2 (RCC_PLLSource_HSE_Div2). Смотри схему */
        //RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
        RCC_PLLConfig(0x00010000, RCC_PLLMul_9);

        /* Включаем PLL */
        RCC_PLLCmd( ENABLE);

        /* Ждем пока PLL будет готов */
        while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {
        }

        /* Переключаем системное тактирование на PLL */
        RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK);

        /* Ждем пока переключиться */
        while (RCC_GetSYSCLKSource() != 0x08) {
        }
    }
    else {
    	/* Проблемы с HSE. Тут можно написать свой код, если надо что-то делать когда микроконтроллер не смог перейти на работу с внешним кварцом */

        /* Пока тут заглушка - вечный цикл*/
        // while (1) {
        //}
    }
}

void init_uart(void) {
    /* Enable USART1 and GPIOA clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);

    /* Configure the GPIOs */
    GPIO_InitTypeDef GPIO_InitStructure;

    /* Configure USART1 Tx (PA.09) as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Configure USART1 Rx (PA.10) as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Configure the USART1 */
    USART_InitTypeDef USART_InitStructure;

    /* USART1 configuration ------------------------------------------------------*/
    /* USART1 configured as follow:
        - BaudRate = 115200 baud
        - Word Length = 8 Bits
        - One Stop Bit
        - No parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
        - USART Clock disabled
        - USART CPOL: Clock is active low
        - USART CPHA: Data is captured on the middle
        - USART LastBit: The clock pulse of the last data bit is not output to
            the SCLK pin
     */
    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_Init(USART1, &USART_InitStructure);

    /* Enable USART1 */
    USART_Cmd(USART1, ENABLE);

    /* Enable the USART1 Receive interrupt: this interrupt is generated when the
    USART1 receive data register is not empty */
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    /* NVIC Configuration */
    NVIC_InitTypeDef NVIC_InitStructure;
    /* Enable the USARTx Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    //NVIC_EnableIRQ(USART1_IRQn);
}

void clear_RXBuffer(void) {
    for (RXi=0; RXi<RX_BUF_SIZE; RXi++)
        RX_BUF[RXi] = '\0';
    RXi = 0;
}

void USARTSend(const char *pucBuffer) {
    while (*pucBuffer) {
        USART_SendData(USART1, *pucBuffer++);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {
        }
    }
}

 

Share this post


Link to post
Share on other sites
2 hours ago, Тимур1992 said:

/* Enable USART1 */ USART_Cmd(USART1, ENABLE);

Попробуй перенести в конец, после инициализации NVIC.

Сейчас при разрешении USART сразу происходит прерывание, а NVIC не инициализирован.

Share this post


Link to post
Share on other sites

Изготовление 2-х слойных плат от 2$, а 4-х слойных от 5$!

Быстрое изготовление прототипа платы всего за 24 часа! Прямая доставка с нашей фабрики!

Смотрите видео о фабрике JLCPCB: https://youtu.be/_XCznQFV-Mw

Посетите первую электронную выставку JLCPCB https://jlcpcb.com/E-exhibition чтобы получить купоны и выиграть iPhone 12, 3D-принтер и так далее...

@Тимур1992 Я вот бегло почитал эту страшную мешанину, но так и не нашел того места, где у тебя происходит, собственно, запуск порта на прием. А сам порт включаться не умеет и никакого прерываний естественно не вызовет

у тебя в папке документов есть папка куба. Там лежат примеры работы со всеми портами в разных режимах. Очень просто и понятно написанные. Твой случай там тоже есть, прям один в один как надо. Прочитай для начала, потом спроси, если что не ясно будет.

Edited by mail_robot

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

Share this post


Link to post
Share on other sites

Высокая надежность SiC! Как они этого добились?

За несколько лет кропотливых исследований и совершенствования технологии компания Infineon смогла довести показатели надежности и стабильности параметров высоковольтных и быстродействующих карбид-кремниевых транзисторов линейки CoolSiC практически до уровня их кремниевых собратьев.

Подробнее

11 час назад, snn_krs сказал:

Попробуй перенести в конец, после инициализации NVIC.

Попробовал не помогло.

Share this post


Link to post
Share on other sites

Вебинар «Практическое использование TrustZone в STM32L5»(10.12.2020)

Приглашаем на вебинар, посвященный экосистеме безопасности и возможностях, которые появились у разработчиков благодаря новой технологии TrustZone в микроконтроллерах STM32L5. Программа рассчитана на технических специалистов и тех, кто уже знаком с основами защиты ПО в STM32.

Подробнее

без запуска приема бесполезно тут чтото переставлять


Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

Share this post


Link to post
Share on other sites

Снижена цена на AC/DC и DC/DC преобразователи Mornsun в Компэл!

Компэл и компания Mornsun снизили цены на преобразователи AC/DC-преобразователи семейств LS и LDE. По привлекательной цене также предлагаются DC/DC-преобразователи изолированных семейств поколений R2 и R3 различного конструктивного исполнения.

Подробнее

Спасибо все, кто отозвался. Проблема оказалась очень простой - я кретин. Когда я создавал проект, я подумал: хм... круто же и функционально писать код на си++. Вообщем код постоянно попадал в функцию NMI_Handler. Но не суть, когда я создал проект на чистом си, и скопировал туда свои код, то почти все сразу завелось! :D

Вообщем, на обратную совместимость надейся, а сам не плошай ХD

Share this post


Link to post
Share on other sites

@Тимур1992 обрамляй прерывание

#ifdef __cplusplus
 extern "C" {
#endif


void xxx_IRQHandler(void)
{
}

#ifdef __cplusplus
}
#endif

и тогда обработчики станут видны в С++

И бросай SPL, на регистрах USART не сложно запустить

Share this post


Link to post
Share on other sites

Кину свой вопрос сюда, сколько не пытался по ЮАРТу принять данные через прерывания через HAL и регистры, ничего не работает, что не так делаю? Без прерывания работает, скорость 250000

void UART1_Init(){
     
  RCC->APB2ENR|= RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN;
  GPIOA->CRH &= !GPIO_CRH_CNF9;
  GPIOA->CRH  |= GPIO_CRH_CNF9_1 | GPIO_CRH_MODE9_0 | GPIO_CRH_CNF10_0;
  USART1->BRR = 0x120;
  USART1->CR1 |= USART_CR1_TE | USART_CR1_RE;
  USART1->CR1 |= USART_CR1_UE;
  USART1->CR1 |= USART_CR1_RXNEIE;
 
  NVIC_EnableIRQ(USART1_IRQn);
  __enable_irq ();

}
 

void USART_IRQHandler(void)
{
     // Выясняем, какое именно событие вызвало прерывание. Если это приём байта в RxD - обрабатываем.
if (USART1->SR & USART_SR_RXNE) {
   

    // Получаем принятый байт
      data30=USART1->DR;

if(data30==1){
  jk++;
}
else if(data30==2){
  jk--;
}
 if(data30==3){
  nj++;

}
else if(data30==4){
  nj--;
}

// Сбрасываем флаг прерывания
    USART1->SR&=~USART_SR_RXNE; }

 

Edited by Электронщик

Share this post


Link to post
Share on other sites

А в чем "не работа" выражается? Не запускается прерывание, или запускается но не читаются данные, или еще что-то?

Ну и тут логическое отрицание нужно на побитовую инверсию заменить:

GPIOA->CRH &= !GPIO_CRH_CNF9;

 

Share this post


Link to post
Share on other sites

в случае с ХАЛ надо весь код смотреть. Те куски что у вас, рабочие, но контекст не понятен.


Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

Share this post


Link to post
Share on other sites
А в чем "не работа" выражается? Не запускается прерывание, или запускается но не читаются данные, или еще что-то?

Не запускается прерывание, так как пробовал отслеживать флажок при входе в прерывание, он не взводится когда я присылаю какие-либо - данные, причем отладчиком все регистры настроены как нужно.

Камень f103C8T6, заметил с ним много проблем, выяснил что SPI2 почему-то не работает, или работает иногда, а одновременно два настроенных SPI не работают, причем как HAL так и регистрами. Может то что беру эти камни с платкой за 65-85грн., может это ширпотреб

Edited by Электронщик

Share this post


Link to post
Share on other sites

для начала надо почитать код примеров, который лежит в папке c:\пользователи\[user]\STM32Cube\Repository\[lib]\Projects\и там по смыслу

Это применительно к ХАЛ. По вашему вопросу там как раз код есть. Очень подробно и качественно прокомментированный. Код 100% рабочий. Посмотрите внимательно как там происходит инициализация, запуск приема по прерываниям и как прописан обработчик. имхо - вам надо не обработчик курочить, а колбэк на предмет парсинга байта. И вообще лучше это делать по ДМА

Edited by mail_robot

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

Share this post


Link to post
Share on other sites
void USART_IRQHandler(void)
{
 
data30=2;
if (USART1->SR & USART_SR_RXNE) {
   
    // Получаем принятый байт
      data31=USART1->DR;
  
USART1->SR&=~USART_SR_RXNE; 
}
}

Сейчас так вот написал, чтобы понять срабатывает ли прерывание, если какие-нибудь данные придут в приемник, должен я провалиться в обработчик прерываний USART_IRQHandler, и data30 станет равна 2, соответсвено зажигаю светик в основном цикле, но этого не происходит

Вот после инициализации, как проверить в реальном времени флаг RXNE, отладчиком я не знаю

Screenshot_1.thumb.jpg.3af98a3202fd0d68f1d302b5cb9d3954.jpg

Edited by Электронщик

Share this post


Link to post
Share on other sites

Может так: USART1_IRQHandler IDE какая? покажи стартап

ну как проверить послал байт, нажал на паузу и смотришь и точку останова в обработчик

я сейчас как раз пример буду делать по USART

Share this post


Link to post
Share on other sites

Я и с DMA вчера игрался для UART ничего не работает, кто-то скажет нужно, или регистры или HAL использовать, одновременно нельзя, но так то удобнее, особенно когда по регистрам не настраивается, взял HAL, я таким образом в ардуино ИДЕ, писал на С + иногда функции writing, быстро и удобно, и никаких конфликтов.

Share this post


Link to post
Share on other sites

В ардуино ИДЕ быстро можно набросать как по регистрам, так и используя функции ардуино, удобнее чем в codevision, и когда нужно быстро для проверки, то нормально, а дальше потом можно перевести все на регистры.

Исправил, но все равно не то, если оно и с HAL не работает, и по регистрам, может чистый проект сделать и в нем попробовать. Мало ли что там куб наворотил, или я где-то что - то.

Share this post


Link to post
Share on other sites

думаю второе

и не натворил, а недотворил скорее ) Выкладывал бы уже весь код

Edited by mail_robot

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

Share this post


Link to post
Share on other sites

Набросал по быстрому, правда тактирование самого проца оставил в кубе, но думаю это не влияет, и вот ничего

Скрытый текст

/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  ** This notice applies to any and all portions of this file
  * that are not between comment pairs USER CODE BEGIN and
  * USER CODE END. Other portions of this file, whether 
  * inserted by the user or by software development tools
  * are owned by their respective copyright owners.
  *
  * COPYRIGHT(c) 2018 STMicroelectronics
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f1xx_hal.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  *
  * @retval None
  */
void GPIOs(){
 RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;//|RCC_APB2ENR_AFIOEN;//включаем тактирование GPIO

GPIOB->CRH |= (GPIO_CRL_MODE4_1);// настроены на 2МГц 
}





void UART1_Init(){
     
  RCC->APB2ENR|= RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN;
  GPIOA->CRH &= ~GPIO_CRH_CNF9;
  GPIOA->CRH  |= GPIO_CRH_CNF9_1 | GPIO_CRH_MODE9_0 | GPIO_CRH_CNF10_0;
  USART1->BRR = 0x120;//250000
  USART1->CR1 |= USART_CR1_TE | USART_CR1_RE;
  // Запускаем модуль USART
  USART1->CR1 |= USART_CR1_UE;
  
  USART1->CR1 |= USART_CR1_RXNEIE;

  // Назначаем обработчик для всех прерываний от USART1
  NVIC_EnableIRQ(USART1_IRQn);
  NVIC_SetPriority (USART1_IRQn, 2);

  __enable_irq ();

}

uint8_t nj=0;
uint8_t data30=0;

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
 // MX_GPIO_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */
GPIOs();
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
   
  while (1)
  {
if(nj==1){
 GPIOB->BSRR = GPIO_BSRR_BS4;
}
else if(nj==0){
 GPIOB->BSRR = GPIO_BSRR_BR4;
}

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */

}

/**
  * @brief System Clock Configuration
  * @retval None
  */

void USART_IRQHandler(void)
{
 
  // Выясняем, какое именно событие вызвало прерывание. Если это приём байта в RxD - обрабатываем.
if (USART1->SR & USART_SR_RXNE) {
   
    // Получаем принятый байт
      data30=USART1->DR;
  

 if(data30==3){
  nj++;

}
else if(data30==4){
  nj--;
}
    


USART1->SR&=~USART_SR_RXNE; 
}
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure the Systick interrupt time 
    */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

    /**Configure the Systick 
    */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

/** Configure pins as 
        * Analog 
        * Input 
        * Output
        * EVENT_OUT
        * EXTI
*/
static void MX_GPIO_Init(void)
{

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @param  file: The file name as string.
  * @param  line: The line in file as a number.
  * @retval None
  */
void _Error_Handler(char *file, int line)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  while(1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/**
  * @}
  */

/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

 

Этот код работает без прерываний, но по сути ничего не меняется. 

Edited by Электронщик

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Сообщения

    • Вот это есть максимальное напряжение - без него никуда.
    • выставлю то напряжение, до которого должен будет заряжаться конденсатор, тогда, например, при заряде стабильным током, можно будет получить время (тогда отношение времени заряда к паузе (во время паузы - разряд до нуля), будет определять ток который будет прямо пропорционален ёмкости, который можно измерить миллиамперметром, я встречал схемы измерителей ёмкости и индуктивности построенных на таком принципе). дельты - это не сомножители, а значки, их нельзя сократить.
    • Послушай Ёмкость - это количество заряда к напряжению.    Вверху есть формула - там для дураков написано.  Дельты сокращаем.  И получается чистый заряд на напряжение.   Это строгая формула.   А без сокращения более простая.  Там не написано дельта 1 и дельта 2 ,  это абсолютно одинаковые дельты.  Их написали чтобы более широко проилюстрировать процесс.    А можно и без них.   Просто формулу сделали более развёрнутую.
    • Это глупость, ты смешиваешь в кучу ЗАРЯД  конденсатора и его ЁМКОСТЬ, а это разные вещи. Если налить в ведро 5 литров воды, то ёмкость ведра так и останется 10 литров, а "заряд" в нём будет 5.
    • Выставишь пороговое - то есть макс.(я правильно понял)? Правильнее сказать что разные величины порогового напряжения при одном алгоритме измерения будут по разному влиять на результат.    Мы это уже и математически доказали и по всякому.    Ну что ты споришь?
    • нет не будет, ёмкость будет получатся одна и та же   выставив пороговое напряжение для компаратора, если буду задаваться напряжением, или длительностью (время) импульса заряда, если буду задаваться временем.
    • Транзистор открывается когда через переход база - эмиттер протекает ток. А коллектор - эмиттер при этом как бы замыкаются между собой. Когда на входе "4,5 вольта" есть напряжение, первый транзистор открыт, весь ток от R2 через КЭ транзистора уходит на минус и второму транзистору ничего не достаётся, он закрыт, лампа не горит. Когда напряжение пропадает, первый транзистор закрывается, в базу второго транзистора поступает ток через R2, он открывается и лампа горит. То есть, первый транзистор как раз инвертирует входной сигнал.

  • Миниатюрная электромагнитная защелка скрытой установки с RFID считывателем

  • Similar Content

    • By xrou
      Здравствуйте, пытаюсь подключить USB флешку к STM32F767ZI
       
      Включаю USB_OTG_FS - host only, (V bus и SOF  не включаю), USB HOST Class for fs ip - Mass Storage host class, FATFS (USE_LFN - в стеке) - USB_Disk
      В настройках USB_HOST требует, как я понял, пин отвечающий за питание устройства - PC1
      Код простейший, должен работать 100% а может нет. Внутренние файлы библиотек не менял
      Думаю что нет питания на USB устройство т.к. пробовал вставить туда ttl конвертер на котором есть светодиод питания и он не горит
       
      Ваши идеи и предположения? 
       
    • By xrou
      Здравствуйте, хочу подключить джойстик к stmке, но проблема в том что он пятивольтовый, а АЦП все, что больше 3.3 выдаёт как 4095. На ардуино есть контакт aref введённый на плату, но на stm, как я понял, он соединён с контактом питания и все что выше 3.3 вольта просто спалит кристал. 
      Подскажите как подключить пятивольтовое устройство к stmке. 
       
      P.s подключить джойстик к 3.3 не получится из-за появления огромных мёртвых зон.
    • By Black Jack
      Здравствуйте, программатор st-link не видит микроконтроллер STM32F103VET6. Присоединение кварца и внешнее тактирование не помогли. Что не так делаю, подскажите.


      схема.dch плата.dip
    • By strifonoff
      это снова я...
      Максимального быстродействия АЦП можно достичь при частоте АЦП 14 МГц, а этого можно добиться только при системной частоте 56 МГц (если внешний кварц на 8 МГц).
      Но возникает проблема со скоростями UART: значение регистра BRR не получится выставить так, что бы скорость была из стандартного ряда.
      Назрели несколько вопросов:
      1) возможно ли менять системную частоту на лету? (чую, что можно, но пока не знаю как) 
      2) критична ли ошибка в скорости UART по сравнению со стандартной? (что будет на другой стороне заранее не известно, т.к. любой может воткнуть свой девайс работающий на какой-то заранее согласованной стандартной скорости)
      3) как поведёт себя железо (состояние ОЗУ, регистров перефирии, состояние ног и т.д.) на изменение частоты? Две части программы () практически независимы, их объединяет только один массив, который наполняется в первой половине, а обрабатывается в другой.
       
    • By xrou
      Здравствуйте, пытаюсь обрабатывать пакеты приходящие от ESP8266 (01), но проблема в том, что пакеты всегда разной длины ведь мы не знаем, что напишет пользователь (хотя даже ответы на AT команды всегда разной длины). Знаю, что в плате F0 есть прерывание по символу, но у меня F103C8T6. Как быть? Создать массив большого размера нельзя, т.к. HAL_Recieve_IT ждет пока не наберется нужное кол-во символов.
      Приму любую идею и советы
×
×
  • Create New...