Systemy sterowania
w elektronice przemysłowej
Wykład 6
dr inż. Bartosz Pękosławski
Łódź, dn. 26.04.2012
Katedra Mikroelektroniki i Technik Informatycznych
Politechnika Łódzka
Plan wykładu
2
1. Programowanie mikrokontrolera ATmega32 w języku C
2. Przegląd wybranych bibliotek standardowych
3. Przegląd bibliotek dla płytek Kamami ZL15AVR
Język C
3
Opracowany w latach 60. XX wieku przez Dennisa Ritchiego
Obecny standard ISO/IEC 9899-1999 (C99)
Język wysokiego poziomu
Możliwość pisania zwięzłych programów
Wymaga dokładnego zrozumienia kodu
AVR → kompilator AVR-GCC (ang. GNU Compiler Collection)
z pakietu WinAVR
Struktura programu w języku C
4
#include <avr/io.h>
#include <stdlib.h>
#include ”plik.h”
...
unsigned char zmienna1;
...
void funkcja1(int parametr){
...
}
...
//komentarz
int main(void){
...
return 0;
}
definicje zmiennych globalnych
dyrektywy
program główny
deklaracje/definicje
funkcji pomocniczych
Program w języku C - moduły
5
#ifndef PLIK_H_INCLUDED
#define PLIK_H_INCLUDED
...
extern int zmienna_globalna;
void funkcja_skladowa(void);
...
#endif
#include ”plik.h”
...
int zmienna_globalna;
void funkcja_skladowa(void){
...
}
...
plik.h
plik.c
tylko deklaracje
AVR-GCC – pliki generowane
6
Plik pośredni (object file) – rozszerzenie *.o
Plik wykonywalny (moduły połączone przez linker) –
rozszerzenie *.elf
Plik wyjściowy – rozszerzenie *.bin i *.hex
Dodatkowe pliki (*.lss – listing z *.elf, *.map)
AVR-GCC – plik makefile
7
## General Flags
PROJECT = cw6
MCU = atmega32
TARGET = cw6.elf
CC = avr-gcc
…
## Include Directories
INCLUDES = -I"C:\Users\VAIO\Documents\PracaDMCS\Dydaktyka\KSEP\cw6\."
## Objects that must be built in order to link
OBJECTS = cw6.o adc.o
## Objects explicitly added by the user
LINKONLYOBJECTS =
## Build
all: $(TARGET) cw6.hex cw6.eep cw6.lss size
## Compile
cw6.o: ../cw6.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<
adc.o: ../adc.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<
Plik sterujący dla programu make kierującego procesem kompilacji programu
(odpowiednie decyzje o rekompilacji w przypadku zmian w plikach źródłowych)
definicje plików obiektowych
ścieżki do bibliotek użytkownika
flagi
kompilacja
(make all)
AVR-GCC – plik makefile (c.d.)
8
##Link
$(TARGET): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $
(TARGET)
%.hex: $(TARGET)
avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@
%.eep: $(TARGET)
-avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0
%.lss: $(TARGET)
avr-objdump -h -S $< > $@
size: ${TARGET}
@echo
@avr-size -C --mcu=${MCU} ${TARGET}
## Clean target
.PHONY: clean
clean:
-rm -rf $(OBJECTS) cw6.elf dep/* cw6.hex cw6.eep cw6.lss cw6.map
AVR Studio automatycznie generuje makefile
czyszczenie projektu z plików wynikowych
(make clean)
wyświetlanie rozmiaru
AVR-GCC – typy zmiennych
9
Typ
Liczba bitów
Wartość min
Wartość max
char
8
-128
127
signed char
8
-128
127
unsigned char
8
0
255
short int
16
-32768
32767
unsigned short int
16
0
65535
int
16
-32768
32767
unsigned int
16
0
65535
long int
32
-2
31
2
31
- 1
unsigned long int
32
0
2
32
- 1
long long int
64
-2
63
2
63
- 1
unsigned long long int
64
0
2
64
- 1
float
32
±1,18E-38
±3,4E38
double
32
±1,18E-38
±3,4E38
long double
32
±1,18E-38
±3,4E38
AVR-GCC – operatory
10
Operator
Znaczenie
+
dodawanie
-
odejmowanie
*
mnożenie
/
dzielenie
%
reszta modulo
=
przypisanie
++
inkrementacja
--
dekrementacja
+=
dodawanie i
przypisanie
-=
odejmowanie i
przypisanie
*=
mnożenie i
przypisanie
/=
dzielenie i
przypisanie
%=
dzielenie modulo i
przypisanie
Operator
Znaczenie
<
mniejszy
>
większy
<=
mniejszy lub
równy
>=
większy lub
równy
==
równy
!=
różny
&&
iloczyn logiczny
||
suma logiczna
!
negacja
Operator
Znaczenie
|
bitowe OR
&
bitowe AND
^
bitowe XOR
~
dopełnienie bitowe
<<
przesunięcie w lewo
>>
przesunięcie w prawo
|=
bitowe OR i przypisanie
&=
bitowe AND i przypisanie
^=
bitowe XOR i przypisanie
<<=
przesunięcie w lewo i
przypisanie
>>=
przesunięcie w prawo i
przypisanie
Warunkowy operator trójargumentowy:
wyrażenie1 ? wyrażenie2 : wyrażenie3
np.
c = (a == 2) ? b : b + 1;
AVR-GCC – podstawowe instrukcje
11
if (warunek)
{instrukcje}
else
{instrukcje}
if (warunek1)
{instrukcje}
else if (warunek2)
{instrukcje}
else
{instrukcje}
switch (wyrażenie)
{
case stała1:
instrukcje
case stała2:
instrukcje
break;
...
default:
instrukcje
}
while (wyrażenie)
{instrukcje}
do
{instrukcje}
while (wyrażenie);
for (wyrażenie1; wyrażenie2;
wyrażenie3)
{instrukcje}
np.
for (i=0; i<10; i++)
funkcja(i);
AVR-GCC – wskaźniki i tablice
12
typ *nazwa_wskaznika;
np.
int *wskaznik;
nazwa_wskaznika = &nazwa_zmiennej;
np.
wskaznik = &liczba;
nazwa_zmiennej = *nazwa_wskaznika;
np.
liczba = *wskaznik;
typ nazwa_tablicy[liczba_elementow];
np.
char tablica[5];
nazwa_tablicy[nr_elementu] = wyrażenie;
np.
tablica[3] = a + b;
*(nazwa_tablicy + nr_elementu*rozmiar_elementu) = wyrażenie;
np.
*(tablica + 3) = a + b;
deklaracja wskaźnika
przypisanie wskaźnikowi
adresu zmiennej
przypisanie zmiennej
wartości wskazywanej przez wskaźnik
definicja tablicy
przypisanie
elementowi
tablicy
wartości
wyrażenia
Program w języku C - makra
13
#define stala
15
#define stala2
20*sqrt(stala)
#define PORT(x) XPORT(x)
#define XPORT(x) (PORT##x)
#ifndef F_CPU
#define F_CPU
16000000
#endif
dla funkcji z delay.h
dla funkcji z delay.h
Program w języku C – przerwania
14
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
void init(void){
...
TIMSK = 1 << TOIE0;
sei();
...
}
SIGNAL(SIG_OVERFLOW0){
...
}
int main(void){
init();
...
}
włączenie przerwania
załączenie plików nagłówkowych
program główny
procedura obsługi przerwania
uchwyt dla przerwania w:
SIGNAL() - bez dodatkowych przerwań
lub INTERRUPT() - po sei() możliwe
dodatkowe przerwania
Program w języku C – przerwania
15
Uchwyty funkcji obsługi:
SIG_INTERRUPT0 do SIG_INTERRUPT2 – przerwania zewnętrzne
SIG_OUTPUT_COMPARE2
– przerwanie porównania timera 2
SIG_OVERFLOW2
– przerwanie przepełnienia timera 2
SIG_INPUT_CAPTURE1
– przerwanie przechwytywania timera 1
SIG_OUTPUT_COMPARE1A
– przerwanie porównania licznika 1(A)
SIG_OUTPUT_COMPARE1B
– przerwanie porównania licznika 1(B)
SIG_OVERFLOW1
– przerwanie przepełnienia licznika 1
SIG_OUTPUT_COMPARE0
– przerwanie porównania licznika 0
SIG_OVERFLOW0
– przerwania przepełnienia licznika 0
SIG_SPI
– przerwanie SPI
SIG_UART_RECV
– przerwanie UART0 – odbiór znaku
SIG_UART_DATA
– przerwanie UART0 – pusty rejestr danych
SIG_UART_TRANS
– przerwania UART0 – zakończenie transmisji
SIG_ADC
– przerwanie ADC – zakończenie przetwarzania
SIG_EEPROM
– przerwanie EEPROM – gotowość
SIG_COMPARATOR
– przerwanie z komparatora analogowego
avr/crc16.h
Obliczanie 16 bitowego CRC
avr/delay.h
Funkcje opóźniające
avr/eeprom.h
Funkcje dostępu do wewnętrznej pamięci EEPROM
avr/ina90.h
Nagłówek dla kompatybilności z IAR C
avr/interrupt.h Funkcje obsługi przerwań
avr/io.h
Włącza nagłówki I/O dla wybranego mikrokontrolera
avr/iom32.h
Definicje I/O dla mikrokontrolera ATmega32 (nie stosować bezpośrednio)
avr/parity.h
Obliczanie bitu parzystości
avr/pgmspace.h Funkcje dostępu do pamięci programu
avr/sfr_defs.h
Makra dla urządzeń peryferyjnych
avr/signal.h
Obsługa przerwań i sygnałów AVR
avr/sleep.h
Zarządzanie poborem energii
avr/timer.h
Funkcje dla timera 0
avr/twi.h
Obsługa TWI (I2C)
avr/wdt.h
Funkcje kontrolujące układ watchdoga
ctype.h
Funkcje testujące wartości typów znakowych
errno.h
Obsługa błędów
inttypes.h
Definicje różnych typów całkowitych
math.h
Różne funkcje matematyczne
setjmp.h
Zawiera funkcje długich skoków (long jumps)
stdio.h
Standardowa biblioteka wejścia/wyjścia
stdlib.h
Różne funkcje standardowe
string.h
Funkcje operujące na łańcuchach
Program w języku C
– biblioteki standardowe
16
...
#define TWBR _SFR_IO8(0x00)
#define TWSR _SFR_IO8(0x01)
#define TWAR _SFR_IO8(0x02)
#define TWDR _SFR_IO8(0x03)
…
* External Interrupt Request 0 */
#define INT0_vect
_VECTOR(1)
#define SIG_INTERRUPT0
_VECTOR(1)
…
* TIMSK */
#define OCIE2 7
#define TOIE2 6
...
Biblioteka standardowa avr/io.h
17
#include <avr/sfr_defs.h>
...
#elif defined (__AVR_ATmega32__)
#include <avr/iom32.h>
...
#include <avr/portpins.h>
#include <avr/common.h>
#include <avr/version.h>
/* Include fuse.h after individual IO header files. */
#include <avr/fuse.h>
/* Include lock.h after individual IO header files. */
#include <avr/lock.h>
…
/* Constants */
#define SPM_PAGESIZE 128
#define RAMEND 0x85F
#define XRAMEND RAMEND
#define E2END 0x3FF
#define E2PAGESIZE 4
#define FLASHEND 0x7FFF
…
Biblioteka standardowa avr/delay.h
18
void _delay_ms(double __ms);
void _delay_us(double __us);
maks. opóźnienie = 6.5535 s
maks. opóźnienie =
768 µs / F_CPU [MHz]
Biblioteka standardowa math.h
19
#define M_E
2.7182818284590452354
#define M_LOG2E
1.4426950408889634074/* log_2 e */
#define M_LOG10E 0.43429448190325182765
/* log_10 e */
#define M_LN2
0.69314718055994530942
/* log_e 2 */
#define M_LN10
2.30258509299404568402
/* log_e 10 */
#define M_PI
3.14159265358979323846
/* pi */
#define M_PI_2
1.57079632679489661923
/* pi/2 */
#define M_PI_4
0.78539816339744830962
/* pi/4 */
#define M_1_PI
0.31830988618379067154
/* 1/pi */
#define M_2_PI
0.63661977236758134308
/* 2/pi */
#define M_2_SQRTPI
1.12837916709551257390
/* 2/sqrt(pi) */
#define M_SQRT2
1.41421356237309504880
/* sqrt(2) */
#define M_SQRT1_2
0.70710678118654752440
/* 1/sqrt(2) */
…
double cos(double x)
double fabs(double x)
double fmod(double x, double y)
double modf(double x, double *iptr)
double sin(double x)
double sqrt(double x)
double tan(double x)
double floor(double x)
double ceil(double x)
double frexp(double x, int *exp)
double ldexp(double x, int exp);
double exp(double x)
double cosh(double x)
double sinh(double x)
double tanh(double x)
double acos(double x)
double asin(double x)
Zwraca arcus sinus z x.
double atan(double x)
double atan2(double x, double y)
double log(double x)
double log10(double x)
double pow(double x, double y)
double strtod(const char *s, char **endptr)
double square(double x)
double inverse(double x)
Program w języku C
- biblioteki dodatkowe
20
Na zajęciach (Kamami ZL15AVR):
adc.h
Obsługa przetwornika A/C
HD44780.h
Obsługa wyświetlacza alfanumerycznego LCD
SPI.h
Inicjalizacja i transmisja SPI
TWI.h
Inicjalizacja i transmisja TWI
usart.h
Inicjalizacja i transmisja USART
Biblioteka adc.h
21
void ADC_Init(void);
int getADC(char channel);
inicjalizacja przetwornika (preskaler = 128,
napięcie odniesienia AVCC)
wykonanie pojedynczej konwersji
void LCD_Initialize(void);
void LCD_WriteCommand(unsigned char);
void LCD_WriteData(unsigned char);
void LCD_WriteText(char *);
void LCD_WriteText_P(prog_char *);
void LCD_GoTo(unsigned char, unsigned char);
void LCD_Clear(void);
void LCD_Home(void);
void LCD_ShiftLeft(void);
void LCD_ShiftRight(void);
Biblioteka HD44780.h
22
inicjalizacja wyświetlacza
(dwie linie, 4-bitowa
komunikacja, kasowanie...)
kasowanie zawartości
wyświetlacza
kursor na początek
zapis rozkazu do rejestru
wyświetlenie tekstu z
pamięci programu
kursor w danej pozycji
(kol, wiersz)
wyświetlenie łańcucha znaków
wyświetlenie znaku
przesunięcie tekstu w lewo
przesunięcie tekstu w prawo
Biblioteka SPI.h
23
void SPI_Init(void);
char SPI_Transmit(char cData);
inicjalizacja interfejsu (master, preskaler = 16,
CPOL = CPHA = 0)
wykonanie pojedynczej transmisji
Biblioteka TWI.h
24
void TWI_Init(void);
void TWI_Start(void);
void TWI_Stop(void);
char TWI_Write(char data);
char TWI_Read(char ack);
inicjalizacja interfejsu (TWBR = 100)
wygenerowanie sekwencji START
wygenerowanie sekwencji STOP
zapis bajtu do slave'a
odczyt bajtu ze slave'a
Biblioteka usart.h
25
void USART_Init(int baud);
void USART_PutChar(char data);
char USART_GetChar(void);
void USART_PutString(char * s);
void USART_GetString(char * s);
inicjalizacja interfejsu (odbiornik i nadajnik,
8 bitów danych, 1 bit stopu, bez kontroli
parzystości)
wysłanie znaku
odbiór znaku
wysłanie łańcucha znaków
odbiór łańcucha znaków
Dziękuję za uwagę.