Stránka 1 z 2
USART - atmega porovnání textového řetězce
Napsal: 08 kvě 2024, 19:18
od Nearduinista
Zdravím už několik dní řeším proč tenhle konkrétní příklad nefunguje. Pokud pošlu zprávu “on” měla by svítit ledka. Když to zadám do přerušení, tak to funguje, ale v hlavním programu nic pokud to nějak nezaobalím.
Kód: Vybrat vše
#include <avr/io.h>
#include <stdio.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <string.h>
#define UART_BAUD_RATE 9600
#define UART_BAUD_REGISTERS (((F_CPU / (UART_BAUD_RATE * 16UL))) - 1)
volatile char prijaty_znak=0;
char zprava[16];
ISR(USART_RX_vect)
{
static int i=0;
prijaty_znak = UDR;
if((prijaty_znak != '\n') && (prijaty_znak!='\r'))
{
zprava[i]=prijaty_znak;
i++;
}
else
{
zprava[i]='\0';
i=0;
}
}
int main(void){
UBRRL = UART_BAUD_REGISTERS;;
UCSRB = (1<<RXEN)|(1<<TXEN);
UCSRC = (1<<URSEL)|(1<<UCSZ0) |(1<<UCSZ1);
UCSRB |= (1 << RXCIE);
DDRA =0xff;
sei();
while(1){
if(strcmp(zprava,"on")==0){PORTA |= (1<<PORTA0);}
}
}
Napsal: 08 kvě 2024, 19:32
od Cowley
Napsal: 08 kvě 2024, 20:30
od Dumitru
Nearduinista píše:Zdravím už několik dní řeším proč tenhle konkrétní příklad nefunguje. Pokud pošlu zprávu “on” měla by svítit ledka. Když to zadám do přerušení, tak to funguje, ale v hlavním programu nic pokud to nějak nezaobalím.
Kód: Vybrat vše
#include <avr/io.h>
#include <stdio.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <string.h>
#define UART_BAUD_RATE 9600
#define UART_BAUD_REGISTERS (((F_CPU / (UART_BAUD_RATE * 16UL))) - 1)
volatile char prijaty_znak=0;
char zprava[16];
ISR(USART_RX_vect)
{
static int i=0;
prijaty_znak = UDR;
if((prijaty_znak != '\n') && (prijaty_znak!='\r'))
{
zprava[i]=prijaty_znak;
i++;
}
else
{
zprava[i]='\0';
i=0;
}
}
int main(void){
UBRRL = UART_BAUD_REGISTERS;;
UCSRB = (1<<RXEN)|(1<<TXEN);
UCSRC = (1<<URSEL)|(1<<UCSZ0) |(1<<UCSZ1);
UCSRB |= (1 << RXCIE);
DDRA =0xff;
sei();
while(1){
if(strcmp(zprava,"on")==0){PORTA |= (1<<PORTA0);}
}
}
Aký reťazec posielaš ak taký "on\r\n" pripadne "on\n\r" tak ? ten poslední znak ty prepíše 'o' na '\0'. skús poslať len "on\r" pripadne "on\n"
Ak posielaš len "on" tak tam chyba ukončovači znak "\0" pre funkciu strcmp()
a dávaj pozor niektoré terminály ty môžu znaky "\r\n" vkladať automaticky
Napsal: 08 kvě 2024, 20:50
od samec
char zprava[16]; musí byť volatile

Napsal: 08 kvě 2024, 20:58
od Nearduinista
samec píše:char zprava[16]; musí byť volatile

