Да хоть так, главная тут задача, отвязаться от c = uart_receive(); на время выполнения условия с циклом for, вот никак не смог отвязать разве что часто нажатием какой нибудь клавишиAlexandrRa писал(а):так правильней.
Автоматический выход из ждущего режима uart_receive();
Re: Автоматический выход из ждущего режима uart_receive();
Последний раз редактировалось Sulik Чт авг 11, 2022 21:14:51, всего редактировалось 3 раза.
- Реклама
-
AlexandrRa
- Открыл глаза
- Сообщения: 75
- Зарегистрирован: Чт ноя 26, 2020 13:19:49
Re: Автоматический выход из ждущего режима uart_receive();
Код: Выделить всё
void uart_handler_RX(void)
{
if (y < Size_data) // если весь пакет не принят
{
data[y] = UDR0; // запись следующего байта data[y]
y++; // счётчик байт
return;
}
y=0;
}
Добавлено after 2 minutes 18 seconds:
Код: Выделить всё
uint8_t flag = 0;
uint8_t Size_data = 12; // например передаём 12 байт
ISR(PCINT0_vect){
if(PINB & (1 << PB0)) flag = 1; // Разрешение передачи данных
}
int main(){
UART_init();
interrupt_init();
sei();
while(1){
if (flag){
for (y = 0; y < Size_data ; y++){
uart_transmit(data[y]);
}
flag = 0; // Данные переданы
}
}Добавлено after 3 minutes 10 seconds:
Что за МК хоть?
Последний раз редактировалось AlexandrRa Чт авг 11, 2022 16:26:00, всего редактировалось 1 раз.
Re: Автоматический выход из ждущего режима uart_receive();
Иногда очень необходимо бывает закрыться именно "\0", есть такие моменты в коде где именно так необходимо учитывая, что количество символов в одном массиве данных могут быть разной длины, то увеличится эта длина то уменьшится.AlexandrRa писал(а):И не закрывай посылку значением данных в передаче. Отучайся от этого.
Добавлено after 2 minutes 34 seconds:
Atmega 328PAlexandrRa писал(а):Что за МК хоть?
Добавлено after 2 minutes 59 seconds:
Это у меня добавлено, просто код я привел как примерAlexandrRa писал(а):И добавь прерывание по приёму
Последний раз редактировалось Sulik Чт авг 11, 2022 21:07:56, всего редактировалось 1 раз.
-
AlexandrRa
- Открыл глаза
- Сообщения: 75
- Зарегистрирован: Чт ноя 26, 2020 13:19:49
Re: Автоматический выход из ждущего режима uart_receive();
Передавай в первом байте размер пакета. Аналогично и при приёме делай. Избежишь проблем. Представь что у тебя в пакете байт по середине указывает на открытие или закрытия 8 дверей. В какой то момент можно передать не всю посылку, а лишь часть её.
Re: Автоматический выход из ждущего режима uart_receive();
Он нужен в другом коде, просто приведенном мною примере он не нужен, но он нужен это для приема неких команд и отправка этих команд в нужное условие с даннымиAlexandrRa писал(а):и с на фиг ненужно стало
Добавлено after 6 minutes 32 seconds:
Задача тут очень понятная, например консоль putty будет постоянно открыть по UART с МК, ждет ввода команд с клавы, но в то же время как только придет нужное прерывание отвязаться от uart_receive(); и начал обрабатывать другое условие с циклом с выводом данных на консоль и после обработки вернулась в тот же режим uart_receive();
Последний раз редактировалось Sulik Чт авг 11, 2022 21:07:09, всего редактировалось 1 раз.
- Реклама
- Starichok51
- Модератор
- Сообщения: 19055
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Автоматический выход из ждущего режима uart_receive();
Sulik, смотри, в каком сообщении ты жмешь кнопку "цитата".
а то получается, что всё тобой процитированное, написано тобой, а не тем человеком, откуда ты взял цитату.
а то получается, что всё тобой процитированное, написано тобой, а не тем человеком, откуда ты взял цитату.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
-
AlexandrRa
- Открыл глаза
- Сообщения: 75
- Зарегистрирован: Чт ноя 26, 2020 13:19:49
Re: Автоматический выход из ждущего режима uart_receive();
Нафига сидеть и ждать приёма? За этим прекрасно сможет следить флаг прерывания. А нужное прерывание смотри по флагу или данным в основном цикле. В этом случае ты всегда будешь отвязан от uart_receive(). И я бы лучше уходил в сон во время ожидания приёма, вместо того чтобы жрать энергию.Задача тут очень понятная, например консоль putty будет постоянно открыть по UART с МК, ждет ввода команд с клавы, но в то же время как только придет нужное прерывание отвязаться от uart_receive(); и начал обрабатывать другое условие с циклом с выводом данных на консоль и после обработки вернулась в тот же режим uart_receive();
Re: Автоматический выход из ждущего режима uart_receive();
Вам командная консоль нужна или как?Sulik писал(а):Задача тут очень понятная,
А команды какого вида, по символьные или пакетные, заканчивающие определенным символом или еще как?
-
codenamehawk
- Вымогатель припоя
- Сообщения: 532
- Зарегистрирован: Вт фев 09, 2010 17:52:26
Re: Автоматический выход из ждущего режима uart_receive();
[uquote="AlexandrRa",url="/forum/viewtopic.php?p=4271521#p4271521"]Не советую так делать, есть возможность прочитать не тот байт или потерять вообще всю посылку. Т. к. чтение данных будет только один раз за цикл. А если данные приходят несколько раз за цикл и неизвестно когда по времени? Очень легко пропустить посылку.[/uquote]
Расскажите это тем кто написал и тем кто применяет software serial.
Если бездумно сидеть в цикле, то всегда существует вероятность потерять данные, даже если применяются прерывания.
Приведенный код будет работать, но если есть аппаратная поддержка, то не применять аппаратные прерывания нет смысла.
Расскажите это тем кто написал и тем кто применяет software serial.
Если бездумно сидеть в цикле, то всегда существует вероятность потерять данные, даже если применяются прерывания.
Приведенный код будет работать, но если есть аппаратная поддержка, то не применять аппаратные прерывания нет смысла.
Re: Автоматический выход из ждущего режима uart_receive();
[uquote="Dimon456",url="/forum/viewtopic.php?p=4272265#p4272265"]
А команды какого вида, по символьные или пакетные, заканчивающие определенным символом или еще как?[/uquote]
Да именно консоль, а команды могут быть и те и другие, по ситуации.
Вам командная консоль нужна или как?Sulik писал(а):Задача тут очень понятная,
А команды какого вида, по символьные или пакетные, заканчивающие определенным символом или еще как?[/uquote]
Да именно консоль, а команды могут быть и те и другие, по ситуации.
Re: Автоматический выход из ждущего режима uart_receive();
Вот пример, смотрите
поддержка по символьных или пакетных команд, заканчивающих символом ENTER
поддержка примитивного редактирования при помощи backspace
код написан под компилятор CVAVR, то есть под компилятор winavr (interrupt [USART_RXC] void usart_rx_isr(void)) надо поменять на ISR(USART_RX_vect) и #asm("sei") на sei();
по умолчанию строка вида '0' - turn off LED располагается в RAM ее надо перенести во FLASHна CVAVR этот код занимает 405 байт RAM и 2156 байт FLASH
Спойлер
реализован кольцевой буфер приемаподдержка по символьных или пакетных команд, заканчивающих символом ENTER
поддержка примитивного редактирования при помощи backspace
код написан под компилятор CVAVR, то есть под компилятор winavr (interrupt [USART_RXC] void usart_rx_isr(void)) надо поменять на ISR(USART_RX_vect) и #asm("sei") на sei();
по умолчанию строка вида '0' - turn off LED располагается в RAM ее надо перенести во FLASH
Код: Выделить всё
#include <mega328p.h>
// Standard Input/Output functions
#include <stdio.h>
// Declare your global variables here
#define DATA_REGISTER_EMPTY (1<<UDRE0)
#define RX_COMPLETE (1<<RXC0)
#define FRAMING_ERROR (1<<FE0)
#define PARITY_ERROR (1<<UPE0)
#define DATA_OVERRUN (1<<DOR0)
// USART Receiver buffer
#define MAX_DMA_BUFFERS_COUNT 32 // 4 8 16 32 64 128
#define BUFFER_MASK (MAX_DMA_BUFFERS_COUNT-1)
volatile unsigned char BUFF_RX_BUF[MAX_DMA_BUFFERS_COUNT]={0};
volatile unsigned char DMA_WR_BUF = 0;
volatile unsigned char DMA_RD_BUF = 0;
// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSR0A;
data=UDR0;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
BUFF_RX_BUF[DMA_WR_BUF] = data;
DMA_WR_BUF++;
DMA_WR_BUF &= BUFFER_MASK;
}
}
#include <string.h>
char b_start=0, b_end=0, len_buff=0, len=0;
bit flag=0;
char buff[24]; // максимальная длинна команды
unsigned long main_p=0;
unsigned long my_atoi(char *str)
{
unsigned long result = 0;
if ('0'>*str || *str>'9')
{
str++;
}
while (*str != '\0')
{
if ('0'> *str || *str>'9')
break;
else
result = result * 10 + (*str++ - '0');
}
return result;
}
static char respcmp(char *s, const char *resp){
while(*resp)
if(*resp++ != *s++) return 0;
return 1;
}
void usart_send_str(const char* str)
{
while(*str) {
while (!(UCSR0A & (1<<UDRE0))) {}
UDR0 = *str++;
}
}
#define SEND(str) usart_send_str(str)
void help(void) // HELP
{
SEND("\r\n");
SEND("\t'0' - turn off LED\r\n");
SEND("\t'1' - turn on LED\r\n");
SEND("\t'LED ON' - turn on LED\r\n");
SEND("\t'LRD OFF' - turn off LED\r\n");
SEND("\t'TOGGLE' - turn toggle LED\r\n");
SEND("\t'COUNT=N' - set all value by N (decimal):\r\n");
SEND("\tSTAT - shows which mode the automatic/off mode is in\r\n");
SEND("\tHELP - help\r\n");
SEND("\r\n");
}
// print 32bit unsigned int
void printu(unsigned long val){
char bufa[11];
char bufb[10];
int i;
int l = 0, bpos = 0;
if(!val){
bufa[0] = '0';
l = 1;
}else{
while(val){
bufb[l++] = val % 10 + '0';
val /= 10;
}
bpos += l;
for(i = 0; i < l; ++i){
bufa[--bpos] = bufb[i];
}
}
bufa[l + bpos] = 0;
SEND(bufa);
}
void main(void)
{
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART0 Mode: Asynchronous
// USART Baud Rate: 9600
UCSR0A=(0<<RXC0) | (0<<TXC0) | (0<<UDRE0) | (0<<FE0) | (0<<DOR0) | (0<<UPE0) | (0<<U2X0) | (0<<MPCM0);
UCSR0B=(1<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0) | (1<<RXEN0) | (1<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80);
UCSR0C=(0<<UMSEL01) | (0<<UMSEL00) | (0<<UPM01) | (0<<UPM00) | (0<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00) | (0<<UCPOL0);
UBRR0H=0x00;
UBRR0L=0x67;
// Global enable interrupts
#asm("sei")
while (1)
{
// Place your code here
while (DMA_RD_BUF != (DMA_WR_BUF)) {
b_start = DMA_RD_BUF; // Копируем позиции начала
DMA_RD_BUF++;
DMA_RD_BUF &= BUFFER_MASK;
b_end = DMA_RD_BUF; // и конца буфера
// сборка команды
len_buff = strlen((void*)buff); // определяем длину
if(b_start < b_end) {
len = b_end-b_start;
memcpy(&buff[len_buff],(void*)&BUFF_RX_BUF[b_start],len);
buff[len_buff+len]=0;
}
if(b_start > b_end) {
len = MAX_DMA_BUFFERS_COUNT-b_start;
memcpy(&buff[len_buff],(void*)&BUFF_RX_BUF[b_start],len);
memcpy(&buff[len],BUFF_RX_BUF,b_end);
buff[len_buff+len+b_end]=0;
}
// если BkSp - сдвигаем назад
len_buff = strlen((void*)buff)-1; // определяем длину
if((buff[len_buff] == 0x08)|| (buff[len_buff] == 0x7f)){
// стираем символ
// но не левее начала буфера
if(len_buff > 0) buff[len_buff-1]=0; else buff[len_buff]=0;
}
// если Enter - ввод закончен
if(((buff[len_buff] == '\n') || (buff[len_buff] == '\r'))) {
flag=1; buff[len_buff]='\0'; // стираем символ Enter, заменяем концом строки \0
}
}
// поиск обработчика
if(flag) {
len_buff = strlen((void*)buff); // определяем длину команды
// если не использовать по символьные команды, то len_buff не нужен
if(respcmp((void*)buff, "1") && len_buff == strlen("1")) { // это просто пример
PORTB |= (1<<(0));
}
if(respcmp((void*)buff, "0")&& len_buff == strlen("0")) {
PORTB &= ~(1<<(0));
}
if(respcmp((void*)buff, "LED ON") && len_buff == strlen("LED ON")) {
PORTB |= (1<<(0));
}
if(respcmp((void*)buff, "LED OFF") && len_buff == strlen("LED OFF")) {
PORTB &= ~(1<<(0));
}
if(respcmp((void*)buff, "TOGGLE") && len_buff == strlen("TOGGLE")) {
PORTB ^= (1<<(0));
}
if(respcmp((void*)buff, "COUNT=")) {
main_p = my_atoi((buff + sizeof("COUNT=")-1));
}
if(respcmp((void*)buff, "PRINT") && len_buff == strlen("PRINT")) {
SEND("\r\nPRINT= "); printu(main_p);SEND("\r\n");
}
if(respcmp((void*)buff, "HELP") && len_buff == strlen("HELP")) {
help();
}
buff[0]=0;
flag=0;
}
}
}


