hardbar

Запись Даных После Опроса И Отправка.алгоритм Uarta На Asm

9 сообщений в этой теме

hardbar    98

Вот хочу сделать опрос кнопок на одном мк отправка по Uart и вывод значения на другом мк.

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

Просто по очереди записывать в РОН и отправлять не работает так как даные после обработки могут пойти не в той порт.

вот схема для наглядности

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

Изменено пользователем hardbar

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Дай сначала байт-идентификатор, а потом байт данных. Т.е. $7F (идентификатор передачи состояния фиксированных кнопок), $XX (само состояние) и $1F (идентификатор кнопок без фиксации), $XX (само состояние). На другом конце МК декодирует идентификаторы в посылках и согласно им поместит результаты "по местам". Коды идентификаторов можешь придумать любые, на свое усмотрение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
hardbar    98

А если идентификатор совпадает с посылкой. Тогда что сделать?

Изменено пользователем hardbar

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
hardbar    98

Ок. А как тогда сделать двух байтовую посылку. Вдруг первый байт придет вторым а второй первым.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Не вей провода и тогда байты не запутаются. :) Ты волнуешься, что принимающий МК собьется со счета? Тогда усложни протокол. Запрос на передачу (МК №1 1байт), ответ готовности приема (МК №2 1байт), посылка данных (идентификатор/данные). Пока не договорятся все посылки игнорировать. Во время ответа второй МК синхронизирует счетчик принятых байт. Ну как-то так. Можно напридумывать как угодно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
hardbar    98

Оооо... гениальная мысля. Нужно чтоб приемник давал команду что готов принять 1 посылку после ее приема давал что готов принять 2 посылку. А потом выводил значение в порт.

