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

 
 
 
Reply to this topicStart new topic
> STM32, USART, прерывание и выход из него
Balabes
сообщение Apr 21 2014, 12:47
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 66
Регистрация: 8-07-13
Пользователь №: 77 442



Здравствуйте!
Хочется сделать что-то похожее на систему команд и принимать с клавиатуры control_word и через if настраивать параметры USART2 и далее что-то другое. Пытаюсь принять в прерывании control_word внутри прерывания работает, а вот выйти из прерывания не получается. Во всяком случае что-то подобное, пошагово через JTAG перестает исполняться как только ввожу хоть 1 символ с клавиатуры. Подскажите в чем я дурак. Спасибо.
CODE
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_usart.h"
#include "stm32f10x_flash.h"
#include "stm32f10x.h"
#include "misc.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define FLASH_PAGE_SIZE ((u16)0x800)
#define START_ADDR ((u32)0x0803F800)
#define END_ADDR ((u32)0x08040000)
#define USART_SPEED_ADDR ((u32)0x0803F800)
#define HW_FlowControl_ADDR ((u32)0x0803F804)
#define PARITY_ADDR ((u32)0x0803F808)
#define STOPBIT_ADDR ((u32)0x0803F80C)

typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;

u32 EraseCounter = 0x00, Address = 0x00,
USART_speed = 0, RData = 0,NbrOfPage = 0x00,
HWF_Control = 0, Parity_bit = 0, Stop_bit = 0;

volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;
volatile TestStatus MemoryProgramStatus = PASSED;

u8 change_var = '0', change_speed = '0', yesno = '0';

char* control_word = "load";

void USART_SendSymbol(USART_TypeDef *USARTx, u8 data)
{
while((USART_GetFlagStatus(USARTx, USART_FLAG_TC)) == RESET);
USART_SendData(USARTx, data);
}

void USART_SendString(USART_TypeDef *USARTx, char *content)
{

u8 i = 0;
while(content[i])
{
USART_SendSymbol(USARTx, content[i++]);
}
USART_SendSymbol(USARTx, '\r');
USART_SendSymbol(USARTx, '\n');

}

u8 USART_ReceiveSymbol(USART_TypeDef *USARTx)
{
u8 data = 0;
while((USART_GetFlagStatus(USARTx, USART_FLAG_RXNE)) == RESET);
data = USART_ReceiveData(USARTx);
return data;
}

char *USART_ReceiveString(USART_TypeDef *USARTx)
{
char *res;
int len;
u8 data;
len = 0;
res = (char *)malloc(len);
if (!res)
return NULL;
res[0] = '\0';
while(1)
{
data = USART_ReceiveSymbol(USARTx);
if (data > 0x0)
{
res = (char *)realloc(res, (len+1)*sizeof(char));
if (!res)
return NULL;
res[len++] = data;
if (data == '.')
{
res[--len] = '\0';
break;

}
}
}
return res;
}

void USARTx_slave_config (USART_TypeDef *USARTx, u32 USART_speed)
{
USART_InitTypeDef USART_slave_struct;

USART_slave_struct.USART_BaudRate = USART_speed;
USART_slave_struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_slave_struct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_slave_struct.USART_Parity = USART_Parity_No;
USART_slave_struct.USART_StopBits = USART_StopBits_1;
USART_slave_struct.USART_WordLength = USART_WordLength_8b;

USART_Init(USARTx, &USART_slave_struct);
USART_Cmd(USARTx, ENABLE);

}

u32 FLASH_ReadWord (u32 Adr)
{
u32 rec = 0;
rec = (*(__IO u32*) Adr + 3);
rec = (*(__IO u32*) Adr + 2);
rec = (*(__IO u32*) Adr + 1);
rec = (*(__IO u32*) Adr);

return rec;

}

u16 FLASH_ReadHalfWord (u32 Adr)
{
u16 rec = 0;
rec = (*(__IO u32*) Adr + 1);
rec = (*(__IO u32*) Adr);

return rec;

}

void USART_SendHEX(USART_TypeDef *USARTx, u8 data)
{
const u8 digits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
if (data<16)
{
USART_SendSymbol(USARTx,'0');
USART_SendSymbol(USARTx, digits[data]);
} else
{
USART_SendSymbol(USARTx, digits[(data & 0xF0) >> 4]);
USART_SendSymbol(USARTx, digits[(data & 0x0F)]);
}
USART_SendSymbol(USARTx, '\r');
USART_SendSymbol(USARTx, '\n');
}

