реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> В чем проблема кода?, неправильно работает программа
ArtTheft
сообщение Aug 29 2014, 14:23
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 19-06-14
Пользователь №: 82 003



Добрый день.
Потихоньку осваиваю STM32VLDiscovery.
Написал код, который банально заменить конструкцию ",," на "0,".
Но он почему-то не работает как надо.
Подскажите в чем моя ошибка
Код под спойлером:
CODE
#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 - Aug 29 2014, 14:24
Go to the top of the page
 
+Quote Post
gerber
сообщение Aug 29 2014, 15:57
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 750
Регистрация: 1-11-11
Пользователь №: 68 088



Цитата(ArtTheft @ Aug 29 2014, 18:23) *
Потихоньку осваиваю 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).


--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
Go to the top of the page
 
+Quote Post
ar__systems
сообщение Aug 29 2014, 16:03
Сообщение #3


self made
****

Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795



С этим кодом всё не так. Я советую отложить на время железо и отладить эту программу на РС.
Go to the top of the page
 
+Quote Post
ArtTheft
сообщение Aug 29 2014, 17:42
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 19-06-14
Пользователь №: 82 003



Цитата(gerber @ Aug 29 2014, 18:57) *
Я нашёл 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. И это тоже исправлю..
Спасибо за подсказки..
Go to the top of the page
 
+Quote Post
Dejmos
сообщение Aug 29 2014, 18:31
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 100
Регистрация: 4-11-11
Из: Смоленск
Пользователь №: 68 137



Цитата(gerber @ Aug 29 2014, 19:57) *
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]==",")) //Если пришло сообщение о нажатии


Цитата(ArtTheft @ Aug 29 2014, 21:42) *
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


--------------------
* работаю так, что лошади оборачиваются *
Go to the top of the page
 
+Quote Post
ArtTheft
сообщение Aug 31 2014, 20:55
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 19-06-14
Пользователь №: 82 003



Цитата(Dejmos @ Aug 29 2014, 21:31) *
Все равно косяк при проверке. Нужно хотя бы так:
Код
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

Дело в том, что я просто хотел совместить свой первоначальный код с данным парсером но он неверно работал, либо же я неправильно пытался вывести хоть какие-то его результаты.
Go to the top of the page
 
+Quote Post
ArtTheft
сообщение Sep 1 2014, 08:48
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 19-06-14
Пользователь №: 82 003



Исправил косяки в коде.
Какие еще ошибки я пропустил?
CODE
#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; // Очистить флаг "Передача завершена".
}
}
Go to the top of the page
 
+Quote Post
Xenia
сообщение Sep 1 2014, 09:10
Сообщение #8


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(ArtTheft @ Sep 1 2014, 12:48) *
GPIOA->CRH &= !GPIO_CRH_CNF9;


Режет глаз восклицательный знак в таких выражениях.
Может быть все-таки так?
GPIOA->CRH &= ~GPIO_CRH_CNF9;

(Это был вопрос, а не совет).
Go to the top of the page
 
+Quote Post
Dejmos
сообщение Sep 1 2014, 10:54
Сообщение #9


Частый гость
**

Группа: Свой
Сообщений: 100
Регистрация: 4-11-11
Из: Смоленск
Пользователь №: 68 137



Цитата(ArtTheft @ Sep 1 2014, 12:48) *
Исправил косяки в коде.
Какие еще ошибки я пропустил?


Их много sad.gif
Придется согласиться с ar__systems - вы не понимаете даже азов программирования.
Рекомендую начать с чего попроще.


--------------------
* работаю так, что лошади оборачиваются *
Go to the top of the page
 
+Quote Post
ArtTheft
сообщение Sep 1 2014, 11:17
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 19-06-14
Пользователь №: 82 003



Цитата(Dejmos @ Sep 1 2014, 13:54) *
Их много sad.gif
Придется согласиться с ar__systems - вы не понимаете даже азов программирования.
Рекомендую начать с чего попроще.

Эх. Понятно.
Не могли бы Вы все таки указать хоть на самые основные ошибки.
Придеться вникать во все азы программирования дабы исправить ошибки...
Go to the top of the page
 
+Quote Post
ar__systems
сообщение Sep 2 2014, 12:56
Сообщение #11


self made
****

Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795



Цитата(ArtTheft @ Sep 1 2014, 06:17) *
Эх. Понятно.
Не могли бы Вы все таки указать хоть на самые основные ошибки.
Придеться вникать во все азы программирования дабы исправить ошибки...


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

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

Код
    
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]==",")) //Если пришло сообщение о нажатии
Go to the top of the page
 
+Quote Post
ArtTheft
сообщение Sep 3 2014, 08:12
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 19-06-14
Пользователь №: 82 003



Цитата(ar__systems @ Sep 2 2014, 15:56) *
А как вы хотели? Че-то как-то налепить не думая, и оно само заработает?

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

Код
    
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 кусков кода.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 25th July 2025 - 22:50
Рейтинг@Mail.ru


Страница сгенерированна за 0.04043 секунд с 7
ELECTRONIX ©2004-2016