초음파센서 3개돌리기 (SFR05 이용 두전째) PIT(내부인터럽트) 와 외부인터럽트
//----------PIT---------------------------------------------------------------------
#define PIT_PIVR (*(volatile unsigned int *) 0xFFFFFD38)
#define PITC_PIMR (*(volatile unsigned int *) 0xFFFFFD30)
//------------PIO------------------------------------------------------------------
#define PIO_ASR (*(volatile unsigned int *) 0xFFFFF470)//
#define PIO_SODR (*(volatile unsigned int *) 0xFFFFF430)
#define PIO_CODR (*(volatile unsigned int *) 0xFFFFF434)
#define PIO_OER (*(volatile unsigned int *) 0xFFFFF410)//
#define PIO_BSR (*(volatile unsigned int *) 0xFFFFF474)//
#define PIO_PDR (*(volatile unsigned int *) 0xFFFFF404)//
#define PIO_IFER (*(volatile unsigned int *) 0xFFFFF420)//
#define PIO_PDSR (*(volatile unsigned int *) 0xFFFFF43C)//
#define PIO_PER (*(volatile unsigned int *) 0xFFFFF400)//
#define PIO_ODR (*(volatile unsigned int *) 0xFFFFF414)
#define PIO_PUER (*(volatile unsigned int *) 0xFFFFF464)
#define PIO_ISR (*(volatile unsigned int *) 0xFFFFF44C)
#define PIO_PUDR (*(volatile unsigned int *) 0xFFFFF460)// 풀업저항 인터럽트 레지스
#define PIO_ODSR (*(volatile unsigned int *) 0xFFFFF438)
#define PIO_IER (*(volatile unsigned int *) 0xFFFFF440) //인터럽트 인에이플 레지스터
//-----RSTC --------------------------------------------------------------
//#define RSTC_MR (*(volatile unsigned int *) 0xFFFFFD08)
//----- PMC -------------------------------------------------------------------
#define PMC_PCER (*(volatile unsigned int *) 0xFFFFFC10)
//------AIC---------------------------------------------------------------------
#define AIC_IDCR (*(volatile unsigned int *) 0xFFFFF124)
#define AIC_SVR ((volatile unsigned int *) 0xFFFFF080)
#define AIC_SMR ((volatile unsigned int *) 0xFFFFF000) // 인터럽트 설정
#define AIC_ICCR (*(volatile unsigned int *) 0xFFFFF128)
#define AIC_IECR (*(volatile unsigned int *) 0xFFFFF120)
//---------DBGU--------------------------------------------------------
#define DBGU_MR (*(volatile unsigned int *) 0xFFFFF204)
#define DBGU_BRGR (*(volatile unsigned int *) 0xFFFFF220)
#define DBGU_CR (*(volatile unsigned int *) 0xFFFFF200)
#define DBGU_SR (*(volatile unsigned int *) 0xFFFFF214)
#define DBGU_RHR (*(volatile unsigned int *) 0xFFFFF218)
#define DBGU_THR (*(volatile unsigned int *) 0xFFFFF21C)
#define DBGU_IER (*(volatile unsigned int *) 0xFFFFF208) // 인터럽트 설정 레지스터
#define MCK 48000000
volatile unsigned int PIT_count=0; // PIT interrupt count
volatile unsigned int PIT_flag=0; // PIT interrupt flag
unsigned int SUM_BUF_L[10];
unsigned int SUM_BUF_F[10];
unsigned int SUM_BUF_R[10];
unsigned int OUTPUT_COUNT_FRONT=0;//정면 센서값 변수
unsigned int OUTPUT_COUNT_LEFT=0;
unsigned int OUTPUT_COUNT_RIGHT=0;
unsigned int F_LOOF_FLAG=0;
unsigned int L_LOOF_FLAG=0;
unsigned int R_LOOF_FLAG=0;
void Delay_ms(unsigned int ms) /* ms delay for -O2 -Otime option */
{ volatile unsigned int count, countmax = (MCK / 10000) * ms;
for(count = 0; count < countmax; count++);
}
void Delay_us(unsigned int us) /* us delay for -O2 -Otime option */
{ volatile unsigned int count, countmax = (MCK / 9600000) * us;
for(count = 0; count < countmax; count++);
}
void DBGU_TX_char(unsigned int data) /* transmit a character by DBGU */
{
while(!(DBGU_SR & 0x0002)); // wait until TXRDY=1
DBGU_THR = data; // transmit a character
}
void DBGU_string(char *string) /* transmit a string by DBGU */
{
while(*string != '\0')
{ DBGU_TX_char(*string);
string++;
}
}
unsigned int DBGU_RX_char(void) /* receive a character by DBGU */
{
while(!(DBGU_SR & 0x0001)); // wait until RXRDY=1
return DBGU_RHR; // receive a character
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void L_FILTER_LINE_UP(unsigned int x)
{
unsigned int i,j,temp;
//출력받은 데이타를 메모리에 저장
for(i=0;i<10;i++)//데이타의 입력
{
SUM_BUF_L[i]=x;
}
//데이터가 박은 값을 우선으로 정렬한다
for(i=0;i<9;i++)
{
for(j=i+1;j<10;j++)
{
if(SUM_BUF_L[i]>SUM_BUF_L[j])
{
temp=SUM_BUF_L[j];
SUM_BUF_L[j]=SUM_BUF_L[i];
SUM_BUF_L[i]=temp;
}
}
}
}
//=--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void F_FILTER_LINE_UP(unsigned int x)
{
unsigned int i,j,temp;
//출력받은 데이타를 메모리에 저장
for(i=0;i<10;i++)//데이타의 입력
{
SUM_BUF_F[i]=x;
}
//데이터가 박은 값을 우선으로 정렬한다
for(i=0;i<9;i++)
{
for(j=i+1;j<10;j++)
{
if(SUM_BUF_F[i]>SUM_BUF_F[j])
{
temp=SUM_BUF_L[j];
SUM_BUF_F[j]=SUM_BUF_F[i];
SUM_BUF_F[i]=temp;
}
}
}
}
//--------------------------------------------------------
void R_FILTER_LINE_UP(unsigned int x)
{
unsigned int i,j,temp;
//출력받은 데이타를 메모리에 저장
for(i=0;i<10;i++)//데이타의 입력
{
SUM_BUF_R[i]=x;
}
//데이터가 박은 값을 우선으로 정렬한다
for(i=0;i<9;i++)
{
for(j=i+1;j<10;j++)
{
if(SUM_BUF_R[i]>SUM_BUF_R[j])
{
temp=SUM_BUF_R[j];
SUM_BUF_R[j]=SUM_BUF_R[i];
SUM_BUF_R[i]=temp;
}
}
}
}
void PIT_ISR(void) /* PIT interrupt service routine */
{
unsigned int PITPIVR;
PITPIVR=PIT_PIVR;// PIT COUNT RESET ???
//-------------------송신부 설정 ----------------------------------------------
PIT_count++; // increment PIT_count
if(PIT_count < 10) // 400Hz/5 = 80Hz (그러나 반주기 동안만 불이켜지게되므로 80Hz/2=40Hz(25ms))
return;
PIT_count = 0; // if PIT_count=10, clear it
PIO_SODR = ((unsigned int)1 << 13)|((unsigned int)1 << 11)|((unsigned int)1 << 12);
Delay_us(10);
PIO_CODR = ((unsigned int)1 << 13)|((unsigned int)1 << 11)|((unsigned int)1 << 12);
DBGU_string("\r송신트리거 발송\r\n");
}
void PIO_ISR_EXTERN(void)// 외부인터럽트 처리 함수(초음파 출력파형을 처리한다)
{
unsigned int num=10000;//전송하고자하는 문자열의 단뒤 예 2자리일경우 10 3자리일경우 100
//unsigned int status;
unsigned int i;//루프돌리기위한 변수
unsigned int PIOPDSR;// PDSR 값 저장을위한 변수
unsigned int FLAG=0;// 출력값을 읽었을 때 만 기억하는 플래그
unsigned int L_FILTER_VALUE;//필터된 값
unsigned int TANSFER_BUF_L[6];//하이퍼 터미널로 전달 할 버퍼
unsigned int F_FILTER_VALUE;//필터된 값
unsigned int TANSFER_BUF_F[6];//하이퍼 터미널로 전달 할 버퍼
unsigned int R_FILTER_VALUE;//필터된 값
unsigned int TANSFER_BUF_R[6];//하이퍼 터미널로 전달 할 버퍼
//--------------- 센서 수신부 입력 받는 곳 ----------------------
PIOPDSR=PIO_PDSR;
// status=PIO_ISR;
//------------FRONT SENSOR-----------------------------------------------------
while((F_LOOF_FLAG<11) && (PIO_PDSR &((unsigned int)0x4000)))//신호 10개를 측정
{
while(PIO_PDSR &((unsigned int)0x4000))// 출력값 측정 PA14번 포트
{
OUTPUT_COUNT_FRONT++; //초음파 센서 데이터 측정
FLAG=1;
}
if(FLAG==1) //카운터 했을때만 출력을 한다
{
DBGU_string("\r센서FRONT입력들어옴2 \r\n");
OUTPUT_COUNT_FRONT=OUTPUT_COUNT_FRONT/80;
//수치를 cm 변환 하드웨어 DATA SHEET상 54로나누면 센지 148로 나누면 인치로 변환
F_FILTER_LINE_UP(OUTPUT_COUNT_FRONT);//데이타 정렬
FLAG=0;// 플레그 초기화
}
F_LOOF_FLAG++;
}
//----------------------------------------------------------------------
if(F_LOOF_FLAG>0)
{ DBGU_string("\rF루프 입력들어옴 \r\n");
for(i=1;i<9;i++) //7개의 데이타중 앞뒤 2개의 데이타 필터링, 튀는 값(앞뒤) 버림
{
F_FILTER_VALUE+=SUM_BUF_F[i];// 8개의 데이타 합산
}
F_FILTER_VALUE=F_FILTER_VALUE/8;//8개의 데이타 평균
for(i=0;i<10;i++)//버퍼의 초기화
{
SUM_BUF_F[i]=0;
}
for(i=0;i<5;i++)//전송하는 문자열의 개수 만큼 루프돌린다.
{
TANSFER_BUF_F[i]=(F_FILTER_VALUE%(10*num)-F_FILTER_VALUE%num)/num + 48;//숫자를 문자로변환
num/=10;//숫자의 단위를 감소시키기 위함
DBGU_TX_char(TANSFER_BUF_F[i]);//캐릭터 문자 1바이트 전송
}
DBGU_TX_char('\r');// 커서 맨앞으로 이동
DBGU_TX_char('\n');// 커서 줄바꾸기
OUTPUT_COUNT_FRONT=0;//다음 초음파 출력값을 받기위해 리셋
F_LOOF_FLAG=0;
}
num=10000;//자릿수 초기화
//------------LEFT SENSOR---------------------------------15--------------------
while((L_LOOF_FLAG<11) && (PIO_PDSR &((unsigned int)0x8000)))//신호 10개를 측정
{
while(PIO_PDSR &((unsigned int)0x8000))// 출력값 측정 PA15번 포트
{
OUTPUT_COUNT_LEFT++; //초음파 센서 데이터 측정
FLAG=2;
}
if(FLAG==2) //카운터 했을때만 출력을 한다
{
DBGU_string("\r센서LEFT입력들어옴2 \r\n");
OUTPUT_COUNT_LEFT=OUTPUT_COUNT_LEFT/80;
//수치를 cm 변환 하드웨어 DATA SHEET상 54로나누면 센지 148로 나누면 인치로 변환
L_FILTER_LINE_UP(OUTPUT_COUNT_LEFT);//데이타 정렬
FLAG=0;// 플레그 초기화
}
L_LOOF_FLAG++;
}
//----------------------------------------------------------------------
if(L_LOOF_FLAG>0)
{ DBGU_string("\rL루프 입력들어옴 \r\n");
for(i=1;i<9;i++) //7개의 데이타중 앞뒤 2개의 데이타 필터링, 튀는 값(앞뒤) 버림
{
L_FILTER_VALUE+=SUM_BUF_L[i];// 8개의 데이타 합산
}
L_FILTER_VALUE=L_FILTER_VALUE/8;//8개의 데이타 평균
for(i=0;i<10;i++)//버퍼의 초기화
{
SUM_BUF_L[i]=0;
}
for(i=0;i<5;i++)//전송하는 문자열의 개수 만큼 루프돌린다.
{
TANSFER_BUF_L[i]=(L_FILTER_VALUE%(10*num)-L_FILTER_VALUE%num)/num + 48;//숫자를 문자로변환
num/=10;//숫자의 단위를 감소시키기 위함
DBGU_TX_char(TANSFER_BUF_L[i]);//캐릭터 문자 1바이트 전송
}
DBGU_TX_char('\r');// 커서 맨앞으로 이동
DBGU_TX_char('\n');// 커서 줄바꾸기
OUTPUT_COUNT_LEFT=0;//다음 초음파 출력값을 받기위해 리셋
L_LOOF_FLAG=0;
}
num=10000;//자릿수 초기화
//------------RIGHT SENSOR---------------------------------15--------------------
while((R_LOOF_FLAG<11) && (PIO_PDSR &((unsigned int)0x100)))//신호 10개를 측정
{
while(PIO_PDSR &((unsigned int)0x100))// 출력값 측정 PA15번 포트
{
OUTPUT_COUNT_RIGHT++; //초음파 센서 데이터 측정
FLAG=3;
}
if(FLAG==3) //카운터 했을때만 출력을 한다
{
DBGU_string("\r센서RIGHT입력들어옴2 \r\n");
OUTPUT_COUNT_RIGHT=OUTPUT_COUNT_RIGHT/80;
//수치를 cm 변환 하드웨어 DATA SHEET상 54로나누면 센지 148로 나누면 인치로 변환
R_FILTER_LINE_UP(OUTPUT_COUNT_RIGHT);//데이타 정렬
FLAG=0;// 플레그 초기화
}
R_LOOF_FLAG++;
}
//----------------------------------------------------------------------
if(R_LOOF_FLAG>0)
{ DBGU_string("\rR루프 입력들어옴 \r\n");
for(i=1;i<9;i++) //7개의 데이타중 앞뒤 2개의 데이타 필터링, 튀는 값(앞뒤) 버림
{
R_FILTER_VALUE+=SUM_BUF_R[i];// 8개의 데이타 합산
}
R_FILTER_VALUE=R_FILTER_VALUE/8;//8개의 데이타 평균
for(i=0;i<10;i++)//버퍼의 초기화
{
SUM_BUF_R[i]=0;
}
for(i=0;i<5;i++)//전송하는 문자열의 개수 만큼 루프돌린다.
{
TANSFER_BUF_R[i]=(R_FILTER_VALUE%(10*num)-R_FILTER_VALUE%num)/num + 48;//숫자를 문자로변환
num/=10;//숫자의 단위를 감소시키기 위함
DBGU_TX_char(TANSFER_BUF_R[i]);//캐릭터 문자 1바이트 전송
}
DBGU_TX_char('\r');// 커서 맨앞으로 이동
DBGU_TX_char('\n');// 커서 줄바꾸기
OUTPUT_COUNT_RIGHT=0;//다음 초음파 출력값을 받기위해 리셋
R_LOOF_FLAG=0;
}
num=10000;//자릿수 초기화
}
int main(void)
{
//-----------DBGU-----------------------------------------------------------------------------
PMC_PCER = (unsigned int) 1 << 2; // enable clock of DBGU 주변장치의 전력공급을 시작한다
DBGU_MR = 0x00000800; // normal mode, no parity
DBGU_BRGR = 26; // MCK/16/26 = 115200 bps
DBGU_CR = 0x00000150; // TX, RX enable
DBGU_IER = ((unsigned int)1<<0);//수신 인터럽트 설정
// DTXD, DRXD by Peripheral A
PIO_ASR = (unsigned int) 1 << 10 | (unsigned int) 1 << 9;
PIO_BSR = 0;
PIO_PDR = (unsigned int) 1 << 10 | (unsigned int) 1 << 9;// 해당포트를 i/o 포트로사용을 금지 한다(주변장치사용)
//-----PIO----------------------------------------------------------------------------------------------------
//PIO_CODR = 0x00003FFF; //
PIO_PER = ((unsigned int)1 << 11)|((unsigned int)1 << 12)|((unsigned int)1 << 13)
|((unsigned int)1 << 14)|((unsigned int)1 << 15)|((unsigned int)1 << 8); // 다음 포트를 주변장치가 아닌 Set in PIO mode 사용 */
PIO_OER = ((unsigned int)1 << 11)|((unsigned int)1 << 12)|((unsigned int)1 << 13)
|((unsigned int)1 << 14)|((unsigned int)1 << 15)|((unsigned int)1 << 8);// 다음포트 를사용하겠다
PIO_ODR = (1 << 14)|(1 << 15)|(1 << 8);
PIO_IER = ((unsigned int)1 << 14)|((unsigned int)1 << 15)|((unsigned int)1 << 8);// 인터럽트 사용을 허가한다
PIO_PUDR = ((unsigned int)1 << 14)|((unsigned int)1 << 15)|((unsigned int)1 << 8);// 풀업저항 금지 즉 입력포트로 설정 하겠다
PIO_IFER = ((unsigned int)1 << 14)|((unsigned int)1 << 15)|((unsigned int)1 << 8);// 글리치 필터(마스터 클럭의 1/2 이하의 주기는 잡음으로 간주하여 무시한다)
//--------PIT----------------------------------------------------------------------------------------
// enable peripheral clock for PIT
PMC_PCER |= ((unsigned int)1 << 1);
PITC_PIMR = (15000-1)|((unsigned int)1 << 24)|((unsigned int)1 << 25);
//---------AIC-------------------------------------------------------------------
//-------- 내부 인터럽트 설정 (PIT)----------------------------------------------
//* Disable the interrupt on the interrupt controller
AIC_IDCR = (unsigned int)1 << 1; // 1 시스템(sys:PMC, DBGU,RTT, PIT,EFC)등 관련 2 입출력관련(PIOA)
//* Save the interrupt handler routine pointer and the interrupt priority
AIC_SVR[1] = (unsigned int)PIT_ISR;
//* Store the Source Mode Register
AIC_SMR[1] = 7 ; // SRCTYPE 00 설정 PRIOR(우선순위):7 가장 높음
//* Clear the interrupt on the interrupt controller
AIC_ICCR = (unsigned int)1 << 1;
AIC_IECR = (unsigned int)1 << 1;
//------ 외부 인터럽트 설정
AIC_IDCR|=(unsigned int)1<<2; //마스크 설정
AIC_SVR[2]=(unsigned int)PIO_ISR_EXTERN; //인터럼트 함수 설정
AIC_SMR[2]=5;//
AIC_IECR|=(unsigned int)1<<2; //인터럽트 허용 명령 레지스터
AIC_ICCR|=(unsigned int)1<<2; //인터럽트를 엣지클리어 명령레지스터
PIO_CODR = ((unsigned int)1 << 14)|((unsigned int)1 << 15)|((unsigned int)1 << 8);
while(1); // wait for interrupt
}