void FLASH_Write (u32 START, u32 END, u32 PAGE_SIZE, u32 USART_ADDR, u32 speed)
{
/* Unlock the Flash Bank Program Erase controller */
FLASH_Unlock();

/* Define the number of page to be erased */
NbrOfPage = (END - START) / PAGE_SIZE;

/* Clear All pending flags */
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);

/* Erase the FLASH pages */
for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
{
FLASHStatus = FLASH_ErasePage(START + (PAGE_SIZE * EraseCounter));
}
/* Program Flash Bank */
/* Write USART speed */

if (FLASHStatus == FLASH_COMPLETE)
{
FLASHStatus = FLASH_ProgramWord(USART_ADDR, speed);
}
FLASH_Lock();
/* Check the corectness of written data */

if (MemoryProgramStatus != FAILED)
{
if((*(__IO u32*) USART_ADDR) != speed)
{
MemoryProgramStatus = FAILED;
}
}
if( MemoryProgramStatus == FAILED)
{
USART_SendString(USART3, "Data is incorrect!");
}
}

void USART_SendInt(USART_TypeDef *USARTx, u32 data)
{
unsigned char temp[10],count=0;
if (data)
{
while (data)
{
temp[count++]=data%10+'0';
data/=10;
}
while (count)
USART_SendSymbol(USARTx, temp[--count]);
}
else USART_SendSymbol(USARTx, '0');
USART_SendSymbol(USARTx, '\r');
USART_SendSymbol(USARTx, '\n');
}

void FromStrToChar(char* str, char mas[])
{
int i = 0;
while (i < strlen(str))
{
mas[i] = str[i];
i++;
}
}

void USART3_IRQHandler()
{
/*int i = 0;
if (USART_GetFlagStatus(USART3, USART_FLAG_RXNE) != RESET)
{
symb = USART_ReceiveSymbol(USART3);
if (i == 10)
{
control_word[i] = symb;
i = 0;
}
else
{
control_word[i++] = symb;
}
control_word[i] = '\0';
}*/

control_word = USART_ReceiveString(USART3);
USART_ClearFlag(USART3, USART_FLAG_RXNE);
NVIC_DisableIRQ(USART3_IRQn);
}

/*void delay (unsigned int DelayValue)
{
for (; DelayValue != 0; DelayValue--) __NOP;
}*/

void Periph_init()
{
//Clock ON for GPIOB/GPIOD/AFIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);
//Clock ON for USART2/3
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 | RCC_APB1Periph_USART3, ENABLE);


GPIO_InitTypeDef PD_config;
GPIO_InitTypeDef PB_config;
USART_InitTypeDef USART_config;
NVIC_InitTypeDef NVIC_config;

// Priority Group
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

// Enable the USART3 Interrupt
NVIC_config.NVIC_IRQChannel = USART3_IRQn;
NVIC_config.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_config.NVIC_IRQChannelSubPriority = 0;
NVIC_config.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_config);

// Allow RXNE
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);

//USART2 Pin Remap
GPIO_PinRemapConfig(GPIO_Remap_USART2 | GPIO_FullRemap_USART3, ENABLE);

// USART2 TX | Port = D Pin = 5
PD_config.GPIO_Pin = GPIO_Pin_5;
PD_config.GPIO_Mode = GPIO_Mode_AF_PP;
PD_config.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOD, &PD_config);

// USART2 RX | Port = D Pin = 6
PD_config.GPIO_Pin = GPIO_Pin_6;
PD_config.GPIO_Mode = GPIO_Mode_IN_FLOATING;
PD_config.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOD, &PD_config);

// USART3 TX | Port = D Pin = 8
PD_config.GPIO_Pin = GPIO_Pin_8;
PD_config.GPIO_Mode = GPIO_Mode_AF_PP;
PD_config.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOD, &PD_config);

// USART3 RX | Port = D Pin = 9
PD_config.GPIO_Pin = GPIO_Pin_9;
PD_config.GPIO_Mode = GPIO_Mode_IN_FLOATING;
PD_config.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOD, &PD_config);

// LED | Port = B Pin = 9
PB_config.GPIO_Pin = GPIO_Pin_9;
PB_config.GPIO_Mode = GPIO_Mode_Out_PP;
PB_config.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &PB_config);

// USART 2/3
USART_config.USART_BaudRate = 9600;
USART_config.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_config.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_config.USART_Parity = USART_Parity_No;
USART_config.USART_StopBits = USART_StopBits_1;
USART_config.USART_WordLength = USART_WordLength_8b;
USART_Init(USART3, &USART_config);

