Witam użytkowników forum.
Korzystając z zestawu zl3avr (z uC Atmega32) chciałem sterować pracą silnika krokowego (unipolarnego). Jako że jestem poczatkującym w tej dziedzinie to efekt jest nie za dobry. Na chwile obecną jestem w stanie sterować pracą silniczka w prawo i w lewo, ale żeby to było możliwe to musze mieć cały czas wciśnięty odpowiedni przycisk. Kierunek obrotu silnika jest wyświetlany na LCD(2x16).
Programowi jest daleko do doskonałości ponieważ nie bardzo wiem jak zaimplementować PWM aby móc płynnie sterować mocą silniczka, a kolejnym problemem jest dodanie kolejnych przycisków. Obecnie mogę korzystać tylko z dwóch, próba dodania kolejnego przycisku nie przynosi porządanego efektu.
Ponieważ po przewertowaniu juz kilkudziesięciu stron nie znalazłem rozwiązania mojego problemu. Stwierdziłem, ze któryś z użytkowników forum moze znać rozwiązanie tych trudności i naprowadzi mnie jak mogę się z tym uporać. Oczywiście ogólną zasadę działania PWM znam tylko nie bardzo wiem jak to napisać w C aby zadziałało na Atmega32.
Na początku kodu jest zamieszczony kod do LCD dopiero pod koniec jest właściwy nie do końca działający program :/
Korzystając z zestawu zl3avr (z uC Atmega32) chciałem sterować pracą silnika krokowego (unipolarnego). Jako że jestem poczatkującym w tej dziedzinie to efekt jest nie za dobry. Na chwile obecną jestem w stanie sterować pracą silniczka w prawo i w lewo, ale żeby to było możliwe to musze mieć cały czas wciśnięty odpowiedni przycisk. Kierunek obrotu silnika jest wyświetlany na LCD(2x16).
Programowi jest daleko do doskonałości ponieważ nie bardzo wiem jak zaimplementować PWM aby móc płynnie sterować mocą silniczka, a kolejnym problemem jest dodanie kolejnych przycisków. Obecnie mogę korzystać tylko z dwóch, próba dodania kolejnego przycisku nie przynosi porządanego efektu.
Ponieważ po przewertowaniu juz kilkudziesięciu stron nie znalazłem rozwiązania mojego problemu. Stwierdziłem, ze któryś z użytkowników forum moze znać rozwiązanie tych trudności i naprowadzi mnie jak mogę się z tym uporać. Oczywiście ogólną zasadę działania PWM znam tylko nie bardzo wiem jak to napisać w C aby zadziałało na Atmega32.
Na początku kodu jest zamieszczony kod do LCD dopiero pod koniec jest właściwy nie do końca działający program :/
/* Program demonstrujacy dzialanie silnika krokowego
Piny/Pins:
PD1 - RS
PD2 - E
PD3 - D4
PD4 - D5
PD5 - D6
PD6 - D7
*/
#define F_CPU 8000000UL
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#define DDR_DB4 DDRD
#define PORT_DB4 PORTD
#define DB4 PD3
#define DDR_DB5 DDRD
#define PORT_DB5 PORTD
#define DB5 PD4
#define DDR_DB6 DDRD
#define PORT_DB6 PORTD
#define DB6 PD5
#define DDR_DB7 DDRD
#define PORT_DB7 PORTD
#define DB7 PD6
#define DDR_RS DDRD
#define PORT_RS PORTD
#define RS PD1
#define DDR_E DDRD
#define PORT_E PORTD
#define E PD2
#define SET_B1 PORT_B1 |= _BV(B1)
#define CLR_B1 PORT_B1 &= ~_BV(B1)
#define SET_B2 PORT_B2 |= _BV(B2)
#define CLR_B2 PORT_B2 &= ~_BV(B2)
#define SET_B3 PORT_B3 |= _BV(B3)
#define CLR_B3 PORT_B3 &= ~_BV(B3)
#define SET_B4 PORT_B4 |= _BV(B4)
#define CLR_B4 PORT_B4 &= ~_BV(B4)
#define SET_DB4 PORT_DB4 |= _BV(DB4)
#define CLR_DB4 PORT_DB4 &= ~_BV(DB4)
#define SET_DB5 PORT_DB5 |= _BV(DB5)
#define CLR_DB5 PORT_DB5 &= ~_BV(DB5)
#define SET_DB6 PORT_DB6 |= _BV(DB6)
#define CLR_DB6 PORT_DB6 &= ~_BV(DB6)
#define SET_DB7 PORT_DB7 |= _BV(DB7)
#define CLR_DB7 PORT_DB7 &= ~_BV(DB7)
#define SET_E PORT_E |= _BV(E)
#define CLR_E PORT_E &= ~_BV(E)
#define SET_RS PORT_RS |= _BV(RS)
#define CLR_RS PORT_RS &= ~_BV(RS)
#define LCD_X 16
#define LCD_Y 2
union
{
int tds;
char nds[2];
} ds;
char buf[6];
void out_nibble(char x)
{
CLR_DB4;
CLR_DB5;
CLR_DB6;
CLR_DB7;
if(x & _BV(0)) SET_DB4;
if(x & _BV(1)) SET_DB5;
if(x & _BV(2)) SET_DB6;
if(x & _BV(3)) SET_DB7;
}
void write_to_lcd(char x)
{
SET_E;
out_nibble(x >> 4);
CLR_E;
SET_E;
out_nibble(x);
CLR_E;
_delay_ms(1);
}
void delay(int useconds)
{
int s;
useconds = useconds;
for (s=0; s<useconds;s++);
}
void write_command(char x)
{
CLR_RS;
write_to_lcd(x);
}
void write_char(char x)
{
SET_RS;
write_to_lcd(x);
}
void write_text(char * s)
{
while(*s)
{
write_char(*s);
s++;
}
}
void lcd_init(void)
{
DDR_DB4 |= _BV(DB4);
DDR_DB5 |= _BV(DB5);
DDR_DB6 |= _BV(DB6);
DDR_DB7 |= _BV(DB7);
DDR_E |= _BV(E);
DDR_RS |= _BV(RS);
_delay_ms(15);
CLR_E;
CLR_RS;
char i;
for(i = 0; i < 3; i++)
{
SET_E;
out_nibble(0x03);
CLR_E;
_delay_ms(5);
}
SET_E;
out_nibble(0x02);
CLR_E;
_delay_ms(1);
write_command(0x28); // interfejs 4-bity, 2-linie, znak 5x7
write_command(0x08); // wyłącz LCD, kursor i miganie
write_command(0x01); // czyść LCD
write_command(0x06); // bez przesuwania w prawo
write_command(0x0C); // włącz LCD, bez kursora i mrugania
}
void LCD_xy(uint8_t x, uint8_t y)
{
switch(y)
{
case 1: y=0x40; break;
case 2: y=0x14; break;
}
write_command(0x80+y+x);
}
void lcdxy(uint8_t x, uint8_t y)
{
switch(y)
{
case 1: y=0x40; break;
case 2: y=0x14; break;
}
write_command(0x80+y+x);
}
void LCD_clr(void)
{
write_command(0x01);
_delay_ms(1);
LCD_xy(0,0);
}
//==========================================================================================//
int main ()
{
lcd_init();
while(1)
{
LCD_xy(1,0);
write_text("Obrot silnika w:");
/* Wszystkie linie portu B będą wyjściami*/
DDRB = 0xff;
// linie PC0,PC1 będą wejściami z podciągnięciem do VCC
DDRC = 0x00;
PORTC = 0x03;
// Jeśli pierwszy przycisk wciśnięty
if(!(PINC & 1<<0))
{
LCD_xy(0,1);
write_text("lewo");
for(int k=3;k>=0;k--)
{
PORTB = _BV(k);
_delay_ms(50);
}
LCD_clr();
}
else
{
PORTB = 0x00;
}
//Jeśli drugi przycisk wciśnięty
if(!(PINC & 1<<1))
{
LCD_xy(0,1);
write_text("prawo");
for(int k=0;k<=3;k++)
{
PORTB = _BV(k);
_delay_ms(100);
}
LCD_clr();
}
else{PORTB = 0x00;}
if(!(PINC & 1<<2))
{
LCD_xy(0,10);
write_text("prawda");
}
}
}