BASIC4MCU | 질문게시판 | 모터
페이지 정보
작성자 룰루 작성일2021-12-24 09:26 조회1,874회 댓글3건본문
#include <avr/io.h>
#define kilo 1000UL
#define Mega (kilo*kilo)
#define F_CPU 16*Mega
#include <util/delay.h>
#include <avr/interrupt.h>
#define ST0P 0
#define GO 1
#define MODE1 0
#define MODE2 1
#define MODE3 2
#define NULL 0
void current_motor(void);
void current_sw(void);
void mcu_timer2_fPWM(void);
//void mcu_timer0_ctc(void);
void mcu_exinterrupt_switch(void);
void chattering(char);
struct op
{
volatile uint8_t state;
volatile uint8_t mode_sel;
uint8_t array_ocr2[];
//struct op *next;
}motor_op =
{
ST0P,
MODE3, //after reset "MODE3" trans to "MODE1" by INT4
{ 76,156,220 } //TCNT2(256),30%,60%,90%
};
int main()
{
current_motor();
current_sw();
mcu_timer2_fPWM();
mcu_exinterrupt_switch();
struct op *ptr = &motor_op;
DDRA = 0xff;
while(1)
{
if(ptr->state)
{
switch(ptr->mode_sel)
{
case MODE1: OCR2 = ptr->array_ocr2[0]; PORTA=0x10; break;
case MODE2: OCR2 = ptr->array_ocr2[1]; PORTA=0x20; break;
case MODE3: OCR2 = ptr->array_ocr2[2]; PORTA=0x40; break;
}
}else {
PORTA ^= 0x01;
_delay_ms(100);
}
}
}
void current_motor(void)
{
DDRB = (1<<DDB6)|(0<DDB7); //for use OC2 (1<<DDB7) //enabled by ISR(INT4_vect).
}
void mcu_timer2_fPWM(void)
{
TCCR2 = (1<<WGM21)|(1<<WGM20)|(1<<COM21)|(0<<COM20)|(1<<CS22)|(0<<CS21)|(1<<CS20); //OC2: enable (COM21:0 =2)
//(fast mode) ( clear:up, set:down) (clock : 1024) = small motor didn't respond high frequency
/*--OCF2-------*/
//TIMSK = (1<<OCR2); //timer2: compare match interrupt enable. //ISR(TIMER2_COMP_VECT) : enable.
}
/*--ISR OCF2-------*/
ISR(TIMER2_COMP_vect)
{
/*none*/
}
void current_sw(void)
{
DDRE = 0xff;
DDRE ^= (1<<DDE4)|(1<<DDE5); //default: 0 //use for INT4,5 port pin function enable.
}
void mcu_exinterrupt_switch(void)
{
EIMSK = (1<<INT4)|(1<<INT5); // INT4,5 enable.
EICRB = (1<<ISC41)|(0<<ISC40)|(1<<ISC51)|(0<<ISC50); //interrupt source collect, trigger: rising edge.
sei();
}
void chattering(char num)
{
EIFR= (1<<num);
_delay_ms(30);
}
ISR(INT4_vect)
{ // mode1 mode2 mode3
static uint8_t trans_mode[3] = {MODE2,MODE3,MODE1};
motor_op.mode_sel = trans_mode[motor_op.mode_sel];
//stop go
static uint8_t trans_array[2] = { GO, GO };
motor_op.state = trans_array[motor_op.state];
DDRB |= 1<<DDB7; //motor: start. (DDR: connect OC2 signal)
chattering(4);
}
ISR(INT5_vect)
{ //mode 1 mode2 mode3
static uint8_t trans_mode[3] = {MODE3,MODE3,MODE3};
motor_op.mode_sel = trans_mode[motor_op.mode_sel];
// stop go
static uint8_t tran_array[2] = {ST0P,ST0P};
motor_op.state = tran_array[motor_op.state];
DDRB &= 0<<DDB7; // motor: stop (DDR: cut OC2 signal)
OCR2 = 0;
chattering(5);
}
프로젝트 설명 :
SW1을 한 번 누르면 미풍, 두번 누르면 약풍, 세번 누르면 강풍, 네번 누르면 다시 미풍이 되며, SW2를 누르면 정지가 되는 모터를 작동하고 싶은데 작동이 안됩니다ㅠ 어디가 문제인가요...
댓글 3
조회수 1,874master님의 댓글
master 작성일
EICRB=(1<<ISC41)|(0<<ISC40)|(1<<ISC51)|(0<<ISC50);
이 설정은 상승엣지가 아니고 하강엣지입니다.
코드가 복잡해서 한번에 파악은 안되지만
각각의 인터럽트 및 PWM등은 하나씩 차근차근 제대로 코딩을 했는지 일일이 확인해야 합니다.
master님의 댓글
master 작성일
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 16000000UL
#include <util/delay.h>
//
volatile char mode=0;
//
ISR(INT4_vect){
if(++mode>3)mode=1;
//
if(mode==1){ OCR2= 76; PORTA=0x10; }
if(mode==2){ OCR2=156; PORTA=0x20; }
if(mode==3){ OCR2=220; PORTA=0x40; }
//
_delay_ms(50); EIFR=0x30;
}
//
ISR(INT5_vect){ mode=0; OCR2=0; PORTA=0; }
//
int main(){
DDRA=0xff; DDRB=0xC0;
TCCR2=(1<<WGM21)|(1<<WGM20)|(1<<COM21)|(0<<COM20)|(1<<CS22)|(0<<CS21)|(1<<CS20);
EICRB=0xAA; EIMSK=0x30; sei();
while(1){}
}
룰루님의 댓글
룰루
이부분만 수정해도 되는 건가요??