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,
Trang 1Tóm tắt về C cho vi điều khiển
Trang 2Bài tập về nhà
2
Trang 3Chương trình C đầu tiên
while(1){
P1=0x55;P1=0xAA;}
}
Trang 5unsigned char bcdbyte;unsigned char w=‘4’;unsigned char z=‘7’;w=w&0x0F;
w=w<<4;
z=z&0x0F;
bcdbyte=w|z;
}
Trang 6void timer0(void) interrupt 1 {
WAVE=~WAVE; //toggle pin
IND=SW; //send switch to LED }
}
Trang 7Ví dụ tổng hợp về ngắt
#include <reg51.h>
sbit WAVE =P0^1;
void timer0() interrupt 1 {
WAVE=~WAVE; //toggle pin
P0=SBUF; //put value on pins
RI=0; //clear interrupt
}
}
void main() { unsigned char x;
P1=0xFF; //make P1 an input TMOD=0x22;
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 while (1) {
x=P1; //read value from pins SBUF=x; //put value in buffer P2=x; //write value to pins }
}
Trang 8Kiể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
Trang 11Đị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 dung thông qua *.
Trang 12Truyền tham chiếu
Thay vi đưa vào theo giá trị, người ta đưa vào theo con trỏ Giá 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*/ {
int tmp = *px;
*px = *py;
*py = tmp;
}
Trang 13Ví dụ: strcpy()
Thường dùng con trỏ như sau.
void strcpy (char *s, char *t) {
while (*s++ = *t++)
;
}
Trang 15Mảng (array)
Mảng là tập hợp xác định các phần tử có cùng kiểu
double empty[0]; /* Error: cannot be empty */
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.
Trang 16File #include sẽ chèn toàn bộ đoạn mã mà
nó được gọi đến vào phần mềm
Trang 17Lệnh #define thường được sử dụng trong việc tạo ra các macro
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));
Trang 18Các Macros đơn giản
Trang 19Ví dụ
#define TIMELOOP(CODE) { \
t0 = clock(); \ for (i = 0; i<n; ++i) { CODE; } \ printf("%7d ", clock() - t0); \
}
Sử dụng như sau:
TIMELOOP(y = sin(x));
Trang 20Dịch có điều kiện
Các lệnh dịch có đ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,
Bảo vệ các header-files sử dụng nhiều lần gọi
Trang 21A typedef cũng có cùng ý nghĩa như #define,
tức là 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];
Trang 22Toán tử làm việc với 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 phép gán bit như sau
&= |= ^= <<= >>=
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);
Trang 25if ((flags & (FIRST | FORTH)) == 0)
flags &= ~ALL; /* (0000) */
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).
Trang 26Cá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};
Trang 27unsigned char sum=0, x
unsigned char chksumbyte;
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 (chksum==0) P0=‘G’;
else P0=‘B’;
}
Trang 29Quay Lại Biến Cục Bộ
double WasherArea (double inner, double outer) {
double innerArea, outerArea, washerArea;
assert(inner>=0.0 && outer>inner);
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”);
Trang 30Liên Quan Giữa Các Hàm
Đồ thị tĩnh mô tả việc gọi hàm trong ví dụ trên
Trang 31Tham Số Và Biến Cục Bộ
Trang 32Phạ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ởi tạo biến tĩnh mặc định là 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
Trang 33static double myvariable;
static void myfunc(int idx);
File two.c:
static int myvariable;
static int myfunc(int idx);
Trang 34Tóm tắt
Hàm có phạm vi ngoài là mặc định
Hàm và biến có 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).