Thảo luận AVR và ứng dụng.

mta_cdt

Super Moderator
Thành viên BQT
#11
hôm nay mình làm 1 project điều chế độ rộng xung ứng dụng trong điều khiển động cơ DC, RC servo, động cơ BLDC.
- đầu tiên tìm hiều 1 chút về điều chế độ rộng xung (PWM) của AVR.
Đối với AVR tùy vào mỗi chip có số lượng chân PWM khác nhau nhưng đều ký hiệu là OCX (OC0,OC1A,OC1B...)
- tổng quát nhất mềm dẻo nhất trong điều chế độ rộng xung của AVR là sử dụng timer 1 (với atmega64 và 128 thì có thêm timer3) vì có thể điều chỉnh được cả về độ rộng xung và chu kỳ ở nhiều cấp. Mình xin lấy ví dụ về atmega8.
- Điều khiển pwm của atmega 8 dùng timer 1 chúng ta chú ý đến các thanh ghi điều khiển là TCCR1A. TCCR1B, ICR1,OCR1A,OCR1B.
- thanh ghi TCCR1A và TCCR1B. đây là 2 thanh ghi điều khiển chọn chế độ hoạt động của timer 1.
2013-08-13_223252.png

2013-08-13_223305.png
3 bit cs12, cs11, cs10 là 3 bit chọn bộ chia tần của timer 1 có giá trị như trên bảng.
- các bit WGM10, WGM11, WGM12, WGM13 là 4 bit chọn mode hoạt động như bảng dưới đây.
2013-08-13_223738.png
Nhìn vào bảng dễ nhận thấy ở chế độ PWM có 2 chế độ chính là fast PWM và phase correct pwm. Mình xét chế độ mode 14 làm ví dụ. Ở mode này
Fast pwm là chế độ điều xung nhanh ở chế độ này thanh ghi TCNT1 đếm từ 0 khi đó chân OC1A ở mức 1 khi TCNT1 đạt đến giá trị OCR1A thì mức ở chân OC1A đổi từ 1 thành 0. TCNT1 tiếp tục đếm đến khi bằng giá trị ICR1 thì TCNT1 xóa về 0 và cứ như vậy lặp lại.
2013-08-13_225007.png
- chế độ phase connect pwm: là chế độ điều xung có độ phân giải cao, hoạt động gần giống như fast pwm khác nhau cơ bản nhất là khi TCNT1=ICR1 thì TCNT1 không bị reset về 0 mà giảm dần về 0.
sơ đồ xung phase connect pwm
2013-08-13_225007.png
Thế là xong phần PWm giờ chúng ta ứng dụng nó vào điều khiển động cơ RCservo.
- động cơ RCservo là động cơ công suất điều khiển góc quay. Để điều khiển góc quay thì chúng ta phải điều xung tần số 50hz với độ rộng xung dương là 1ms thì động cơ quay -90 độ, 1.5ms ở 0 độ còn 2ms thì 90 độ.

Tương tự cũng có thể điều khiển động cơ không chổi than qua ESC là loại động cơ đẩy của máy bay mô hình. Nếu mà bạn nào yêu thích máy bay cánh bằng, trực thăng, quad roto thì không thoát được. Chỉ khác là động cơ RC điều khiển góc quay còn BLDC điều khiển tốc độ. Nếu độ rộng xung dương 1ms thì động cơ đứng im ở 2ms động cơ quay với vận tốc max.
code mình viết trên 2 phần mềm là codevison avr và avr studio.
trên codevison avr
Mã:
/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.0 Professional
Automatic Program Generator
© Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
 
Project :
Version :
Date    : 8/13/2013
Author  : NeVaDa
Company :
Comments:
 
 
Chip type              : ATmega8
Program type            : Application
AVR Core Clock frequency: 8.000000 MHz
Memory model            : Small
External RAM size      : 0
Data Stack size        : 256
*****************************************************/
 
#include <mega8.h>
#include <delay.h>
 
// Declare your global variables here
 
void main(void)
{
// Declare your local variables here
 
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=Out Func1=Out Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=0 State1=0 State0=T
PORTB=0x00;
DDRB=0x06;
 
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
 
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;
 
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
 
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 1000.000 kHz
// Mode: Fast PWM top=ICR1
// OC1A output: Non-Inv.
// OC1B output: Non-Inv.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0xA2;
TCCR1B=0x1A;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x4E;
ICR1L=0x20;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
 
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
 
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;
 
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
 
// USART initialization
// USART disabled
UCSRB=0x00;
 
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
 
// ADC initialization
// ADC disabled
ADCSRA=0x00;
 
// SPI initialization
// SPI disabled
SPCR=0x00;
 
// TWI initialization
// TWI disabled
TWCR=0x00;
 
while (1)
      {
        OCR1A=1000;
        delay_ms(1000);
        OCR1A=1500;
        delay_ms(1000);
          OCR1A=2000;  delay_ms(1000);
      // Place your code here
 
      }
}
viết trên avrstudio.
Mã:
#define F_CPU 8000000
#include <util/delay.h>
#include <avr/io.h>
 