Pokud použiji příkaz na porovnávání řetězců strcmp, tak když nechám volatile, překladač dá varování: passing argument 1 of ‘strncmp’ discards qualifiers from pointer target type. A nefunguje to stejně
Napsal: 08 kvě 2024, 21:16
od Nearduinista
Dumitru píše:Nearduinista píše:Zdravím už několik dní řeším proč tenhle konkrétní příklad nefunguje. Pokud pošlu zprávu “on” měla by svítit ledka. Když to zadám do přerušení, tak to funguje, ale v hlavním programu nic pokud to nějak nezaobalím.
Kód: Vybrat vše
#include <avr/io.h>
#include <stdio.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <string.h>
#define UART_BAUD_RATE 9600
#define UART_BAUD_REGISTERS (((F_CPU / (UART_BAUD_RATE * 16UL))) - 1)
volatile char prijaty_znak=0;
char zprava[16];
ISR(USART_RX_vect)
{
static int i=0;
prijaty_znak = UDR;
if((prijaty_znak != '\n') && (prijaty_znak!='\r'))
{
zprava[i]=prijaty_znak;
i++;
}
else
{
zprava[i]='\0';
i=0;
}
}
int main(void){
UBRRL = UART_BAUD_REGISTERS;;
UCSRB = (1<<RXEN)|(1<<TXEN);
UCSRC = (1<<URSEL)|(1<<UCSZ0) |(1<<UCSZ1);
UCSRB |= (1 << RXCIE);
DDRA =0xff;
sei();
while(1){
if(strcmp(zprava,"on")==0){PORTA |= (1<<PORTA0);}
}
}
Aký reťazec posielaš ak taký "on\r\n" pripadne "on\n\r" tak ? ten poslední znak ty prepíše 'o' na '\0'. skús poslať len "on\r" pripadne "on\n"
Ak posielaš len "on" tak tam chyba ukončovači znak "\0" pre funkciu strcmp()
a dávaj pozor niektoré terminály ty môžu znaky "\r\n" vkladať automaticky
Například takhle už to funguje v pohodě ale proč? Tady defakto jen počkám až se zpráva nahraje celá . A potom vyhodnotím řetězec zda je stejný nebo není. To mě vrtá už několik dnů hlavou.
Kód: Vybrat vše
#include <avr/io.h>
#include <stdio.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <string.h>
#define UART_BAUD_RATE 9600
#define UART_BAUD_REGISTERS (((F_CPU / (UART_BAUD_RATE * 16UL))) - 1)
volatile char prijaty_znak=0;
volatile int prijato=0;
char zprava[16];
ISR(USART_RX_vect)
{
static int i=0;
prijaty_znak = UDR;
if((prijaty_znak != '\n') && (prijaty_znak!='\r'))
{
zprava[i]=prijaty_znak;
i++;
}
else
{
zprava[i]='\0';
prijato=1;
i=0;
}
}
int main(void)
{
UBRRL = UART_BAUD_REGISTERS;
UCSRB = (1<<RXEN)|(1<<TXEN);
UCSRC = (1<<URSEL)|(1<<UCSZ0) |(1<<UCSZ1);
UCSRB |= (1 << RXCIE);
DDRD=0b00000010;
DDRA =0xff;
sei();
while(1)
{
if(prijato==1)
{
if(strcmp(zprava,"on")==0)
{
PORTA |=(1<<PORTA1);
}
prijato=0;
}
}
}
Napsal: 08 kvě 2024, 21:25
od samec
Ach jaj, strcmp. Používaš čarovné funkcie, tak máš čarovné výsledky.
Napsal: 08 kvě 2024, 21:36
od Dumitru
neviem koľko trvá kym sa funkcia strcmp vykoná ale v prvom prípade ju voláš dookola v maine a ako už som písal ak pošleš „on\r\n“ tak sa do bufra uloží zaprava[0] = „o“ a zaprava[1] = „n“ potom „\r“ zaprava[2] = „\0“ vynuluje i=0 a „\n“ do zprava[i=0] kde je uložene „o“ prepíše na „\0“ a ak strcmp tráva dlhšie ako prijatie jedného znaku tak potom to nesedí v druhom prípade spustíš strcmp len raz pravé vtedy keď sprava je korektná.
Napsal: 08 kvě 2024, 21:37
od rnbw
V skompilovanom kod mozno ani ziadny strcmp nebude, pretoze kompilator usudi, ze dana podmienka sa nemoze nikdy splnit a pri optimalizacii ho odstrani.
Kód: Vybrat vše
$ cat test.c
#include <stdio.h>
#include <string.h>
char zprava[16];
int main() {
while (1) {
if (strcmp(zprava,"on") == 0)
printf("AAAAAA\n");
}
}
$ cc test.c -o test
$ strings test | grep strcmp
strcmp
strcmp@GLIBC_2.0
$ cc test.c -O2 -o test
$ strings test | grep strcmp
$
Napsal: 08 kvě 2024, 21:58
od Nearduinista
Dumitru píše:neviem koľko trvá kym sa funkcia strcmp vykoná ale v prvom prípade ju voláš dookola v maine a ako už som písal ak pošleš „on\r\n“ tak sa do bufra uloží zaprava[0] = „o“ a zaprava[1] = „n“ potom „\r“ zaprava[2] = „\0“ vynuluje i=0 a „\n“ do zprava[i=0] kde je uložene „o“ prepíše na „\0“ a ak strcmp tráva dlhšie ako prijatie jedného znaku tak potom to nesedí v druhom prípade spustíš strcmp len raz pravé vtedy keď sprava je korektná.
Tož mě to taky napadlo, tak jsem se to pro zkoušku jal vyřešit takhle. A furt to nejede hm...
Kód: Vybrat vše
ISR(USART_RX_vect)
{
static int i=0;
prijaty_znak = UDR;
if((prijaty_znak != '\n') && (prijaty_znak!='\r'))
{
zprava[i]=prijaty_znak;
i++;
}
else
{
if(i>0)
{
zprava[i]='\0';
}
i=0;
}
}
Napsal: 08 kvě 2024, 22:24
od Dumitru
Nearduinista píše:Dumitru píše:neviem koľko trvá kym sa funkcia strcmp vykoná ale v prvom prípade ju voláš dookola v maine a ako už som písal ak pošleš „on\r\n“ tak sa do bufra uloží zaprava[0] = „o“ a zaprava[1] = „n“ potom „\r“ zaprava[2] = „\0“ vynuluje i=0 a „\n“ do zprava[i=0] kde je uložene „o“ prepíše na „\0“ a ak strcmp tráva dlhšie ako prijatie jedného znaku tak potom to nesedí v druhom prípade spustíš strcmp len raz pravé vtedy keď sprava je korektná.
Tož mě to taky napadlo, tak jsem se to pro zkoušku jal vyřešit takhle. A furt to nejede hm...
Kód: Vybrat vše
ISR(USART_RX_vect)
{
static int i=0;
prijaty_znak = UDR;
if((prijaty_znak != '\n') && (prijaty_znak!='\r'))
{
zprava[i]=prijaty_znak;
i++;
}
else
{
if(i>0)
{
zprava[i]='\0';
}
i=0;
}
}
a sisi isty ze tam chodia znaky \r a \n inak sa ty tam nikdy nedostane \0
skus takto
Kód: Vybrat vše
volatile char zprava[16];
ISR(USART_RX_vect)
{
static int i=0;
prijaty_znak = UDR;
if((prijaty_znak != '\n') && (prijaty_znak!='\r'))
{
zprava[i]=prijaty_znak;
i++;
zprava[i] = '\0';
}
else
{
if(i>0)
{
zprava[i]='\0';
}
i=0;
}
}
a v maine
Kód: Vybrat vše
if (strcmp((char *)zprava,(char *)"on\0") == 0)
Napsal: 08 kvě 2024, 22:37
od Nearduinista
Jistý už si nejsem ničím, každopádně pokračování zase zítra po práci už mám z toho bolehlav.
Napsal: 08 kvě 2024, 23:40
od samec
tak nič
Napsal: 09 kvě 2024, 13:02
od mhepp
A není problém v té proměnné i?
Kód: Vybrat vše
...
volatile char zprava[16];
ISR(USART_RX_vect)
{
static int i=0;
...
}
Při každém volání ISR dojde k inicializaci proměnné i na 0, takže to vlastně neukládá nic... Z i bych udělal globální proměnnou:
Kód: Vybrat vše
...
volatile int prijato=0;
volatile char zprava[16];
volatile int i=0;
ISR(USART_RX_vect)
{
prijaty_znak = UDR;
//chybi osetreni delky vstupu - if (i>14) {...}
if((prijaty_znak != '\n') && (prijaty_znak!='\r'))
{
zprava[i]=prijaty_znak;
i++;
zprava[i]=0;
} else {
i=0;
prijato=1;
}
}
Napsal: 09 kvě 2024, 13:42
od Dumitru