Перейти к содержанию
    

В чем проблема кода?

Добрый день.

Потихоньку осваиваю STM32VLDiscovery.

Написал код, который банально заменить конструкцию ",," на "0,".

Но он почему-то не работает как надо.

Подскажите в чем моя ошибка

Код под спойлером:

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_usart.h"
#include "string.h"
#include "stdio.h"
#include "gps_parser.h"

#define buflength  (700)
char uart1_rx_buf[buflength]; //Буфер для приёма сообщения.
volatile unsigned int uart1_rx_bit; //Номер байта UART принимаемого в буфер.

//Структуры для инициализации GPIOA и USART1
GPIO_InitTypeDef    GPIO_InitStruct;
USART_InitTypeDef    USART_InitStruct;

int main(void)
{
 // Включаем модули USART1 и GPIOA, а также включаем альтернативные функции выходов
 RCC->APB2ENR|= RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN;
 // Контакт PA9 будет выходом с альтернативной функцией, а контакт PA10 - входом
 GPIOA->CRH &= !GPIO_CRH_CNF9;
 GPIOA->CRH  |= GPIO_CRH_CNF9_1 | GPIO_CRH_MODE9_0 | GPIO_CRH_CNF10_0;
 // Настраиваем регистр тактирования, скорость составит 9600 бод (при тактовой частоте 24 МГц)
 USART1->BRR = 0xD0;
 // Выключаем TxD и RxD USART
 USART1->CR1 |= USART_CR1_TE | USART_CR1_RE;
 // Запускаем модуль USART
 USART1->CR1 |= USART_CR1_UE;
 // Разрешаем прерывание по приёму информации с RxD
 USART1->CR1 |= USART_CR1_RXNEIE;
 // Назначаем обработчик для всех прерываний от USART1
 NVIC_EnableIRQ(USART1_IRQn);
 // Бесконечный цикл
 while(1);
}

void USART1_Send(char chr) {
USART1->DR = chr;
}

void USART1_Send_String(char* str) {
 int i=0;
 while(str[i])
   USART1_Send(str[i++]);
}

// Обработчик всех прерываний от USART1
void USART1_IRQHandler(void) {

if (USART1->SR & USART_SR_RXNE) //Проверяем, прило ли чтонибудь в UART
{
uart1_rx_buf[uart1_rx_bit]=USART1->DR; //Помещаем принятый байт в буфер.
if ((uart1_rx_buf[uart1_rx_bit]==",")&&(uart1_rx_buf[uart1_rx_bit-1]==",")) //Если пришло сообщение о нажатии
	    {
	uart1_rx_buf[uart1_rx_bit] = "0";
	uart1_rx_buf[uart1_rx_bit+1] = ",";
	    }
}
USART1_Send_String(uart1_rx_buf);
}

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

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


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

Потихоньку осваиваю STM32VLDiscovery.

Написал код, который банально заменить конструкцию ",," на "0,".

Но он почему-то не работает как надо.

Подскажите в чем моя ошибка

Я нашёл 5 ошибок:

1) uart1_rx_bit не инициализирована, поскольку она глобальна, то будет нулём, хотя и не айс так делать.

2) из нулевого индекса uart1_rx_bit идёт вычитание единицы в индексе, вот тут уже серьёзно ... по логике замены, должно быть прибавление единицы.

if ((uart1_rx_buf[uart1_rx_bit]==",")&&(uart1_rx_buf[uart1_rx_bit-1]==",")) //Если пришло сообщение о нажатии
{
uart1_rx_buf[uart1_rx_bit] = "0";
uart1_rx_buf[uart1_rx_bit+1] = ",";
}

3) нигде нет изменения индекса uart1_rx_bit, у вас любой принятый символ пишется в нулевой индекс.

4) отправка буфера в UART идёт всегда, независимо, пришло что-то или нет.

5) так отправлять в UART нельзя, после каждого символа, записанного в DR, нужно дождаться, пока он уйдёт в сдвиговый регистр (Tx Empty).

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


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

С этим кодом всё не так. Я советую отложить на время железо и отладить эту программу на РС.

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


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

Я нашёл 5 ошибок:

1) uart1_rx_bit не инициализирована, поскольку она глобальна, то будет нулём, хотя и не айс так делать.

2) из нулевого индекса uart1_rx_bit идёт вычитание единицы в индексе, вот тут уже серьёзно ... по логике замены, должно быть прибавление единицы.

