FPGA 직렬 통신 데이터 분석 두 가지 방식
4427 단어 FPGA 프로 토 콜 실현
논 리 를 사용 하여 분석 하면 논리 로 데이터 송 수신 을 하 는데 여 기 는 샤 오 메 이 형의 을 참조 할 수 있다.그 핵심 은 데이터 수신 부분의 디자인,즉 데이터 프레임 수신 상태 기의 디자인 이다.상태 기 는 크게 다음 과 같은 상 태 를 포함한다.프레임 헤드,바이트 수,데이터,프레임 꼬리.기본 적 인 상황 에서 상태 기 는 프레임 헤드 상태 에 있 고 프레임 헤드 가 감지 되면 다음 상태 에 들어간다.그렇지 않 으 면 상태 기 는 프레임 헤드 에 있다.이 순환 에 따라 데이터 프레임 이 검 측 될 때 까지 높 은 신호 가 발생 하 는 동시에 검 측 된 데이터 프레임 잠 금 저장 을 명령 상 태 를 분석 하 는 동시에 다음 데이터 프레임 의 수신 을 시작한다.
Nios 를 사용 하여 분석 합 니 다.보통 Altera 가 가지 고 있 는 Uart 핵 을 사용 하여 데이터 송 수신 을 완성 합 니 다.이 부분 은 제 블 로그 인 을 참조 하 십시오.주 소 는 다음 과 같 습 니 다.http://blog.chinaaet.com/helimin/p/5100018309
구체 적 인 협 의 는 나의 블 로그 인 을 참조 하고 주 소 는 다음 과 같다.
http://blog.chinaaet.com/helimin/p/5100051178
인 터 럽 트 방식 으로 한 바이트 씩 받 을 때마다 인 터 럽 트 합 니 다.데 이 터 를 받 은 후에 분석 하고 생각 은 다음 과 같다.
1.명령 캐 시 배열 recBuf 를 정의 합 니 다.중단 에 들 어 갈 때마다 받 은 1 바이트 데 이 터 를 배열 에 저장 하고 배열 의 끝 부분 색인 recTailPointor 는 1 을 추가 합 니 다.
void uart0_isr(void * context,alt_u32 id)
{
rxdata0 = IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE);
recBuf[recTailPointor] = rxdata0;//
recTailPointor += 1;
}
2.직렬 해석 함수 에 들 어가 서 다음 과 같은 조작 을 합 니 다.현재 바이트 수 계산 함 수 를 호출 하여 배열 에 들 어 가 는 바이트 수 를 계산 합 니 다.
inline alt_u8 getRecLen(void)
{
alt_u8 lureclen = 0;
if(recHeadPointor <= recTailPointor){
lureclen = recTailPointor - recHeadPointor;
}
else{ // recHeadPointor > recTailPointor, recBuf[256] , 。
lureclen = 256 - (recHeadPointor - recTailPointor);
}
return lureclen;
}
3. 직렬 해석 함수 에서 배열 에 넣 는 바이트 수가 0 보다 큰 지 판단 하고 0 보다 크 면 배열 의 첫 번 째 요소 가 프레임 헤드 인지 판단 하 며 프레임 헤드 라면 두 번 째 요소(바이트 수)에 따라 데 이 터 를 수신 하여 한 프레임 의 데 이 터 를 받 을 때 까지 데 이 터 를 수신 합 니 다.이 때 데이터 인덱스 를 받 는 헤드 포인 터 를 끝으로 이동 합 니 다.
alt_u8 UartAnalyze(void)
{
alt_u8 i = 0;
alt_u8 luRecLen = 0;
alt_u8 lutmp = 0;
luRecLen = getRecLen(); //
if(luRecLen > 0){
if(recBuf[recHeadPointor] == 0xcc){
while(1){//
if(uartOverTimeFlag == 0){
luRecLen = getRecLen();
if(luRecLen >= 1){
if(luRecLen > (recBuf[recHeadPointor+1] + 3)){
break;// , ,
}
}
}
else{
recHeadPointor = recTailPointor;// 。
recTime = 0;
uartOverTimeFlag = 0;
return ERROR_OVERTIME;
}
}
// uartCMDBuf[] 。
for(i=0;i<=luRecLen;i++){
lutmp = recHeadPointor + i;
uartCMDBuf[i] = recBuf[lutmp];
}
recHeadPointor = recTailPointor;// 。
recTime = 0;
uartOverTimeFlag = 0;
if(Get_DRC(uartCMDBuf,uartCMDBuf[1]) == uartCMDBuf[uartCMDBuf[1]+1]){
return CMD_CORRECT;
}
else{//if(Get_DRC(uartCMDBuf,uartCMDBuf[1]) == uartCMDBuf[uartCMDBuf[1]+1])
return ERROR_DRC_NO_PASS;
}
}
else{//if(recBuf[recHeadPointor] == 0xcc)&& if(recBuf[recHeadPointor] == 0xf0)
recHeadPointor = recTailPointor;// 。
recTime = 0;
uartOverTimeFlag = 0;
return ERROR_SHAKE_HANDS;
}
}
else{//luRecLen=0 。
recHeadPointor = recTailPointor;// 。
recTime = 0;
uartOverTimeFlag = 0;
return 0;
}
}
데이터 수신 시 시스템 을 더욱 안정 시 키 기 위해 타 이 머 를 사용 하여 시간 초과 판단 을 한다.만약 한 동안 명령 을 받 지 못 하면 이번 수신 을 포기한다.
한 프레임 의 데 이 터 를 수신 한 후에 CRC 순환 검사,프레임 끝 검 사 를 실시 하고 만약 에 모두 ok 이면 수신 배열 의 한 프레임 의 데 이 터 를 옮 겨 데이터 분석 에 사용 하 는 동시에 다음 프레임 데이터 의 수신 을 시작 합 니 다.
당시 이 직렬 해석 부분 을 쓰 는 프로그램 은 고수 의 지 시 를 받 아 2 주일 이 넘 게 걸 렸 다.사실 기본 적 인 사고방식 은 비교적 간단 하 다.인 터 럽 트 를 사용 하여 데이터 수신 을 하고 해석 함수 에서 협의 에 따라 수신 하고 수신 이 끝 난 후에 협의 에 따라 해석한다.
두 가지 방식 중에서 간단 한 공사 응용 에 대해 사용 할 수 있 는 방식 은 하나 이다.한편,비교적 복잡 한 협의 에 대해 수백 가지 통제 와 관련 되 고 서로 다른 패 킷 바이트 수가 다 를 수 있 을 때 사용 방식 2 가 매우 적합 하 다.
중요 한 것 은 협의 이다.좋 은 협 의 를 제정 하 는 것 이 매우 중요 하 다.