int main(void)
{
PORTB=0x00;
DDRB=0xFF;
 
TCCR1A=(1<<COM1A1)|(1<<COM1B1)|(1<<WGM11);
TCCR1B=(1<<WGM13)|(1<<WGM12)|(1<<CS11);
// chon bo chia tan 1/8 mode 14
ICR1=20000;
while(1)
{
  OCR1A=1000;
  _delay_ms(1000);
 
  OCR1A=1500;
  _delay_ms(1000);
    OCR1A=2000;
  _delay_ms(1000);
 
    }
 
}
kết quả mô phỏng.
2013-08-13_215545.png
 

Đính kèm

mta_cdt

Super Moderator
Thành viên BQT
#12
còn 1 phần nữa trong box avr của mình chưa có là phần giao tiếp với ds1307.
Về ds1307 bên pic với 89 thì có nhiều người viết rùi còn bên AVR chưa có. Hôm nay ngày nghỉ làm nốt forum dạo này cũng trầm quá. Để các bạn mới bắt đầu avr mình viết bằng codevison avr.
khi bật phần mềm lên khởi tạo codewinrar xong thiết lập chip tần số thạch anh. Sau đó để khởi tạo Ds1307 chọn I2C sau đó chọn đến cổng hỗ trợ I2C. Mình lấy atmega8 làm ví dụ thì cổng I2C ở PORTC.
2013-09-01_210417.jpg
sau đó chọn tiếp như sau chú ý hai chân SDA với SCL phải đúng với phần cứng.
2013-09-01_210521.jpg
rồi dùng tiếp cái gì thì khởi tạo cái đó. Đối với bài này đơn giản mình làm thêm cái truyền thông với máy tính nữa
sau đó code như sau:
Mã:
/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.0 Professional
Automatic Program Generator
© Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
 
Project :
Version :
Date    : 9/1/2013
Author  : NeVaDa
Company :
Comments:
 
 
Chip type              : ATmega8L
Program type            : Application
AVR Core Clock frequency: 8.000000 MHz
Memory model            : Small
External RAM size      : 0
Data Stack size        : 256
*****************************************************/
 
#include <mega8.h>
#include <delay.h>
#include <stdio.h>
 
// I2C Bus functions
#asm
  .equ __i2c_port=0x15 ;PORTC
  .equ __sda_bit=4
  .equ __scl_bit=5
#endasm
#include <i2c.h>
 
// DS1307 Real Time Clock functions
#include <ds1307.h>
 
// Standard Input/Output functions
#include <stdio.h>
 
// Declare your global variables here
unsigned char h,m,s; // hàm luu 3 bien gio phut giay
void main(void)
{
// Declare your local variables here
 
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;
 
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
 
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;
 
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
 
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
 
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
 
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;
 
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
 
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;
 
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
 
// ADC initialization
// ADC disabled
ADCSRA=0x00;
 
// SPI initialization
// SPI disabled
SPCR=0x00;
 
// TWI initialization
// TWI disabled
TWCR=0x00;
 
// I2C Bus initialization
i2c_init();
 
// DS1307 Real Time Clock initialization
// Square wave output on pin SQW/OUT: On
// Square wave frequency: 1Hz
rtc_init(0,1,0);
rtc_set_time(20,47,30);    // cai dat gia tri gio phut giay
while (1)
      {  rtc_get_time(&h,&m,&s);  // lay gia tri gio phut giay
      printf("%d:%d:%d\n",h,m,s);  // gui len may tinh
     
      // Place your code here
 
      }
}
và được kết quả là
2013-09-01_211608.jpg
code và file mô phỏng download tại file đính kèm.
 

Đính kèm

#13
mta_cdt
Em cám ơn anh nhiều
//===================================================
MOD: với những bài viết dài thì em không nên trích dẫn
 

longma

Kỹ sư
Banned
#14
:), Không đơn giản thế đâu bạn, nó #include rất nhiều file. Mà quan trọng là hiểu quy trình vận hành, rồi viết chương trình mới bài bản. Code thì mỗi người một cách, tốt nhất chỉ cần gợi ý. Nếu Ct đúng nó sẽ xuất hiện đồng hồ cho bạn xem.
 

mta_cdt

Super Moderator
Thành viên BQT
#15
:), Không đơn giản thế đâu bạn, nó #include rất nhiều file. Mà quan trọng là hiểu quy trình vận hành, rồi viết chương trình mới bài bản. Code thì mỗi người một cách, tốt nhất chỉ cần gợi ý. Nếu Ct đúng nó sẽ xuất hiện đồng hồ cho bạn xem.
cần những file gì mà nhiều thế bạn có thể chỉ bảo giúp anh em được không?
 

chung123

Học sinh phổ thông
#16
e hỏi ty ad ơi. e muốn tìm mạch led chạy chữ chạy con avr code asm. ad giúp e với hix hix
 

mta_cdt

Super Moderator
Thành viên BQT
#17
e hỏi ty ad ơi. e muốn tìm mạch led chạy chữ chạy con avr code asm. ad giúp e với hix hix
Rất buồn cho bạn là mình không biết code asm cho avr.
 

bienhaui

Học sinh phổ thông
#19
thấy nhộn vào góp vui tí. mình thấy ít ai mô phỏng BLDC trên protues nên thử với ATmega8 . nhưng chưa mượt lắm.:-?
 

Quảng cáo Google