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

Вебинар "Новый BlueNRG-LP с Bluetooth 5.2 и Long Range — волшебная палочка разработчика IoT" (04/02/2021)

Приглашаем 4 февраля на бесплатный вебинар о BlueNRG-LP - новой системе-на-кристалле (SoC) STMicroelectronics. На вебинаре будут детально рассмотрены функциональные блоки, особенности подключения, аппаратные и программные средства для разработки, настройка сценариев с помощью BlueNRG-GUI, практические примеры работы с микросхемой, а также примеры применения BlueNRG-LP в устройствах интернета вещей.

Подробнее

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

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

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

Share this post


Link to post
Share on other sites

Новые компактные конденсаторы Panasonic серии TPS. Закаленный характер.

Panasonic представил новую серию TPS твердотельных танталовых конденсаторов с проводящим полимером для поверхностного монтажа. Конденсаторы серии TPS обладают уникальными особенностями, что делает их отличным выбором для использования в приложениях с высокими требованиями.

Подробнее

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


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

Share this post


Link to post
Share on other sites

SiC MOSFET на 1200 В для схем флайбэк до 500 Вт!

Компания Wolfspeed выпустила новые карбид-кремниевые транзисторы C3M0350120D/J на 1200 В, предназначенные для маломощных устройств мощностью до 500 Вт. Карбид-кремниевые транзисторы в сравнении с кремниевыми демонстрируют меньший на 75% уровень потерь на переключение и меньшее на 50% значение потерь проводимости в рабочем режиме при температуре кристалла 100…150°С.

Подробнее

