Jump to content
motoalex

Stm32 Прием Данных По Usart И Вывод На Hd44780

Recommended Posts

Здравствуйте уважаемые любители МК)

Пытаюсь организовать такую задачу на STM32f407VG:

1. Принимаем данные по USART, помещаем их во временный буфер( Recieve_buff).

2. Если попадается символ '+' читаем (Recieve_buff) и записываем данные после '+' в массив данных (massive).

3. Выводим данные на жки wh1602.

с 1 и 3 пунктом проблем как бы нет, но вот со вторым вовсе не клеится. К примеру: отправляю +suprima, после 1, а то и 3 отправки приходит только один символ 's', т.е. и не каждый раз выводятся данные. Прошу помощи у Гуру сообщества. Всем Благ!

#include "main.h"

uint16_t delay_count=0;
uint32_t i;
uint32_t i3;
int i2=123;
char str1[50];
uint8_t massive[256]; // massive buffer
uint8_t Recieve_buff[256]; // recieved buffer
uint8_t Recieve_W=0, Recieve_R=0, Recieve_C=0;
char Send_buffer[100];
uint8_t Send_count=0;

void SysTick_Handler(void)// counter
{
if (delay_count > 0)
{
 delay_count --;
}
}
void(delay_ms(uint16_t delay_temp)) // schitayem nashe vremya, kotoroe zadano v osnovnom tele
{
delay_count = delay_temp;
while(delay_count) {}
}
//---------------------------------------------------//
//recieved data interrupt
//---------------------------------------------------//
void USART2_IRQHandler(void)
{
if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET) // if flag interrupt set up we will do next...
{
USART_ClearITPendingBit(USART2, USART_IT_RXNE); // reset interrupt
	 Recieve_buff[Recieve_W] =USART_ReceiveData(USART2);
 Recieve_W++;
 Recieve_C++;
}
}
//---------------------------------------------------//
int main(void)
{
USART2_init();
SystemCoreClockUpdate();
SysTick_Config(SystemCoreClock/1000);// 1ms
delay_ms(50);
LCD_ini();
while(1)
{
if(Recieve_C>0)
{
if(Recieve_buff[Recieve_R++]=='+')
{
massive[i3++]=Recieve_buff[Recieve_R++];
sprintf(str1, "%s", massive);
//sprintf(str7, "%s %d %s", "one", i2, str);
 LCD_Send_String8(0,str1);
}
Recieve_C--;
Recieve_R++;
}
}
}

Edited by motoalex

Share this post


Link to post
Share on other sites

Тут надо учесть, что буквы по USART передаются медленно, одна за другой, а процессор работает быстро.

Вот, только передали первый символ из строки "+suprima", как тут же сработали оба условия if(Recieve_C>0) и if(Recieve_buff[Recieve_R++]=='+'), и процессор сразу пытается вывести что-то на экран. Хотя ещё только-только второй символ "s" передаётся, не говоря уже об остальных символах из строки.

Причём при приёме следующего символа условие if(Recieve_buff[Recieve_R++]=='+') уже не будет срабатывать, т.к. Recieve_R уже увеличился и проехал плюсик в буфере.

Надо по-другому. Проверять в прерывании все полученные символы на равенство "+", и при приёме плюсика выставлять флаг, что пошла строка. В главном цикле проверять флаг, и при установке флага просто выводить все приходящие символы на экран по одному. После приёма всей строки - флаг сбрасывать и снова ждать плюсик.

Edited by Yurkin2015

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-принтер и так далее...

Надо по-другому. Проверять в прерывании все полученные символы на равенство "+", и при приёме плюсика выставлять флаг, что пошла строка. В главном цикле проверять флаг, и при установке флага просто выводить все приходящие символы на экран по одному. После приёма всей строки - флаг сбрасывать и снова ждать плюсик.

Огромное спасибо Вам, Уважаемый, сделал почти как Вы говорите,но есть пару нюансов:

1. sprintf(str1, "%s", USART_ReceiveData(USART2)); - не корректно выводит данные на ЖКИ, Я в прерывании по выставлению флага, сделал ещё одно условие и там пишу в Recieve_buff[Recieve_W]. И его уже вывожу на ЖКИ - всё славно.

2. Конец строки ловлю тоже в прерывании символом конца строки.

Но есть ещё пару вопросов, когда лучше обнулять переменную Recieve_W буфера Recieve_buff[], так как выполнение этой операции в прерывании не всегда выводит последний отправленный символ.

Share this post


Link to post
Share on other sites

Безмостовые ККМ для 99% КПД!

Схема коррекции коэффициента мощности (ККМ) на основе так называемого «тотемного столба» (Totem Pole) обладает минимально возможными потерями и потенциально может обеспечить самые жесткие требования к энергоэффективности источников питания. Компания Wolfspeed представляет референсную разработку – плату ККМ CRD-02AD065N на базе собственных карбид-кремниевых MOSFET и диодов с наилучшими в отрасли характеристиками.

Подробнее

Мне кажется, использовать функцию sprintf() тут не надо.

Программа по USART получает уже готовый символ.

Можно либо сразу его отправлять без всяких преобразований, типа LCD_Send_Data(USART_ReceiveData(USART2));

Но лучше накапливать строку в буфере прямо в прерывании, а по концу строки выводить её прямо на ЖКИ в основной программе.

типа так:

Прерывание
{
char tmpc = USART_ReceiveData(USART2);
 Если (Plusik == 1)
 {
  str1[Receive_R++] = tmpc;
 }
 if(tmpc=='+')
 {
    Plusik = 1;
    Receive_R = 0;
 }
 Если получили конец строки,
 {
    Plusik = 0 ;
    str1[Receive_R]=0 ;
    KonecStroki=1;
   }
}

В основной программе
while(1){
если (KonecStroki==1)
 {
   LCD_Send_Line(str1);
   KonecStroki=0;
 }
}

Edited by Yurkin2015

Share this post


Link to post
Share on other sites

Гибридные IGBT - сила Si и SiC в одном корпусе!

Компания Infineon представила новые гибридные IGBT-транзисторы на 650 В, которые сочетают в себе преимущества технологий TRENCHSTOP и CoolSiC. Использование SiC-диода Шоттки позволяет значительно расширить возможности IGBT и снизить уровень энергии, необходимой для включения транзистора (Eon), а также уменьшить потери на переключение.

Подробнее

Вы очень сильно мне помогли, все работает, как часики. хочу Вас попросить об последней просьбе.Как сравнить два массива (один в памяти, а другой принятый по usart).

char massive[]={'S','U','P','R','I','M','A','1','2','3','4','5'}; // massive buffer
***********************************
while(1)
{
if(f2==1) // флаг на конец строки
{
if (f4==0) флаг на работу с массивами
{
if (massive[i3]==str1[i3]) // сравниваем наши массивы
{
i3++;
if(i3==12)
 {
 f4=1; //обнуляем флаг
 f3=1; // идем на печать строки в ЖКИ
 }
}
}
if(f3==1)
{
LCD_Send_String8(0, str1);
 i3=0; f2=0; f3=0;
}
}
}
}

В моем случае не правильно сравниваю данные в массиве. Точней не правильно пишу алгоритм.

Edited by motoalex

Share this post


Link to post
Share on other sites

Вебинар «Параметры выше, цена ниже. Обновление в линейке AC/DC- и DC/DC-преобразователей MORNSUN» (26.01.2021)

Приглашаем 26 января на бесплатный вебинар, посвящённый преимуществам и отличиям новых источников питания и DC/DC-преобразователей Mornsun. На вебинаре будут рассмотрены изолированные и неизолированные DC/DC-преобразователи последнего, четвертого, поколения (R4) и компактные модульные источники питания второго и третьего поколений (семейства LS/R3 и LD/R2) на плату. Рассмотрим новую группу продукции – встраиваемые источники питания в кожухе.

Подробнее