Спасиба!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

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

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Похожие публикации

    • Автор: DmitryDDDD
      Здравствуйте, имеется задача передачи данных от stm32 на ПК и от ПК в stm по UART. Имеется stm32f411e-disco, созданная программа на пк в Qt creator. UART передатчик - CH340. Программа для stm - Keil, настройка в cubeMX.
      Основные выдержки из кода Qt (mainwindow.cpp):
       
      C++ (Qt)Выделить код
      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
      // Настройка UART      serial = new QSerialPort(this);      serial->setPortName("com4");      serial->setBaudRate(QSerialPort::Baud115200);      serial->setDataBits(QSerialPort::Data8);      serial->setParity(QSerialPort::NoParity);      serial->setStopBits(QSerialPort::OneStop);      serial->setFlowControl(QSerialPort::NoFlowControl);      serial->open(QIODevice::ReadWrite);      /*serial->write("ok*");  */                                                          connect(serial, SIGNAL(readyRead()), this, SLOT(serialReceived()));   // Запись принятых даннх в текстовое окно void MainWindow::serialReceived() {     QByteArray ba;     ba=serial->readAll();     ui->label->setText(ba);     qDebug()<<ba; }   // Отправка "1" и "2" в зависимости от нажатой кнопки void MainWindow::on_pushButton_clicked() {   serial->write("1"); }   void MainWindow::on_pushButton_2_clicked() {   serial->write("2"); }
      Настроен UART на прием и передачу. При нажатии какой-либо кнопки по UART передаётся 1 или 2ка. Так же принятая информация отображается в текстовом окне label. При замыкании RX и TX у CH340 отправленная 1 или 2 тут же принимаются программой.

      Программный код для stm создан в CubeMX. Там подключено два UART, один на приём, другой на передачу (можно настроить один для работы в 2 направления).
      Основные выдержки из кода Keil (main.c):
      //Настройка UART
      serial = new QSerialPort(this);
      serial->setPortName("com4");
      serial->setBaudRate(QSerialPort::Baud115200);
      serial->setDataBits(QSerialPort::Data8);
      serial->setParity(QSerialPort::NoParity);
      serial->setStopBits(QSerialPort::OneStop);
      serial->setFlowControl(QSerialPort::NoFlowControl);
      serial->open(QIODevice::ReadWrite);
      /* serial->write("ok*"); */ // Transmiting "ок" to COM Port
      connect(serial, SIGNAL(readyRead()), this, SLOT(serialReceived()));
       
      // Отображение принятых данных в текстовом меню label
      void MainWindow::serialReceived()
      {
      QByteArray ba;
      ba=serial->readAll();
      ui->label->setText(ba);
      qDebug()<<ba;
      }
       
      // Отправка 1 или 2 в зависимости от нажатой кнопки
      void MainWindow::on_pushButton_clicked()
      {
      serial->write("1");
      }
       
      void MainWindow::on_pushButton_2_clicked()
      {
      serial->write("2");
      }
       
      Выдержки из кода в Keil (main.c):
       
      // Настройка UART
      static void MX_USART1_UART_Init(void)
      {
        huart1.Instance = USART1;
        huart1.Init.BaudRate = 115200;
        huart1.Init.WordLength = UART_WORDLENGTH_8B;
        huart1.Init.StopBits = UART_STOPBITS_1;
        huart1.Init.Parity = UART_PARITY_NONE;
        huart1.Init.Mode = UART_MODE_TX_RX;
        huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
        huart1.Init.OverSampling = UART_OVERSAMPLING_16;
        if (HAL_UART_Init(&huart1) != HAL_OK)
        {
          _Error_Handler(__FILE__, __LINE__);
        }
      }
      // 2 массива для принятия и отправки данных
        uint8_t strTX[1];
          uint8_t strRX[1];
      // Попытка сделать что-то адекватное
              int strTX = 1;
      while(1) {        
              HAL_UART_Transmit_IT(&huart2, (uint8_t*) strTX, 1);
            HAL_UART_Receive_IT(&huart2, (uint8_t*) strTX, 1);
      Код в keil явно кривой, в Qt вроде всё работает. Получается передать из stm в Qt, но из Qt в stm нет. 
      Нужно получить следующее: нажимаем в Qt одну из двух кнопок, отправляется в stm либо 1, либо 2 в зависимости от выбранной кнопки. Stm принимает, обрабатывает, если 1, то загорается один светодиод, если 2, то другой. Дальше stm отправляет обратно в Qt информацию о том, какой светодиод загорелся. 

      P.S: довольно далек от программирования, но стараюсь разобраться. Буду благодарен любой помощти, некоторые скриншоты прилагаю.



    • Автор: User_1
      Всем привет!
      Почему-то этот код работает: 
      void Send_to_UART(char* string) { char data = 0; while(*string) { while(!(USART_GetFlagStatus(USART1, USART_FLAG_TXE))); data = *string; USART1->TDR = data; string++; } while(!(USART_GetFlagStatus(USART1, USART_FLAG_TXE))); USART_SendData(USART1, 0x0D); while(!(USART_GetFlagStatus(USART1, USART_FLAG_TXE))); USART_SendData(USART1, 0x0A); while(!(USART_GetFlagStatus(USART1, USART_FLAG_TC))); } char hello[13] = {'H','e','l','l','o',' ','W','o','r','l','d','!'}; int main (void) { Init_Clock(); Init_USART1(); Send_to_UART(hello); while(1); } А если написать вот так:
      int main (void) { Init_Clock(); Init_USART1(); Send_to_UART("Hello World!"); while(1); } то не просто не работает - микроконтролер зависает даже до входа в main().
      В Си ведь, насколько я понимаю, строка - это тот же массив символов
      Объясните, пожалуйста, что я делаю не так?
      Камень stm32f030, среда CooCox CoIDE
    • Гость Andrey-Docent
      Автор: Гость Andrey-Docent
      Всем привет! Планируется сделать на базе arduino устройство, ведущее обмен данными с переферийным устройством по интерфейсу rs-232 и также необходимо контролировать работу arduino с помощью компьютера тоже посредством интерфейса rs-232. Но у arduino только один такой порт. Первая мысль в связи с этим - сделать ещё один порт и вывести линии RX и TX на другие (например цифровые) ножки порта. Можно ли как-то это сделать? Нет ли готовых библиотек для этого (на данный момент не нашёл таковых в интернете)? Может есть ещё какой-нибудь обходной путь? Заранее спасибо.
    • Автор: LoKeR
      Доброго времени суток, нашел хорошую статью Usart прием и отправка строки. Настроил на порт Usart3 перестал работать, попробовал на Usart2 перекинуть тоже не работает, как правильно переделать подскажите...
      stm32-uart-spl.rar
    • Автор: Тимур1992
      Доброго времени суток.
      Решил пробудить свои скилы по написанию программ под 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) { } } }