Спасибо все, кто отозвался. Проблема оказалась очень простой - я кретин. Когда я создавал проект, я подумал: хм... круто же и функционально писать код на си++. Вообщем код постоянно попадал в функцию 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к вк стоят неподходящие. В 1 к вк вообще с нулевым запасом по напряжению. 
    • Рдиатор. Размер 45мм на 45мм, расстояние между отверстиями - 62 мм. Возможно чуть меньше, 61,8, или 61,7 Отдам. Вот ради интереса. Вдруг нужен кому, а у меня валяется. Условия - передам в метро (мск). Могу быть там не всегда, интерес в личку.  
    • Q2 должен быть составной, и на последних моделях нет резисторов подтяжки базы (затвора) на +12V и на -12V.
    • @GeKo Извините, что долго не отвечал, последнее время редко на форум захожу. DIP и TQFP корпуса для ATmega8/48/88 отличаются только отсутствием/наличием двух доп. входов АЦП для DIP/TQFP соответственно. Они в моей схеме не задействованы. Так что можно и в DIP корпусе использовать МК.
    • Но все же, я не уверен, что он забыл, потому и улыбка.
    • Это не мои, и не у меня. У меня есть личные советские механические, и в наследство осталось механические современные. По логике это не подходит. Весы как стояли на полу, так и стоят. Как были пустые, так и остались. Да и магазинные весы автоматически обнулятся, если поставить пустую тару и кнопкой обнулить. То есть сами подстраиваются под вес пустой тары, отвёрточкой крутить ничего не нужно настраивать. А почему тогда первое включение без глюка, последующие за ним с глюком? Если через 5 минут, то снова первое норм, последующие подряд не норм.
    • Оконечник там по топологии цирклотрона выполнен с хитровыкрученным китайским драйвером на входе. Нагрузка подключается между однополярными плечами двух независимых питающих выпрямителей. Можно поэкспериментировать с резистивной нагрузкой для начала, чтобы понять, держит ли ОБР и насколько греются радиаторы.

  • Усилитель мощности MX50 SE, 2 канала, 100 Ватт. Собранный или в виде DIY-набора для самостоятельной сборки

  • Similar Content

    • By Стальной
      Доброго времени суток!
      Неделю не могу запустить DCMI на STM32F407VET6. 
      Работаю через HAL, инициализация кубом. К МК подключена камера OV7670. Камера дает картинку 640х480, и такое изображение мне негде хранить. Поэтому через фичу CROP хочу вырезать картинку 160х128 из центра под имеющийся экран.
      Ниже примерный код, без настройки камеры. Камера тактируется от 16 МГц MCO. Сигналы поступают на выводы МК, посмотрел осциллографом. У камеры есть некоторые настройки, которые тут в коде не показал, так как они влияют только на представление данных, но не на алгоритм захвата данных.
      /* USER CODE BEGIN PV */ uint16_t DCMI_data[20480] = {0}; //128*160=20480 words uint32_t ptr; /* USER CODE END PV */ //тут еще код куба, пропущу его 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(); MX_DMA_Init(); MX_DCMI_Init(); /* USER CODE BEGIN 2 */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET); //снять ресет с матрицы ptr = (uint32_t)(&DCMI_data[0]); HAL_Delay( 500 ); //начать резать с 512 клока строки (256 пиксель), начать резать с 160 строки //захватить 256 клоков (128 пикселей), захватить 160 строк HAL_DCMI_ConfigCrop(&hdcmi, 512, 160, 256, 160); HAL_DCMI_EnableCrop(&hdcmi); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_SNAPSHOT, ptr, 10240); //однократный захват, 10240 тетрад, 20480 слов, 160*128=40960 пикселей HAL_Delay(1500); } /* USER CODE END 3 */ } В результате в буфере ничего не появляется, DMA туда ничего не кладёт, проверил. Если не вызывать функцию EnableCrop, но какие-то данные появляются, но на экран их корректно отобразить не получается. Также пытался в камере обрезку включить, а не в МК - снова нет данных. Пробовал разные частоты тактирования матрицы давать - без разницы. Отладчиком увидел, что бит EN в регистре конфигурации потока  DMA не снимается, как будто DMA не получал запросов на транзакции. Помогите, пожалуйста, разобраться.
      Проект на яндексДиске
    • By Карен Григорян
      Здравствуйте, товарищи форумчане!
      У меня вот такая проблемка: есть такая схема:

      По сути тут stm32 на который подаётся некоторое постоянное напряжение, а именно на вход PA1. МК получает его, приводит в цифровую форму (разрядность АЦП равна восьми) и выводит их при помощи восьми GPIO выводов, а именно PB0-PB7. Эти выводы соединены со схемой ЦАП, которая преобразует значение, полученное от stm32 обратно в аналоговую форму и выводит в пробнике R2(1).
      Проблема в том результат выводится не верный. Точнее говоря не всегда верный. Когда я подаю 1В, то на выходе получаю 0,99В, что верно. Но когда, например, подаю 300мВ, то получаю 1.8В, что совсем не верно. Код прошивки предельно прост:
        while (1)
        {
              HAL_ADC_Start_IT(&hadc1);
              HAL_Delay(10);
      }
      Код колбека прерывания:
      void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
      {
          if(hadc->Instance == ADC1) //check if the interrupt comes from ACD1
          {
            int adc = HAL_ADC_GetValue(&hadc1);
                  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,(adc>>0)&1);
                  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,(adc>>1)&1);
                  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,(adc>>2)&1);
                  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,(adc>>3)&1);
                  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,(adc>>4)&1);
                  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,(adc>>5)&1);
                  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,(adc>>6)&1);
                  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,(adc>>7)&1);
          }
              }
      На всякий случай вот настройка АЦП в stm32:

      Вот пример неправильного вычисления:

    • By Vladimir Rubtsov
      Здраствуйте) Подскажите мне балбесу что я делаю не так. Хочу сделать чтобы при нажатии кнопки (PB13) срабатывал светодиод (PE1), но не работает, я как понял что я не правильно инициализирую режим работы порта кнопки, должен быть режим Input mode, но я не пойму как это сделать. У меня просто горит светодиод, но при нажатии кнопки ничего не происходит. Плата у меня stm32h743zi. Подскажите пожалуйста что я делаю не так, все сайты прочекал, но так ничего и не нашел. p.s. Пробовал через HAL писать тоже самое, там естественно все работает, но я хочу понять как работать с кнопкой без HAL.
      #include "stm32h7xx.h" void GPIO_Init(void); int main(void) { GPIO_Init(); if((GPIOC->IDR & GPIO_IDR_ID13) != 0) { GPIOE->BSRR |= GPIO_BSRR_BR1; }else{ GPIOE->BSRR |= GPIO_BSRR_BS1; } } void GPIO_Init () { RCC->AHB4ENR |= RCC_AHB4ENR_GPIOEEN; RCC->AHB4ENR |= RCC_AHB4ENR_GPIOCEN; GPIOE->MODER = GPIO_MODER_MODE1_0; GPIOC->MODER &= ~GPIO_MODER_MODE13; }


    • By Денисов Никита
      Здравствуйте. Решил я таки попробовать перебраться с Arduino AVR на STM32 и для начала решил полностью скопировать Arduino проект, но появилась проблема. Код который на AVR занимал 7кбайт и свободно вмещался на Atmega8, на STM32 занимает 26кбайт. В проекте используется 2 канала ацп + прерывания по DMA, дисплей 1602 по i2c и 4 GPIO. Конечно это занимает только 42% памяти STM32F103C8T, но для такого проекта она избыточна и я хотел использовать STM32F030F4P, но там только 16 кб памяти и прошивка не влезает. Что я не так делаю? Может нужно какую-то оптимизацию включить или что-то подобное(выбран уровень оптимизации for size)? Или у меня просто код никчёмный? Но там так мало написано, что сомневаюсь что я мог где-то накосячить 
    • By Любовь Бертулите
      Компания производитель вендинговых автоматов для розлива питьевой воды в поисках инженера-системотехника/инженера электронщика.
      График 5/2 с 9 до 18, здесь удаленный формат не рассматриваем.
      Место работы – г. Екатеринбург.
      Мы ищем специалиста, который будет делать прототипы нового для контроллера, курировать производство, проверять, дорабатывать, перепаивать, а также:
      Переписывать текущие программы на С++; Создавать программу для Android для конфигурации параметров контроллера через bluetooth. (т.е. предлагать новые, современные идеи и подходы для развития имеющихся контроллеров, которыми вы владеете); Предлагать новые программные продукты, среды разработки. Будет в тренде мира микроэлектроники, китайского контрактного производства. Может предложить совершенно новую реализацию наших текущих задач, чтобы это было лучше и эффективнее. В идеале, нам нужен специалист, который имеет:
      Опыт программирования микроконтроллеров Atmega, STM32, ESP32; Опыт работы в Altium Designer; Опыт работы в c++ (IAR, QT); Опыт работы с modbus, rs485/232, SPI. Готовы рассматривать специалистов с разным опытом, поэтому пишите, задавайте вопросы.
      Резюме можно отправить на почту lb@ktekt.ru (да, мы кадровое агентство), позвонить можно по следующему тел. 89068001212 - Любовь. 
       
×
×
  • Create New...