char massive[]={'S','U','P','R','I','M','A','1','2','3','4','5'}; // massive buffer
***********************************
while(1)
{
if (f2 == 1) // флаг на конец строки
{
 f2 = 0;
 f3 = 1;
 for(i3=0; i3<12; i3++)
 {
  if (massive[i3] != str1[i3]) // сравниваем наши массивы
  {
   f3 = 0; 
   break;
  }
 }
 if(f3 == 1)
 { 
  LCD_Send_String8(0, str1);
  f3 = 0;
 }
}
}

Edited by melkiy93

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...

  • Сообщения

    • Никто вам не поможет... Кроме стандарной процедуры снятия параметров Тиля -Смолла(ПТС) Ну стояли эти бошки в каком то Эдифере 5.1, но даже в паспорте ПТС не пишут. А вам же нужно определиться не с названиями а в какой тип АО и какого объема их ставить, верно? Если нужны названия головок, спойлер можно не открывать.
    • а может не зря автор данной моргалки предлагал замену Д814А - 1N3181 с Uст=7.7V?
    • Ну-ну. Нашел ведь место, где спрашивать. Ты бы еще вспомнил Высоцкого и в «Спортлото» написал. 1. Внутри этой микросхемы стоит опорная цепочка из трех идентичных резисторов. Поэтому точками переключения микросхемы являются напряжения на конденсаторе 1/3 и 2/3 от напряжения питания. При напряжении питания 9в это будут напряжения 3в и 6в. Верхний порог переключения 6в доступен для измерения тестером через вывод 5 микросхемы. Из этого и нужно было исходить при подборе стабилитрона. 2. Не бойся увеличить емкость конденсатора на выводе 5 микросхемы до 100nF. Это критично при отсчете временнЫх интервалов большой длительности. Конденсатор должен быть пленочным. Керамический конденсатор ставить нельзя из-за микрофонного эффекта. 3. Идея автора была – не допустить слишком большого ухода напряжения на конденсаторе C4 свыше порога 6в. Идея хорошая, реализация – не очень. Основная причина – большая утечка оптопары. Автор долго и нудно пытался убрать утечку. В итоге не придумал ничего лучше, чем поставить резистор R11. 4. Приводим схему в порядок. Выкидываем стабилитрон. Увеличиваем сопротивление R9. Чем больше – тем лучше. Но не более чем до 100кОм (верхний предел 2/3 Uпит. R8, R9 – делитель). Оптимальное значение – 68кОм…82кОм. Излишки тока сбрасываем вместо стабилитрона на внутренний делитель микросхемы. Заодно привязываемся к верхнему порогу 2/3Uпит. Нужно поставить диод между выводами 2+6 и 5. Анодом к выводам 2+6, катодом к выводу 5. Диод должен быть с малой утечкой, например, 1N4148, КД522. Внутри микросхемы три резистора по 5кОм, поэтому далеко вверх напряжение не уплывет. Впрочем, при сопротивлении R9 около 91кОм, вполне возможно, даже и диод не понадобится.
    • R11 попробуйте переставить только на светодиод оптопары или увеличить до 3k
    • Храбрые как львы Спецназ Кирово-Чепецка лучший, его никто не остановит  КЛАЙД и звезда это всё что доложу Родине... ПВО доделает работу НИКТО кроме спецназа слезы мужские дорого будут оплачены Настолько дороги, что срать будут чем видеть
    • У КОМ порта (RS232) кроме уровней еще и обратная логика: 0 - +15 В , а 1 - -15 В.
    • Ну да, ну да ==== покупаю бензин заливаю, машина в ступор - Это Наши индивидуальные проблемы. Из водопровода идёт ржавая вода ... или вон тут отравилось 200 человек = Это Наши индивидуальные проблемы. Выпускники - школьники прочитали за всю жизнь 5...7 книг... Это Наши индивидуальные проблемы.  Я так понимаю,= это перерастает  ужо в общенациональное достояние.

  • Модуль цифрового таймера с реле до 10А. НЗ и НО выходы

  • 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...