Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: В чем проблема кода?
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
ArtTheft
Добрый день.
Потихоньку осваиваю 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);
}
gerber
Цитата(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).
ar__systems
С этим кодом всё не так. Я советую отложить на время железо и отладить эту программу на РС.
ArtTheft
Цитата(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. И это тоже исправлю..
Спасибо за подсказки..
Dejmos
Цитата(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
ArtTheft
Цитата(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

Дело в том, что я просто хотел совместить свой первоначальный код с данным парсером но он неверно работал, либо же я неправильно пытался вывести хоть какие-то его результаты.
ArtTheft
Исправил косяки в коде.
Какие еще ошибки я пропустил?
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; // Очистить флаг "Передача завершена".
}
}
Xenia
Цитата(ArtTheft @ Sep 1 2014, 12:48) *
GPIOA->CRH &= !GPIO_CRH_CNF9;


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

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


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

Эх. Понятно.
Не могли бы Вы все таки указать хоть на самые основные ошибки.
Придеться вникать во все азы программирования дабы исправить ошибки...
ar__systems
Цитата(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]==",")) //Если пришло сообщение о нажатии
ArtTheft
Цитата(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 кусков кода.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.