BASIC4MCU | 질문게시판 | pwm dc 모터 제어 질문입니다.
페이지 정보
작성자 하아 작성일2020-06-07 01:42 조회4,089회 댓글1건본문
소스코드를 넣어 동작을 시켜보면 모터가 잘돌다가 갑자기 멈추고 제가 지속적으로 스위치를 눌러줘야지 돌아가는 현상이 발생합니다.
왜 그런지 알 수 있을까요?
#define F_CPU 16000000UL
#include<avr/io.h>
#include<util/delay.h>#define TOP 500
#define SW1 0x06
#define SW2 0x05
#define SW3 0x03
#define SPD_UP 0x01
#define SPD_DOWN 0x04
#define NO_KEY 0x07
#define KEY_INPUT (PINA&0x07)
#define Debouncing_time 20 //디바운싱타임은 20ms
#define CW 0 //clockwise
#define CCW 1 //counter-clockwisevoid Delay_ms(unsigned int MilliSeconds) {
unsigned int i;
for(i=0;i<MilliSeconds;i++) _delay_ms(1);
}void SetDirection(char Direction){
unsigned int tmp;
tmp=OCR3A; //원래의 듀티 비 보관
OCR3A=0; //듀티 비=0 -> 브릿지의 상하 스위치 동시 오프
_delay_us(10); //dead time
if(Direction==CW) PORTE&=~(1<<2); //방향이 시계방향이면 방향 반대로
else PORTE|=1<<2; //방향이 반시계방향이면 방향 반대로
_delay_us(10); //dead time
OCR3A=tmp; //원래의 듀티 비 복원
}char KeyHit(void) //모든 스위치에 대해서 눌렸을 경우 1리턴
{
if(KEY_INPUT==NO_KEY)return 0;
else return 1;
}char KeyHit_SW2(void){ //SW2가 눌린 상태에서 다른 스위치가 눌리면 1리턴
if((KEY_INPUT&0x05)==0x05)return 0;
else return 1;
}
int main(void)
{
DDRA|=~((1<<0)|(1<<1)|(1<<2));
PORTA|=(1<<0)|(1<<1)|(1<<2);
TCCR3A=0x80;
TCCR3B&=0xC0;
TCCR3B|=0x12;
ICR3=TOP; //TOP값 탑재
OCR3A=0; //타이머3 설정
DDRE|=(1<<3)|(1<<2); //포트E 설정
unsigned int spd=0; //모터의 속도
unsigned int SpeedIndex[6]={0, 100, 200, 300, 400, TOP}; //모터 속도 종류
int dir=CW; //모터의 방향
int KeyFlag=0; //스위치 제어 플래그
int KeyFlag_SW2=0;while (1)
{
while(!(PINA&0x02)){ //SW2가 눌린 상태의 루프
if(!KeyHit_SW2()){
KeyFlag_SW2=1;
continue;
}
else{
Delay_ms(Debouncing_time);
if(!KeyHit_SW2()){
KeyFlag_SW2=1;
continue;
}
else{
if(!KeyFlag_SW2)continue;
else{
KeyFlag_SW2=0;
switch(PINA&0x05){ //SW1, SW3 판단
case 0x04: //SW1이 눌리면
if(spd>0)spd--; //스피드 감소
OCR3A=SpeedIndex[spd]; //비교일치 레지스터에 입력
break;
case 0x01: //SW3이 눌리면
if(spd<5)spd++; //스피트 증가
OCR3A=SpeedIndex[spd]; //비교일치 레지스터에 입력
break;
}
}
}
}
}
if(!KeyHit()){
KeyFlag=1;
continue;
}
else{
Delay_ms(Debouncing_time);
if(!KeyHit()){
KeyFlag=1;
continue;
}
else{
if(!KeyFlag)continue;
else{
KeyFlag=0;switch(KEY_INPUT){
case SW1: //SW1이 눌리면
dir=CW; //시계방향
break;
case SW3: //SW3이 눌리면
dir=CCW; //시계 반대 방향
break;
}
SetDirection(dir); //방향 입력
}
}
}
}
}
댓글 1
조회수 4,089master님의 댓글
master 작성일
회로 체크는 타인이 원격으로 할 수가 없습니다.
잘 체크해보세요