if ((uart1_rx_buf[uart1_rx_bit]==",")&&(uart1_rx_buf[uart1_rx_bit-1]==",")) //Если пришло сообщение о нажатии
{
uart1_rx_buf[uart1_rx_bit] = "0";
uart1_rx_buf[uart1_rx_bit+1] = ",";
}

3) нигде нет изменения индекса uart1_rx_bit, у вас любой принятый символ пишется в нулевой индекс.

4) отправка буфера в UART идёт всегда, независимо, пришло что-то или нет.

5) так отправлять в UART нельзя, после каждого символа, записанного в DR, нужно дождаться, пока он уйдёт в сдвиговый регистр (Tx Empty).

1. Вначале же она обьявлена: volatile unsigned int uart1_rx_bit;

2. Спасибо за подсказку, поправлю.

3. Я так понимаю надо добавить uart1_rx_bit++; Видимо забыл исправить этот кусок кода

4. Это я тоже поправлю.

5. И это тоже исправлю..

Спасибо за подсказки..

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


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

2) из нулевого индекса uart1_rx_bit идёт вычитание единицы в индексе, вот тут уже серьёзно ... по логике замены, должно быть прибавление единицы.

if ((uart1_rx_buf[uart1_rx_bit]==",")&&(uart1_rx_buf[uart1_rx_bit-1]==",")) //Если пришло сообщение о нажатии
{
uart1_rx_buf[uart1_rx_bit] = "0";
uart1_rx_buf[uart1_rx_bit+1] = ",";
}

 

Все равно косяк при проверке. Нужно хотя бы так:

if (uart1_rx_bit)
  if ((uart1_rx_buf[uart1_rx_bit]==",")&&(uart1_rx_buf[uart1_rx_bit-1]==",")) //Если пришло сообщение о нажатии

 

1. Вначале же она обьявлена: volatile unsigned int uart1_rx_bit;

Объявлена, но не инициализирована. Нужно явно задать начальное значение.

volatile unsigned int uart1_rx_bit=0;

Без этого с глобальной переменной работать скорее всего будет, а вот с локальной уже нет.

 

 

6. Нет проверки переполнения буфера. Он кольцевой должен быть по задумке или какой?

Чтобы заработало хоть как-то можно задать:

#define buflength  256
char uart1_rx_buf[buflength]; //Буфер для приёма сообщения.
volatile unsigned char uart1_rx_bit=0; //Номер байта UART принимаемого в буфер.

а 2) сделать как предложил gerber

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


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

Все равно косяк при проверке. Нужно хотя бы так:

if (uart1_rx_bit)
  if ((uart1_rx_buf[uart1_rx_bit]==",")&&(uart1_rx_buf[uart1_rx_bit-1]==",")) //Если пришло сообщение о нажатии

 

 

Объявлена, но не инициализирована. Нужно явно задать начальное значение.

volatile unsigned int uart1_rx_bit=0;

Без этого с глобальной переменной работать скорее всего будет, а вот с локальной уже нет.

 

 

6. Нет проверки переполнения буфера. Он кольцевой должен быть по задумке или какой?

Чтобы заработало хоть как-то можно задать:

#define buflength  256
char uart1_rx_buf[buflength]; //Буфер для приёма сообщения.
volatile unsigned char uart1_rx_bit=0; //Номер байта UART принимаемого в буфер.

а 2) сделать как предложил gerber

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

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


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

Исправил косяки в коде.

Какие еще ошибки я пропустил?

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_usart.h"
#include "string.h"
#include "stdio.h"
#include "gps_parser.h"

#define buflength  (256)
char uart1_rx_buf[buflength]; //Буфер для приёма сообщения.
volatile unsigned char uart1_rx_bit=0; //Номер байта UART принимаемого в буфер.

//Структуры для инициализации GPIOA и USART1
GPIO_InitTypeDef    GPIO_InitStruct;
USART_InitTypeDef    USART_InitStruct;

