Tải bản đầy đủ (.pdf) (18 trang)

Tóm tắt C cho vi điều khiển

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (308.38 KB, 18 trang )

1
Tóm tắtvề Cchoviđiềukhiển
Tóm

tắt

về

C

cho

vi

điều

khiển
1
Bài tập về nhà
2
2
Chương trình C đầu tiên
#
in
c
l
ude
<r
eg5
1
.


h>
#include <reg51 h>
# c ude eg5 .
void main(void)
{
for (;;)
{
P1=0x55;
P1 0 AA
#include

<reg51
.
h>
void main(void)
{
while(1)
{
P1=0x55;
10AA
3
P1
=
0
x
AA
;
}
}
P

1
=
0
x
AA
;
}
}
Ví dụ lệnh sử dụng bit
#include <reg51.h>
void main(void)
{
unsigned char z;
unsigned

char

z;
z=P1;
z=z&0x3;
4
3
Chuyển đổi Hex - ASCII
#include <reg51.h>
void main(void)
#include <reg51.h>
void main(void)
void

main(void)

{
unsigned char x,y,z;
unsigned char
mybyte=0x29;
x=mybyte&0x0F;
P1=x|0x30;
y=mybyte&0xF0;
void

main(void)
{
unsigned char bcdbyte;
unsigned char w=‘4’;
unsigned char z=‘7’;
w
=
w&0x0F;
5
y=mybyte&0xF0;
y=y>>4;
P2=y|0x30;
}
w w&0x0F;
w=w<<4;
z=z&0x0F;
bcdbyte=w|z;
}
Ví dụ sử dụng với ngắt Timer
#include <reg51.h>
sbit SW =P1^7;

sbit IND =P1^0;
sbit WAVE =P2^5;
void timer0(void) interrupt 1 {
WAVE=~WAVE; //toggle pin
}
void main() {
SW=1; //make switch input
TMOD=0x02;
TH0=0xA4; //TH0=
92
6
TH0=0xA4;

//TH0=
-
92
IE=0x82; //enable interrupt for timer 0
while (1) {
IND=SW; //send switch to LED
}
}
4
Ví dụ tổng hợp về ngắt
#include <reg51.h>
sbit WAVE =P0^1;
void timer0() interrupt 1 {
void main() {
unsigned char x;
P1=0xFF; //make P1 an input
O022

void

timer0()

interrupt

1

{
WAVE=~WAVE; //toggle pin
}
void serial0() interrupt 4 {
if (TI==1) {
TI=0; //clear interrupt
}
l{
TM
O
D=
0
x
22
;
TH1=0xF6; //4800 baud rate
SCON=0x50;
TH0=0xA4; //5 kHz has =200us
IE=0x92; //enable interrupts
TR1=1; //start timer 1
TR0=1; //start timer 0
hil (1) {

7
e
l
se
{
P0=SBUF; //put value on pins
RI=0; //clear interrupt
}
}
w
hil
e
(1)

{
x=P1; //read value from pins
SBUF=x; //put value in buffer
P2=x; //write value to pins
}
}
Kiểu dữ liệu
 C có ba kiểu chính: characters, integers and
floating-point.
 Mỗi kiểu khác nhau thi có giá trị sử dụng khác nhau
và thao tác có thể thực hiện trên chúng
 Mỗi kiểu có độ chính xác khác nhau và giới hạn sử
dụng min max
 Kiểu mở rộng: long, double, void
5
Character Constants

 Là các số nguyên biểu diễn kỹ tự theo bảng
ASCII
ASCII
.
 Ví dụ ‘R’ có giá trị 52 hoặc 064 or 0x34
 Các giá trị ASCII có thể định nghĩa cho các ký tự
không thể gõ được từ bàn phím
\n new line
\
t
tab
\
t
tab
Lệnh
Cấu trúc for
for (init; test; action)
statement;
Tương tự như lệnh while
init;
while (test)
{
statement;
action;
}
6
Pointers
 Định nghĩa: Con trỏ là một biết dùng để chứa địa
chỉ trong bộ nhớ của biến đấy
 Khai báo * nghĩa là “trỏ tới”.

 Khai báo & nghĩa là “địa chỉ của ”.
 Lấ
y
n

i dun
g
thôn
g

q
ua
*
.
y ộ ggq
Truyền tham chiếu
 Tha
y
vi đưa vào theo
g
iá tr
ị,
n
g
ười ta đưa vào theo con trỏ. Giá
y g ị,g
trị đầu vào sẽ được copy những vẫn trỏ đến cùng ô nhớ ban đầu
swap(&a, &b); /* Pass pointers to a and b */
void swap(int* px, int* py)
/*px and py are copies of the pointer arguments*/

{
itt *
i
n
t

t
mp =
*
px;
*px = *py;
*py = tmp;
}
7
Ví dụ: strcpy()
 Thường dùng con trỏ như sau.
void strcpy (char *s, char *t)
{
while (*s++ = *t++)
;
}
Con trỏ và giá trị hàm
 Hàm có thể trả về con trỏ.
int* func_returns_pointer(void);
 Tuy nhiên sẽ là lỗi nếu trả về con trỏ của biến cục
bộ.
int* misguided(void)
{
int array[10], i;
for (i = 0; i < 10; ++i)

array[i] = i;
return array;
}
8
Mảng (array)
 Mảng là tập hợp xác định các phần tử có cùng kiểu
dbl t[0]/*E tb t*/
d
ou
bl
e emp
t
y
[0]
;
/*

E
rror: canno
t

b
e emp
t
y
*/
int an_array[10]; /* OK, allocate for 10 ints. */
a = an_array[0]; /* first element */
b = an_array[9]; /* last element */
c = an_array[10]; /* Error: but will compile */

 Người lập trình phải tự quản lý giới hạn của mảng.
Lệnh include
 Xác định các khai báo của các hàm và các biến.
#include <standard.h>
#include “myheader.h”
 File #include sẽ chèn toàn bộ đoạn mã mà nó
đ i đế àhầ ề
đ
ược gọ
i

đế
n v
à
o p
hầ
n m

m
9
Macros
Lệnh #define thường được sử dụng trong việc tạo ra các macro
Khai báo sau
Khai

báo

sau
#define MAX(x,y) ((x)>(y) ? (x) : (y))
Macro giống như hàm, nhưng thực chất không phải hàm. Thực tế

chương trình dịch sẽ thay thế mọi khai báo MAX bằng dòng lệnh
tương ứng các đối số đưa vào (inline)
int a=4, b= -7, c;
c = MAX(a,b);
expands to:
c = ((a)>(b) ? (a) : (b));
Các Macros đơn giản
#define SQR(x) ((x)*(x))
#define SGN(x) (((x)<0) ? -1 : 1)
#d fi ABS( ) ((( )<0) ?
() ())
#d
e
fi
ne
ABS(
x
)

(((
x
)<0)

?

-
(
x
)
:

(
x
))
#define ISDIGIT(x) ((x) >= '0' && (x) <= '9')
#define NELEMS(array) (sizeof(array) /
sizeof(array[0]))
#define CLAMP(val,low,high) \
((val)<(low) ? (low) : (val) > (high) ? (high) :
( l))
(
va
l))
#define ROUND(val) \
((val)>0 ? (int)((val)+0.5) : -(int)(0.5-(val)))
10
Ví dụ
#define TIMELOOP(CODE) {
\
#define

TIMELOOP(CODE)

{

\
t0 = clock(); \
for (i = 0; i<n; ++i) { CODE; } \
printf("%7d ", clock() - t0); \
}
19

Sử dụng như sau:
TIMELOOP(y = sin(x));
Dịch có điều kiện
Các lệnh dịch có điề kiện trong C

Các

lệnh

dịch



điề
u
kiện

trong

C
:
 #if, #elif, #else, #endif
 #ifdef, #ifndef
 Mục đích:
 Thêm vào các đoạn gỡ lỗi chương trình

Thêm vào các đoạn không phãi mã chuẩn
Thêm

vào


các

đoạn

không

phãi



chuẩn
,
 Bảo vệ các header-files sử dụng nhiều lần gọi.
11
Typedefs
A typedef cũng có cùng ý nghĩa như #define, tức là
thuầntùythựchiệnviệc thay thế vănbảnnhưng
thuần

tùy

thực

hiện

việc

thay


thế

văn

bản
,
nhưng

typedef là từ khóa của C, và được dịch bởi chương
trình dịch.
Từ khóa typedef cho phép tạo ra kiểu dữ liệu mới với
tên mới
typedef int Length;
Length len, maxlen;
Length lengths[50];
Toán tử làm việc với bit
C cung cấp 6 toán tử bit:
C

cung

cấp

6

toán

tử

bit:

&| ^~<<>>
Các toán tử này chỉ làm việc với các kiểu char, short, int,
long.
Không dùng cho dấu phẩy động.
Và 5
p

p

g
án bit như sau
ppg
&= |= ^= <<= >>=
Phép gán này tương tự với phép gán số học
z &= x | y;
z = z & (x | y);
12
Mặt nạ bit
 Bước 1. Tạo ra số nguyên để đại diện cho từng trạng
thái của bit (hoặt nhóm bit). Ví dụ
enum {
FIRST = 0x01, /* 0001 binary */
SECND = 0x02, /* 0010 binary */
THIRD = 0x04, /* 0100 binary */
FORTH = 0x08, /* 1000 binary */
23
ALL = 0x0f /* 1111 binary */
};
Mặt nạ bit
 Một cách khác

enum {
FIRST =
1

<
<
0
,
,
SECND = 1 << 1,
THIRD = 1 << 2,
FORTH = 1 << 3,
ALL = ~(~0 << 4)
};
 Dòng cuối cùng thường dùng để bật tắt một nhóm bit
/
/
24
1111 1111
/
* ~
0

*/
1111 0000 /* ~0 << 4 */
0000 1111 /* ~(~0 << 4) */
13
Thao tác với mặt nạ bit
unsigned flags = 0;
flags |= SECND | THIRD | FORTH; /* (1110). */

flags &= ~(FIRST | THIRD); /* (1010). */
flags ^= (THIRD | FORTH); /* (1100). */
if ((flags & (FIRST | FORTH)) == 0)
flags &= ~ALL; /* (0000). */
 Keys:
Tá tử|
dù để tổ h á ặt tá tử
dù để đả
25
1.
T
o
á
n
tử|

ng
để

tổ

h
ợp c
á
c m
ặt
nạ,
t
o
á

n
tử

~

ng
để

đả
o
dấu tất cả các bit (mọi bit là 1 trừ những bit được che mặt nạ).
2. |= dùng để set bits.
3. &= dùng để reset bits.
4. ^= dùng để đảo dấu bits.
5. & dùng để chọn bits (cho việc kiểm tra trạng thái).
Các Macros cho từng bít
#define BitSet(arg,posn) ((arg) | (1L << (posn)))
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))
#define BitTst(arg,posn) ((arg) & (1L << (posn)))
enum {FIRST, SECND, THIRD};
unsigned flags = 0;
flags = BitSet(flags, FIRST); /* Set first bit. */
fl BitFl (fl THIRD) /* T l thi d bit
26
fl
ags =
BitFl
p
(fl

ags,
THIRD)
;
/*

T
ogg
l
e
thi
r
d

bit
.
*/
if (BitTst(flags, SECND) == 0) /* Test second bit.
*/
flags = 0;
14
Ví dụ về checksum 8bit
#include <reg51.h>
void main(void)
{
idh
#include <reg51.h>
void main(void)
{
uns
i

gne
d
c
h
ar
mydata[]={0x25,0x62,0x3F,0x52};
unsigned char sum=0, x
unsigned char chksumbyte;
for (x=0;x<4;x++)
{
P2=mydata[x];
sum=sum+mydata[x];
P1
{
unsigned char mydata[]
={0x25,0x62,0x3F,0x52,0xE8};
unsigned char shksum=0;
unsigned char x;
for (x=0;x<5;x++)
chksum=chksum+mydata[x];
if ( hk 0)
27
P1
=sum;
}
chksumbyte=~sum+1;
P1=chksumbyte;
}
if


(
c
hk
sum==
0)
P0=‘G’;
else
P0=‘B’;
}
Phạm vi
 Phạm vi:
 Cục bộ
 Tĩnh
 Ngoài
15
Quay Lại Biến Cục Bộ
#include <stdio.h>
#include <assert.h>
#define PI 3.14
double CircleArea (double r) {
assert(r>0.0);
return PI * r * r;
}
double WasherArea (double inner, double outer) {
double innerArea, outerArea, washerArea;
assert(inner>=0.0 && outer>inner);
innerArea = CircleArea(inner);
outerArea = CircleArea(outer);
washerArea = outerArea - innerArea;
return washerArea;

}
int main(void) {
double innerRadius, outerRadius;
int scanfCount;
printf (“Input inner radius and outer radius: ”);
scanfCount = scanf (“ %lf %lf”, &innerRadius, &outerRadius);
if (scanfCount != 2 || innerRadius<0.0 || outerRadius<=innerRadius) {
printf (“Bad input…\n”);
return -1;
}
printf (“ %f ”, WasherArea(innerRadius, outerRadius ));
return 0;
}
Liên Quan Giữa Các Hàm
 Đồ thị tĩnh mô tả việc gọi hàm trong ví dụ trên
16
Tham Số Và Biến Cục Bộ
Phạm vi tĩnh (Static Scope)
 Biến hay hàm có từ khóa static ở trước chỉ có phạm
vi trong file được dùng đó.

Khởitạobiếntĩnh mặc định là 0

Khởi

tạo

biến

tĩnh


mặc

định



0
 Biến cục bộ dùng trong hàm khi có khai báo static sẽ
giữ nguyên giá trị giữa các lần gọi hàm
int increment(void)
{
static int local
_
static;
32
_
return local_static++;
}
17
Phạm vi Tĩnh
 Biến và hàm tĩnh của một file không thể được sử
d bởiáfilkhá
d
ụng
bởi
c
á
c
fil

e
khá
c
 Có thể có cùng một tên mà không bị tranh chấp tên.
File one.c:
static double myvariable;
static void myfunc(int idx);
File two c:
33
File

two
.
c:
static int myvariable;
static int myfunc(int idx);
Tóm tắt
 Hàm có phạm vi ngoài là mặc định

Hàm và biếncókhaibáo
static
chỉ giớihạnsử
Hàm



biến




khai

báo

static
chỉ

giới

hạn

sử

dụng trong file đó.
 Biến định nghĩa trong hàm chỉ có giá trị cục bộ
(ngay cả khi dùng static).
18
Chống include nhiều file

Phương pháp chống:

Phương

pháp

chống:
 “header guards”.
#ifndef A_HEADER_H_
#define A_HEADER_H_
/* Contents of header file is contained here. */

35
#endif

×