STM32f4. Функция atoi.

Все о микроконтроллерах: AVR, PIC, STM8, STM32, Arduino, Altera, Xilinx, все что угодно. Этот раздел для всего что клацает байтиками.
Post Reply
Rogers
Posts: 13
Joined: 30 Sep 2013, 21:37
Location: МО, Климовск

STM32f4. Функция atoi.

Post by Rogers »

Приветствую! Я продолжаю ковырять тему UARTа и у меня появился вопрос: как полученные данные (строка) переконвертировать в числовые данные? То есть ввожу "0" (в терминале) как "строку" (30 в hex коде), а в результате хочу вывести "0" как число (0 в hex коде). И как это отследить/проверить ? В различных терминалах уже сразу конвертируется результат ввода/вывода в ASCII/Hex. Про функцию atoi я в курсе и использовал ее в windows-приложениях, но не в arm. Прикладываю рабочий код по приему "строки" и вывода "строки". Работаю в keil 5.0.

Code: Select all

#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_usart.h"


char uart2_rx_buf[128]; //Буфер для приёма сообщения.
uint8_t uart2_rx_bit; //Номер байта UART принимаемого в буфер.


//Функция отправляет байт в UART
void send_to_uart(uint8_t data)
{
 while(!(USART2->SR & USART_SR_TC));
 USART2->DR=data;
}

//Функция отправляет строку в UART, по сути пересылая по байту в send_to_uart
void send_str(char * string)
{
 uint8_t i=0;
 while(string[i])
 {
  send_to_uart(string[i]);
  i++;
 }
}

//Инициализируем USART2
void usart_init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure; //Структура содержащая настройки порта
  USART_InitTypeDef USART_InitStructure; //Структура содержащая настройки USART

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //Включаем тактирование порта A
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //Включаем тактирование порта USART2


  GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); //Подключаем PA3 к TX USART2
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); //Подключаем PA2 к RX USART2

  //Конфигурируем PA2 как альтернативную функцию -> TX UART. Подробнее об конфигурации можно почитать во втором уроке.
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  //Конфигурируем PA2 как альтернативную функцию -> RX UART. Подробнее об конфигурации можно почитать во втором уроке.
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  USART_StructInit(&USART_InitStructure); //Инициализируем UART с дефолтными настройками: скорость 9600, 8 бит данных, 1 стоп бит

  USART_Init(USART2, &USART_InitStructure);
  USART_Cmd(USART2, ENABLE); //Включаем UART
}

int main(void)
{
	GPIO_InitTypeDef GPIO_InitStructure; //Структура содержащая настройки порта
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); //Включаем тактирование порта D
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12| GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15; //Выбераем нужные вывод
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //Включаем режим выхода
	GPIO_Init(GPIOD, &GPIO_InitStructure); //вызов функции инициализации


	usart_init(); //Инициализируем UART
	//Настраиваем прерывания по приему
	__enable_irq(); //Глобальное включение прерывания
	NVIC_EnableIRQ(USART2_IRQn); //Включаем прерывания от UART
	NVIC_SetPriority(USART2_IRQn, 0); //Прерывание от UART, приоритет 0, самый высокий
	USART2->CR1 |= USART_CR1_RXNEIE; //Прерывание по приему

    while(1)
    {

    }
}


void USART2_IRQHandler (void)
{
		char uart_data;
		if (USART2->SR & USART_SR_RXNE) //Проверяем, прилош ли чтонибудь в UART
		{
		USART2->DR = USART2->DR; //Echo по приему, символ отправленный в консоль вернется
		uart_data=USART2->DR; //Считываем то что пришло в переменную...
		uart2_rx_buf[uart2_rx_bit]=USART2->DR; //Помещаем принятый байт в буфер.
	    uart2_rx_bit++; //Наращиваем счётчик байтов буфера.

	    if(uart_data=='\r') //Если пришло сообщение о нажатии Enter...
	    {
    		GPIO_ResetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); //Сбрасываем все пины в «0»
	    	if(strcmp(uart2_rx_buf,"led0\r")==0) //Если пришла команда "led0"
	    	{
	    		GPIO_SetBits(GPIOD, GPIO_Pin_12); //Подаем «1» на PD12
	    	}
	    	else if(strcmp(uart2_rx_buf,"led1\r")==0) //Если пришла команда "led1"
	    	{
	    		GPIO_SetBits(GPIOD, GPIO_Pin_13); //Подаем «1» на PD13
	    	}
	    	else if(strcmp(uart2_rx_buf,"led2\r")==0) //Если пришла команда "led2"
	    	{
	    		GPIO_SetBits(GPIOD, GPIO_Pin_14); //Подаем «1» на PD14
	    	}
	    	else if(strcmp(uart2_rx_buf,"led3\r")==0) //Если пришла команда "led3"
	    	{
	    		GPIO_SetBits(GPIOD, GPIO_Pin_15); //Подаем «1» на PD15
	    	}
	    	
	    	else
	    	{
	    		send_str("\n"); //Переходим на новую строку
	    		send_str("String: ");
	    		send_str(uart2_rx_buf); //Отправляем ее обратно в консоль
	    	}

			memset(uart2_rx_buf, 0, sizeof(uart2_rx_buf)); //Очищаем буфер
			uart2_rx_bit=0; //Сбрасываем счетчик
			send_str("\n");
		}
		}
}

faddistr
Posts: 15
Joined: 30 Apr 2014, 19:27

Re: STM32f4. Функция atoi.

Post by faddistr »

Чтобы перевести число из строки в число - надо отнять 0x30(цифры имеют аскии коды 0х30 - 0х39). Если число двухзначное XY, то bin=(X-0x30)*10+(Y-0x30). Аналогично для произвольной разрядности... Но в теории ничего не должно мешать сделать #include <stdlib.h> и воспользоваться стандартной функцией atoi
Rogers
Posts: 13
Joined: 30 Sep 2013, 21:37
Location: МО, Климовск

Re: STM32f4. Функция atoi.

Post by Rogers »

Добавляю посреди кода например в main или в начале обработчика в конце:

Code: Select all

int n; n =atoi(uart2_rx_buf); send_str(uart2_rx_buf);
ничего не срабатывает и в watch не отслеживается.
Если добавить во внутрь while(1). то после перезапуска n с char станет int, но просмотреть значение не удается.
Также был добавлен код для atoi()(со стандартным atoi в stdlib.h программа не реагирует):

Code: Select all

int atoi(char* s)
{
    int n = 0;
    while( *s >= '0' && *s <= '9' ) {
        n *= 10;
        n += *s++;
        n -= '0';
    }
    return n;
}
faddistr
Posts: 15
Joined: 30 Apr 2014, 19:27

Re: STM32f4. Функция atoi.

Post by faddistr »

Вроде бы должно работать, разве что int это знаковый тип, а у вас знак не учтен(иногда это критично). А по поводу вотча-есть в кейле такая бага, попробуйте обновить кейл и проверьте, что оптимизация отключена(оптимизатор может выбросить значение). Так-же все должно работать через просмотр памяти - для чего закиньте в качестве адреса &n(первые четыре будут ваше число в хексе, в little-endian).
Rogers
Posts: 13
Joined: 30 Sep 2013, 21:37
Location: МО, Климовск

Re: STM32f4. Функция atoi.

Post by Rogers »

Проблема решена написанием собственного atoi т.к. штатный atoi не работает.
Post Reply