|
|
  |
В чем проблема кода?, неправильно работает программа |
|
|
|
Aug 29 2014, 14:23
|
Участник

Группа: Участник
Сообщений: 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
|
|
|
|
|
Aug 29 2014, 15:57
|
Знающий
   
Группа: Участник
Сообщений: 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).
--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
|
|
|
|
|
Aug 29 2014, 17:42
|
Участник

Группа: Участник
Сообщений: 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. И это тоже исправлю.. Спасибо за подсказки..
|
|
|
|
|
Aug 29 2014, 18:31
|

Частый гость
 
Группа: Свой
Сообщений: 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
--------------------
* работаю так, что лошади оборачиваются *
|
|
|
|
|
Aug 31 2014, 20:55
|
Участник

Группа: Участник
Сообщений: 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Дело в том, что я просто хотел совместить свой первоначальный код с данным парсером но он неверно работал, либо же я неправильно пытался вывести хоть какие-то его результаты.
|
|
|
|
|
Sep 1 2014, 08:48
|
Участник

Группа: Участник
Сообщений: 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; // Очистить флаг "Передача завершена". } }
|
|
|
|
|
Sep 1 2014, 09:10
|

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

|
Цитата(ArtTheft @ Sep 1 2014, 12:48)  GPIOA->CRH &= !GPIO_CRH_CNF9; Режет глаз восклицательный знак в таких выражениях. Может быть все-таки так? GPIOA->CRH &= ~GPIO_CRH_CNF9; (Это был вопрос, а не совет).
|
|
|
|
|
Sep 1 2014, 10:54
|

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

|
Цитата(ArtTheft @ Sep 1 2014, 12:48)  Исправил косяки в коде. Какие еще ошибки я пропустил? Их много  Придется согласиться с ar__systems - вы не понимаете даже азов программирования. Рекомендую начать с чего попроще.
--------------------
* работаю так, что лошади оборачиваются *
|
|
|
|
|
Sep 1 2014, 11:17
|
Участник

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

|
Цитата(Dejmos @ Sep 1 2014, 13:54)  Их много  Придется согласиться с ar__systems - вы не понимаете даже азов программирования. Рекомендую начать с чего попроще. Эх. Понятно. Не могли бы Вы все таки указать хоть на самые основные ошибки. Придеться вникать во все азы программирования дабы исправить ошибки...
|
|
|
|
|
Sep 2 2014, 12:56
|
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]==",")) //Если пришло сообщение о нажатии
|
|
|
|
|
Sep 3 2014, 08: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 кусков кода.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|