Пн янв 09, 2023 17:18:15
Вт янв 10, 2023 00:24:47
Вт янв 10, 2023 02:54:03
Вт янв 10, 2023 03:17:36
Пн янв 16, 2023 14:35:25
Пн янв 16, 2023 16:41:48
Вт янв 17, 2023 10:24:46
struct Serv485u8// данные выдаются в формате char
{
unsigned char Addr; //1 1
unsigned char contr; //1 2//0x5A
unsigned short len; //2 4
unsigned char pak[2];//2 6
unsigned char c[1024];//передаваемые данные
};
struct
{
unsigned char pac;
unsigned char read;
}uk;//указатель на точки чтения и записи
unsigned char uart_rx[1024]; // кольцевой буфер приёма
unsigned char adr = 0x50;
void InPac();
bool СheckCRC485(unsigned char *Buff, unsigned short len);
void ReadPac(unsigned char * pcBlock, unsigned short len);
//----------
void __ISR(_UART_2_VECTOR, IPL1AUTO) UART2Interrupt(void)//
{
unsigned short i0=10;//блокировка зацикливания
if(IFS1bits.U2EIF)//проверить на наличие ошибок
{
CheckError(); //читаем биты ошибок
}
else
{ // ошибок нет, читаем
do
{
uart_rx[uk.pak] = U2RXREG;
if(uk.pak<sizeof(uart_rx)-1)//индекс сдвинули на байт
uk.pak++;
else uk.pak=0;
i0--;
} while(U2STAbits.URXDA && i0);
}
IFS1bits.U2RXIF=0; //сброс флага прерывания
}
//========================
void main()
{
while(1)
{
if((uk.pac - uk.read) >4)
InPac();
// тут ещё много всяких if'ов которые по флагам от таймеров и иных прерываний выполняют различные задания
}
}
//----------
void InPac()
{
struct Serv485u8 *serv;
while(uk.read!=uk.pac)// пока всё не прочитаем
// помню что буфер кольцевой, но этот вопрос буду решать позже, главное с выравниванием разобраться
{
if(uart_rx[uk.read]==adr && uart_rx[uk.read+1]==0x5A)//;
{//собираем пакет
serv=(void*)&uart_rx[uk.read];// можно было и так serv=(struct Serv485u8*)&uart_rx[uk.read]; но ничего особо не меняет
//если uk.read не чётное число, адрес получается тоже нечётный
//если обратиться к структуре(например serv->len) то тут вылетаем в ошибку
if(serv->len < (uk.pac - uk.read))//если пришёл весь пакет
{
if(СheckCRC485(uart_rx[uk.read], serv485->len-2))
{
ReadPac(uart_rx[uk.read], serv485->len-2);//передаём пакет на разборку
uk.read+=serv485->len; // данные считали, двинули указатель чтения
if(uk.read>=sizeof(uart_rx))//если вышли за пределы кольцевого массива, вернутся к началу
uk.read-=sizeof(uart_rx);
}
else uk.read++;
}
else break; // выходим, зайдём в следующий раз, возможно к тому моменту успеет всё собраться
}
else// не нашли нужных байт, двигаем указатель чтения
uk.read++;
}
}// Ну как то так
Вт янв 17, 2023 13:45:51
Естественно. Ошибка вылетает из-за того, что адрес получается невыровненный.alex_ писал(а):если обратиться к структуре(например serv->len) то тут вылетаем в ошибку
Вт янв 17, 2023 14:04:10
Вт янв 17, 2023 14:07:01
С чего они потеряются, если они уже приняты и их осталось обработать ? Принимать нужно весь пакет от и до, а потом уже заниматься обработкой.alex_ писал(а):Кольцевой буфер нужен для того чтобы не потерять данные в процессе обработки
Вт янв 17, 2023 14:10:36
Ср янв 18, 2023 01:12:16
Ср янв 18, 2023 16:07:33
Ср апр 26, 2023 14:35:32
Пт май 12, 2023 19:16:08
struct Serv485u8// данные выдаются в формате char
{
unsigned char Addr; //1 1
unsigned char contr; //1 2//0x5A
unsigned short len; //2 4
unsigned char pak[2];//2 6
unsigned char c[1024];//передаваемые данные
};
struct
{
unsigned char pac;
unsigned char read;
}uk;//указатель на точки чтения и записи
unsigned char uart_rx[1024]; // кольцевой буфер приёма
unsigned char adr = 0x50;
void InPac();
bool СheckCRC485(unsigned char *Buff, unsigned short len);
void ReadPac(unsigned char * pcBlock, unsigned short len);
//----------
void __ISR(_UART_2_VECTOR, IPL1AUTO) UART2Interrupt(void)//
{
unsigned short i0=10;//блокировка зацикливания
if(IFS1bits.U2EIF)//проверить на наличие ошибок
{
CheckError(); //читаем биты ошибок
}
else
{ // ошибок нет, читаем
do
{
uart_rx[uk.pak] = U2RXREG;
if(uk.pak<sizeof(uart_rx)-1)//индекс сдвинули на байт
uk.pak++;
else uk.pak=0;
i0--;
} while(U2STAbits.URXDA && i0);
}
IFS1bits.U2RXIF=0; //сброс флага прерывания
}
//======
void main()
{
while(1)
{
if((uk.pac - uk.read) >4)
InPac();
// тут ещё много всяких if'ов которые по флагам от таймеров и иных прерываний выполняют различные задания
}
}
//----------
void InPac()
{
struct Serv485u8 *serv;
while(uk.read!=uk.pac)// пока всё не прочитаем
// помню что буфер кольцевой, но этот вопрос буду решать позже, главное с выравниванием разобраться
{
if(uart_rx[uk.read]==adr && uart_rx[uk.read+1]==0x5A)//;
{//собираем пакет
serv=(void*)&uart_rx[uk.read];// можно было и так serv=(struct Serv485u8*)&uart_rx[uk.read]; но ничего особо не меняет
//если uk.read не чётное число, адрес получается тоже нечётный
//если обратиться к структуре(например serv->len) то тут вылетаем в ошибку
if(serv->len < (uk.pac - uk.read))//если пришёл весь пакет
{
if(СheckCRC485(uart_rx[uk.read], serv485->len-2))
{
ReadPac(uart_rx[uk.read], serv485->len-2);//передаём пакет на разборку
uk.read+=serv485->len; // данные считали, двинули указатель чтения
if(uk.read>=sizeof(uart_rx))//если вышли за пределы кольцевого массива, вернутся к началу
uk.read-=sizeof(uart_rx);
}
else uk.read++;
}
else break; // выходим, зайдём в следующий раз, возможно к тому моменту успеет всё собраться
}
else// не нашли нужных байт, двигаем указатель чтения
uk.read++;
}
}// Ну как то так
#pragma pack(push, 1)
struct Serv485u8// данные выдаются в формате char
{
unsigned char Addr; //1 1
unsigned char contr; //1 2//0x5A
unsigned short len; //2 4
unsigned char pak[2];//2 6
unsigned char c[1024];//передаваемые данные
};
struct
{
unsigned char pac;
unsigned char read;
}uk;//указатель на точки чтения и записи
#pragma pack()
Сб май 13, 2023 23:33:05
Пт июн 30, 2023 16:53:14
Пт авг 04, 2023 15:04:00
Пн авг 07, 2023 09:56:12
Чт ноя 23, 2023 16:56:20