Em chào các anh/chị, em đã code avr được khá lâu, tuy nhiên em đang gặp một vấn đề rất lạ:
Em code cho atmega 168pa, 8, 16 khi dùng lệnh sei(); đều ok, nhưng khi code cho atmega328 thì chỉ cẩn enable biến ngắt toàn cục là chương trình không chạy, bỏ lệnh sei(); thì chương trình lại chạy bình thường ( truyền usart lên máy tính ).
Để mọi người rõ hơn, em xin đưa code lên đây ạ, mục đích của prj là điều chế độ rộng xung của 4 chân tạo xung OCxn của avr thông qua điều chỉnh biến trở đầu vào ADC3. Khi mô phỏng thì vẫn bình thường, nhưng khi nạp vào chip thì không chạy. Các cao nhân bắt bệnh cho em với nhé !!!!
/*
* pwm_to_motor.c
*
* Created: 4/4/2013 4:21:20 PM
* Author: nghia
*/
#ifdef F_CPU
#define F_CPU 16000000UL
#endif
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
#include <vk1.6/usart.h>
#include <vk1.6/led.h>
#include <vk1.6/adc_0_to_3.h>
unsigned char i,t;
/************************************************** **********************/
/* pwm init, timer0-1 init
t_step=1/(16e6/256)= 256/16e6=1.6e-5 (s)
1ms= 62 step
2ms= 125 step
*/
/************************************************** **********************/
void pwm_init(void)
{
//------------- timer0 ----------------
DDRD|=(1<<PIND5)|(1<<PIND6);//output pwm pins
TCCR0A|=(1<<COM0A1)|(1<<COM0B1)|(1<<WGM01)|(1<<WGM 00);//fast pwm, compare match out put oc0a,oc0b
TIMSK0|=(1<<TOIE0);//enable interrupt when tm0 overflows
//------------- timer1 -----------------
DDRB|=(1<<PINB1)|(1<<PINB2);//output pwm pins
TCCR1A|=(1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);
TIMSK1|=(1<<TOIE1);
}
void pwm_start(void)
{
//-------- start running ---------------------
TCCR0B|=(1<<CS02);//start running
TCCR1B|=(1<<CS12)|(1<<WGM12);//start running
}
void pwm_mt1(unsigned char t)
{
if(t>127){t=127;}
OCR0A=t+125;
}
void pwm_mt2(unsigned char t)
{
if(t>127){t=127;}
OCR0B=t+125;
}
void pwm_mt3(unsigned char t)
{
if(t>125){t=125;}
OCR1A=t+127;
}
void pwm_mt4(unsigned char t)
{
if(t>127){t=127;}
OCR1B=t+125;
}
void pwm_mt(unsigned char i, unsigned char t)
{
if(t>127){t=127;}
if(i==1){OCR0A=t+125;}//mt1
else if(i==2)
{
OCR0B=t+125; //mt2
}
else if(i==3)
{
OCR1A=t+125;//mt3
}
else
{
OCR1B=t+125;//mt4
}
}
//--------------------------------------------------------------------
int main(void)
{
CLKPR=0x80;
CLKPR=0x00;
//----------- system init ------------
//sei();
pwm_init();
adc_init();
usart_init();
_delay_ms(100);
led_on();
pwm_start();
while(1)
{
//TODO:: Please write your application code
t= adc_get_value(3) * 0.1222;
usart_clr(4);
usart_print_nb(t);
for(i=1;i<5;i++)
{
pwm_mt(i,t);
}
_delay_ms(30);
}
}
ISR(TIMER0_OVF_vect)
{
TCNT0=127;
}
ISR(TIMER1_OVF_vect)
{
TCNT1=127;
}
Đây là fuse của em nó, dùng thạch anh ngoại 16Mhz
File mô phỏng và prj gửi kèm.
thac mac sei().rar
Em code cho atmega 168pa, 8, 16 khi dùng lệnh sei(); đều ok, nhưng khi code cho atmega328 thì chỉ cẩn enable biến ngắt toàn cục là chương trình không chạy, bỏ lệnh sei(); thì chương trình lại chạy bình thường ( truyền usart lên máy tính ).
Để mọi người rõ hơn, em xin đưa code lên đây ạ, mục đích của prj là điều chế độ rộng xung của 4 chân tạo xung OCxn của avr thông qua điều chỉnh biến trở đầu vào ADC3. Khi mô phỏng thì vẫn bình thường, nhưng khi nạp vào chip thì không chạy. Các cao nhân bắt bệnh cho em với nhé !!!!
/*
* pwm_to_motor.c
*
* Created: 4/4/2013 4:21:20 PM
* Author: nghia
*/
#ifdef F_CPU
#define F_CPU 16000000UL
#endif
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
#include <vk1.6/usart.h>
#include <vk1.6/led.h>
#include <vk1.6/adc_0_to_3.h>
unsigned char i,t;
/************************************************** **********************/
/* pwm init, timer0-1 init
t_step=1/(16e6/256)= 256/16e6=1.6e-5 (s)
1ms= 62 step
2ms= 125 step
*/
/************************************************** **********************/
void pwm_init(void)
{
//------------- timer0 ----------------
DDRD|=(1<<PIND5)|(1<<PIND6);//output pwm pins
TCCR0A|=(1<<COM0A1)|(1<<COM0B1)|(1<<WGM01)|(1<<WGM 00);//fast pwm, compare match out put oc0a,oc0b
TIMSK0|=(1<<TOIE0);//enable interrupt when tm0 overflows
//------------- timer1 -----------------
DDRB|=(1<<PINB1)|(1<<PINB2);//output pwm pins
TCCR1A|=(1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);
TIMSK1|=(1<<TOIE1);
}
void pwm_start(void)
{
//-------- start running ---------------------
TCCR0B|=(1<<CS02);//start running
TCCR1B|=(1<<CS12)|(1<<WGM12);//start running
}
void pwm_mt1(unsigned char t)
{
if(t>127){t=127;}
OCR0A=t+125;
}
void pwm_mt2(unsigned char t)
{
if(t>127){t=127;}
OCR0B=t+125;
}
void pwm_mt3(unsigned char t)
{
if(t>125){t=125;}
OCR1A=t+127;
}
void pwm_mt4(unsigned char t)
{
if(t>127){t=127;}
OCR1B=t+125;
}
void pwm_mt(unsigned char i, unsigned char t)
{
if(t>127){t=127;}
if(i==1){OCR0A=t+125;}//mt1
else if(i==2)
{
OCR0B=t+125; //mt2
}
else if(i==3)
{
OCR1A=t+125;//mt3
}
else
{
OCR1B=t+125;//mt4
}
}
//--------------------------------------------------------------------
int main(void)
{
CLKPR=0x80;
CLKPR=0x00;
//----------- system init ------------
//sei();
pwm_init();
adc_init();
usart_init();
_delay_ms(100);
led_on();
pwm_start();
while(1)
{
//TODO:: Please write your application code
t= adc_get_value(3) * 0.1222;
usart_clr(4);
usart_print_nb(t);
for(i=1;i<5;i++)
{
pwm_mt(i,t);
}
_delay_ms(30);
}
}
ISR(TIMER0_OVF_vect)
{
TCNT0=127;
}
ISR(TIMER1_OVF_vect)
{
TCNT1=127;
}
Đây là fuse của em nó, dùng thạch anh ngoại 16Mhz
File mô phỏng và prj gửi kèm.
thac mac sei().rar
Comment