int main(void)
{
 // Включаем модули USART1 и GPIOA, а также включаем альтернативные функции выходов
 RCC->APB2ENR|= RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN;
 // Контакт PA9 будет выходом с альтернативной функцией, а контакт PA10 - входом
 GPIOA->CRH &= !GPIO_CRH_CNF9;
 GPIOA->CRH  |= GPIO_CRH_CNF9_1 | GPIO_CRH_MODE9_0 | GPIO_CRH_CNF10_0;
 // Настраиваем регистр тактирования, скорость составит 9600 бод (при тактовой частоте 24 МГц)
 USART1->BRR = 0xD0;
 // Выключаем TxD и RxD USART
 USART1->CR1 |= USART_CR1_TE | USART_CR1_RE;
 // Запускаем модуль USART
 USART1->CR1 |= USART_CR1_UE;
 // Разрешаем прерывание по приёму информации с RxD
 USART1->CR1 |= USART_CR1_RXNEIE;
 // Назначаем обработчик для всех прерываний от USART1
 NVIC_EnableIRQ(USART1_IRQn);
 // Бесконечный цикл
 while(1);
}

void USART1_Send(char chr) {
while(!(USART1->SR & USART_SR_TC));
USART1->DR = chr;
}

void USART1_Send_String(char* str) {
 int i=0;
 while(str[i])
   USART1_Send(str[i++]);
}

// Обработчик всех прерываний от USART1
void USART1_IRQHandler(void) {
char uart_data;
if (USART1->SR & USART_SR_RXNE) //Проверяем, прило ли чтонибудь в UART
{
uart_data=USART1->DR; //Считываем то что пришло в переменную...
uart1_rx_buf[uart1_rx_bit]=USART1->DR; //Помещаем принятый байт в буфер.
uart1_rx_bit++;
if ((uart1_rx_buf[uart1_rx_bit]==",")&&(uart1_rx_buf[uart1_rx_bit+1]==",")) //Если пришло сообщение о нажатии
	    {
	uart1_rx_buf[uart1_rx_bit] = "0";
	uart1_rx_buf[uart1_rx_bit+1] = ",";
	    }
}
USART1_Send_String(uart1_rx_buf);
memset(uart1_rx_buf, 0, sizeof(uart1_rx_buf)); //Очищаем буфер
uart1_rx_bit=0; //Сбрасываем счетчик
   if (USART3->SR&USART_SR_TC) // Если прерывание по завершению передачи.
   {
     USART3->SR&=~USART_SR_TC; // Очистить флаг "Передача завершена".
   }
}

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


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

GPIOA->CRH &= !GPIO_CRH_CNF9;

 

Режет глаз восклицательный знак в таких выражениях.

Может быть все-таки так?

GPIOA->CRH &= ~GPIO_CRH_CNF9;

 

(Это был вопрос, а не совет).

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


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

Исправил косяки в коде.

Какие еще ошибки я пропустил?

 

Их много :(

Придется согласиться с ar__systems - вы не понимаете даже азов программирования.

Рекомендую начать с чего попроще.

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


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

Их много :(

Придется согласиться с ar__systems - вы не понимаете даже азов программирования.

Рекомендую начать с чего попроще.

Эх. Понятно.

Не могли бы Вы все таки указать хоть на самые основные ошибки.

Придеться вникать во все азы программирования дабы исправить ошибки...

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


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

Эх. Понятно.

Не могли бы Вы все таки указать хоть на самые основные ошибки.

Придеться вникать во все азы программирования дабы исправить ошибки...

 

А как вы хотели? Че-то как-то налепить не думая, и оно само заработает?

 

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

 

    
uart_data=USART1->DR; //Считываем то что пришло в переменную...
uart1_rx_buf[uart1_rx_bit]=USART1->DR; //Помещаем принятый байт в буфер.
uart1_rx_bit++;
if ((uart1_rx_buf[uart1_rx_bit]==",")&&(uart1_rx_buf[uart1_rx_bit+1]==",")) //Если пришло сообщение о нажатии

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


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

А как вы хотели? Че-то как-то налепить не думая, и оно само заработает?

 

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

 

    
uart_data=USART1->DR; //Считываем то что пришло в переменную...
uart1_rx_buf[uart1_rx_bit]=USART1->DR; //Помещаем принятый байт в буфер.
uart1_rx_bit++;
if ((uart1_rx_buf[uart1_rx_bit]==",")&&(uart1_rx_buf[uart1_rx_bit+1]==",")) //Если пришло сообщение о нажатии

Насчет основ это я понимаю, что так с нуля ничего толкового не получиться...

Но дело еще в том, что это код был в примере с сайта схем.нет...и еще на одном сайте.

Это сборная конструкция из 2 кусков кода.

 

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


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

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...