// Enable USART2/3
USART_Cmd(USART3, ENABLE);
}

int main(void)
{
SystemInit();
Periph_init();

while(1)
{
if (strcmp(control_word, "load") == 0)
{
USART_speed = FLASH_ReadWord(USART_SPEED_ADDR);
if (USART_speed == 0xFFFFFFFF)
{
USART_SendString(USART3, "USART don't have the speed Setting");
}
else
{
USART_SendString(USART3, "Current USART speed is:");
USART_SendInt(USART3, USART_speed);
}
HWF_Control = FLASH_ReadWord(HW_FlowControl_ADDR);
if (HWF_Control == 0xFFFFFFFF)
{
USART_SendString(USART3, "USART HardwareFlowControl Setting is empty");
}
else
{
if (HWF_Control == 0x00000000)
{
USART_SendString(USART3, "USART HardwareFlowControl Setting is: None");
}
if (HWF_Control == 0x00000300)
{
USART_SendString(USART3, "USART HardwareFlowControl Setting is: CTS/RTS");
}
}
Parity_bit = FLASH_ReadWord(PARITY_ADDR);
if (Parity_bit == 0xFFFFFFFF)
{
USART_SendString(USART3, "USART Parity bit Setting is empty");
}
else
{
if (Parity_bit == 0x00000000)
{
USART_SendString(USART3, "USART Parity bit Setting is: No");
}

if (Parity_bit == 0x00000400)
{
USART_SendString(USART3, "USART Parity bit Setting is: Even");
}

if (Parity_bit == 0x00000600)
{
USART_SendString(USART3, "USART Parity bit Setting is: Odd");
}
}
Stop_bit = FLASH_ReadWord(STOPBIT_ADDR);
if (Stop_bit == 0xFFFFFFFF)
{
USART_SendString(USART3, "USART Stop bit Setting is empty");
}
else
{
if (Stop_bit == 0x00000000)
{
USART_SendString(USART3, "USART Stop bit Setting is: 1");
}

if (Stop_bit == 0x00003000)
{
USART_SendString(USART3, "USART Stop bit Setting is: 1,5");
}

if (Stop_bit == 0x00002000)
{
USART_SendString(USART3, "USART Stop bit Setting is: 2");
}
}

control_word = "nothing";
}

if (strcmp(control_word, "br9600") == 0)
{
USART_speed = 9600;
USART_SendString(USART3, "USART speed set to 9600");
control_word = "nothing";

}

if (strcmp(control_word, "br19200") == 0)
{
USART_speed = 19200;
USART_SendString(USART3, "USART speed set to 19200");
control_word = "nothing";

}

if (strcmp(control_word, "br115200") == 0)
{
USART_speed = 115200;
USART_SendString(USART3, "USART speed set to 115200");
control_word = "nothing";

}

if (strcmp(control_word, "nothing") == 0)
{

}
}
return 0;
}


Сообщение отредактировал IgorKossak - Apr 21 2014, 13:55
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 21 2014, 20:48
Сообщение #2


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



malloc и realloc(!) в прерывании - это чересчур.
К тому же у вас вот тут ошибка:
Цитата(Balabes @ Apr 21 2014, 18:47) *
Код
    len = 0;
    res = (char *)malloc(len);
    if (!res)
        return NULL;
    res[0] = '\0';

Вы распределяете буфер на 0 символов, и сразу же записываете туда символ '\0'.

Попробуйте для начала вызывать ваш USART_ReceiveString() не из прерывания, а из main(). Ну и заведите буфер для команд размером с самую длинную команду, и уберите malloc/realloc.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Balabes
сообщение Apr 22 2014, 05:33
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 66
Регистрация: 8-07-13
Пользователь №: 77 442



в main() функция работает нормально, хотя согласен динамическая память это перебор, просто не выходит у меня из обработчика прерывания программа
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 22 2014, 07:45
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Balabes @ Apr 22 2014, 08:33) *
в main() функция работает нормально,
То есть тот факт, что вы пишете за пределы выделенной вам памяти и портите неизвестно что вас не смущает?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Balabes
сообщение Apr 22 2014, 08:32
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 66
Регистрация: 8-07-13
Пользователь №: 77 442



нуууу это нехорошо, но пока проблем никаких не было, я уже исправил
Go to the top of the page
 
+Quote Post

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

 


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


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