PDA

View Full Version : Ngắt porB trong pic6f877


daothienbao
14-05-2008, 06:48 PM
Em đã đăng 1 số bài trên diễn đàn để hỏi anh em về bài tập lớn của em, hôm nay em lại mắc và mong anh em giúp đỡ
Yêu cầu với bài tập của em là dùng PIC6f877 để đo và hiển thị tốc độ động cơ. Em đang làm phân chuyển chế độ. EM muốn mạch chạy của minh gồm 3 phần
1.Đo và hiển thị tốc độ động cơ
2.Nhập giá trị thay đổi vào ( ở đây là tăng giảm tốc độ)
3.PWM
Em muốn dùng 1 button để chuyển chế độ làm việc cho PIC, chân em chọn là RB4. 2 chân RB5, RB6 em dùng để tăng giảm giá trị. Có thể tóm tắt như sau:
Khi chay, đầu tiên chưa hiển thị gì cả, nếu ấn nút RB4 thì hiển thị động cơ, ấn lần nữa thì chuyển sang chế độ chờ nhập giá trị tăng giảm, ấn thêm nút nữa thì PWM đồng thời hiển thị luôn.
Vì chưa tìm hiểu được về con encoder nên em tạm thời dùng IC555 để tạo xung.
Tạm thời chưa xử lý phần PWM, em mới làm phần chuyển mạch thôi, Code của em dưới đây:

#include "D:\pro2\vd\lcd1.h"
#include "def_877a.h"
#include<lcd_lib_4bit.c>
#use delay(clock=20000000)
int8 nghin,tram,chuc,donvi,a;
int16 count,so_vong,int_count1,x;
void tinhtoan_hienthi(int16 x);
void kiemtra2(){
if( portb = 0b11011111 )
{
so_vong = so_vong + 10;}
else {
if (portd = 0b10111111)
{so_vong = so_vong - 10;}}}


void kiemtra1()
{if(a = 1 ) tinhtoan_hienthi(so_vong); //a=1 thi do va hien thi toc do dong co
else {
if(a = 2 ) // nhap gia tri thay doi
{
printf(lcd_putchar,"moi nhap gia tri");
kiemtra2();
lcd_putcmd(0xc0);
printf(lcd_putchar,"toc do=");
lcd_putchar(nghin);
lcd_putchar(tram);
lcd_putchar(chuc);
lcd_putchar(donvi);
}else {// a khong =2 thi a=3 chay PWM xong lai set a=0
printf(lcd_putchar,"PWM");
tinhtoan_hienthi(so_vong);
a=0;}}
}


#define INTS_PER_SECOND1 19
#int_rtcc // Ngat Timer 0
void Timer0_isr() // Dem so vong quay dong co
{
count++;
}

#INT_TIMER1 // Chuong trinh ngat Timer 1
void Timer11_isr() { // Ham duoc goi khi TImer1 tran (65535->0)
// Xap xi 19 lan / giay
if(--int_count1==0)
{
int_count1 = INTS_PER_SECOND1;
so_vong = (count*255 + get_timer0())/100;
count = 0;
set_timer0(0);
}
}
#int_RB // ham kiem tra dau vao
void RB_isr()
{
if(portb = 0b11101111) //an nut chuyen trang thai
{a++;
lcd_putcmd(0x01);
kiemtra1();
}
else {kiemtra2();}
portb = 0xff;//reset lai port B
}
void tinhtoan_hienthi(int16 x) // thuc hien tach so va dua ra hien thi luon
{nghin = x / 1000 + 0x30;
x = x % 1000;
tram = x / 100 + 0x30; // tách s? hàng tram
x = x % 100; // chia l?y ph?n d?
chuc = x / 10 + 0x30; // tách l?y ph?n ch?c
donvi = x % 10 + 0x30; // ph?n don v?
printf(lcd_putchar,"hien thi toc do");
lcd_putcmd(0xC0);
printf(lcd_putchar,"toc do=");
lcd_putchar(nghin);
lcd_putchar(tram);
lcd_putchar(chuc);
lcd_putchar(donvi);
}

void main()
{
setup_timer_0 (RTCC_DIV_1|RTCC_EXT_H_TO_L); // Timer0 is Counter
set_timer0(0);
set_timer1(0);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);
enable_interrupts(INT_RTCC);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
count = 0;
int_count1 = INTS_PER_SECOND1;
so_vong = 0;
a = 0;
TRISA = 0xFF;
trisB = 0xFF;
portb = 0xff;
RD2 = 1;
trisD = 0;
lcd_init();
delay_ms(200);
printf(lcd_putchar,"Liencoi");


while(1) // doan chuong trinh hien thi len LCD
{enable_interrupts(INT_RB);
//tinhtoan_hienthi(so_vong);
delay_ms(500);}
}



EM thấy khi chạy mắc 1 số vấn đề sau:
1.Sau lần đầu tiên ấn BR4(a=1) thì màn hình có clear, nhưng từ những lần sau thì không
Do đó em cũng không kiểm tra được những phần sau đúng hay chưa
2.Ấn lần thứ nhất thì tocdo=0000, phải ấn đến lần thử 2 thì mới hiển thị tốc độ
3.Ngoài ra vì em chưa xử lý được phần lear màn hình sau mỗi lần chuyển chế độ nên không kiểm tra được phần ngăt porB như trên đúng hay sai.
Mong anh em giúp đỡ.
Dưới đây là mạch

nguyencuongdhdt
14-03-2011, 01:00 AM
ai gip e lam den giao thong voi