portb로 8port 전부 pwm 출력을 하고자 하는데 뭐가 틀렸는지 모르겠습니다.
아래 소스는 본 홈페이지 어느 분이 짜신건데 제가 활용해봤습니다.
죄송합니다. 뭔가 수고비를 바라신다면 댓가를 지불할 의향도 있습니다.
한번 봐주세요. 저 왕초보입니다. 죽겠습니다...ㅠㅠ
개발 환경은 AVR Studio Atmega128 GCC입니다.
#include<avr/io.h>
#include<avr/interrupt.h>
int int_cmd;
void PORT_init(void)
{
DDRB=0xFF;
PORTB=0xFF;
}
SIGNAL(TIMER0_COMP_vect)
{
int_cmd++;
if(int_cmd>>250){
//int_cmd=0;
PORTB=0x00;
}
else if(int_cmd>>500){
PORTB=0xFF;
int_cmd=0;
}
}
void PWM_init(void)
{
TCCR3A = 0x22; // Fast PWM mode(14), output OC3B
TCCR3B = 0x19; // Fpwm = 16MHz/1/(1+1599) = 10kHz
TCCR3C = 0x00;
ICR3H = (1599 >> 8);
ICR3L = 1599 & 0xFF;
OCR3BH = 0x00;
OCR3BL = 0x00;
TCNT3H = 0x00;
TCNT3L = 0x00;
sei();
}
int main(void)
{
PORT_init();
PWM_init();
while(1){
}
}
음 세세히 안봐서 자세한건 모르겠고.. 인터럽트 구문에서 비교하는게 이상해요.
>> 이거 쉬프트 연산자니까 틀렸고..
순서가 int_cmd가 0부터 증가한다고 하면 만족하는게 없습니다.
즉, int_cmd 가 100까지는 0이고 200까지는 1로 하고 싶다면
if(int_cmd<100)
{
PORTB=0x00;
}
else
{
PORTB=0xFF;
}
int_cmd++;
if ( int_cmd > 200 ) int_cmd = 0 ;
이렇게 하면 되구요.
int int_cmd;
전역 변수가 초기화 되는걸로 아는데.. 혹시 모르니 int int_cmd = 0 ;
하세요.
그냥 문법상 틀려서 지적해 봅니다.
안되면 세세히봐야 겠네요. ^^
안되네요...이 프로그램 PORTB로 8포트 전부 PWM 출력 되는거 맞나요???ㅠㅠ
음.. 좀더 보니.. 여러 프로그램 같다 붙이신거 같네요 ^.^;;
걍 pwm 처럼 파형 나오는것만 원하신다면 저녁에 하나 짜드릴께요. 새벽쯤? ^.^
TCCR3A = 0x22; // Fast PWM mode(14), output OC3B
TCCR3B = 0x19; // Fpwm = 16MHz/1/(1+1599) = 10kHz
이게 맞다면 output OC3B 에 pwm 출력하는 프로그램 입니다.
SIGNAL(TIMER0_COMP_vect)
이렇게 해서 쓰시길 원한다면 타이머 오버플로 인터럽트로 기준 시간 만들어서 하면 pwm 비슷하게 구현 가능합니다.
대충 아래와 같아요. 전 코드비전 쓰니까 인터럽트 쪽만 "ISR(TIMER0_OVF_vect)" 으로 바꾸면 될듯 하네요.
음 확인은 안해봤지만 개념은 아래와 같아요. 대충 했기에 정확하진 않지만요.
그리고 8포트 전부 PWM 기능 없습니다. 수동으로 만들어야 해요. 마이컴 내부 pwm 을 사용하고 싶다면
레지스터 설정만 해 주면 거기에 해당하는 포트들만 가능합니다.
수고하세요.
// Timer 0 overflow interrupt service routine
// 7.813Khz 이니까 TCNT0 하나당 1/7813 s 가 됩니다.
// 그리고 업카운터니까 256-100 을 하면 100번 카운터 된다음 인터럽트가 걸립니다.
// 따라서 인터럽트에 들어갈때의 시간은 1/7813*100 = 0.01279918 s 가 됩니다.
// 그리고 20Hz 의 파형을 만들고 싶다면 0.025s(high) , 0.025s(low) 이니까
// 아래와 같습니다.
unsigned int count = 0 ;
char flag = 0 ;
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=256-100;
count++ ;
if ( count >= 2 ) // 0.025s (약)
{
count = 0 ;
if ( flag ) flag = 0 ;
else flag = 1 ;
}
if ( flag )
{
PORTB = 0xFF ;
}
else
{
PORTB = 0x00 ;
}
}
void Init ()
{
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7.813 kHz
// Mode: Normal top=FFh
// OC0 output: Disconnected
ASSR=0x00;
TCCR0=0x07;
TCNT0=256-100;
OCR0=0x00;
}
감사합니다.(__) 그런데 잘 안되네요...에혀...죽겠다...ㅠㅠ 아예 avr studio에서 어떻게 코드를 적어야 되는지 full로 적어 주셔요...저 한개도 몰라요...휴...죄송합니다...(__)
위와 같은 방법도 있겠지만 다른 방법으로 생각하면 디렐이 함수을 사용하여 그 파형을 만들어 내면 되지 않겠습니까?