PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Các ngôn ngữ lập trình khác (CCS C, HT PIC,...) (http://www.picvietnam.com/forum/forumdisplay.php?f=12)
-   -   CCS C cho PIC/dsPIC phiên bản 4.xxx (http://www.picvietnam.com/forum/showthread.php?t=2296)

namqn 28-08-2008 10:08 PM

Trích:

Nguyên văn bởi bean984 (Post 18431)
mình đang tìm hiểu con 16f628a. đang làm với 16f877a bg chuyển qua tìm hiểu con này. loay hoay mãi vẫn không điều khiển được chân RA4. mình cũng đã thử kéo con trở 1k lên VDD nhưng cũng k đc. xin hỏi làm sao để set chân RA4 thành chân I/O? con này còn có chân nào đặc biệt không?
cảm ơn mọi người.

Để tránh cho chân RA4 là ngõ ra của bộ so sánh thứ hai, cần đảm bảo 3 bit thấp nhất của thanh ghi CMCON khác với giá trị "110". Vì RA4 là loại ngõ ra cực máng hở, nhất thiết phải có điện trở kéo lên để xuất mức cao ra chân này.

Các chân RA0 .. RA3 sẽ ở trạng thái analog khi vừa reset PIC, cần thay đổi 3 bit thấp nhất của thanh ghi CMCON một cách thích hợp (xem hình 10-1 trong datasheet) để có thể dùng chúng như chân digital.

Thân,

bean984 29-08-2008 10:42 AM

ý e muốn hỏi là nếu dùng ccs thì sẽ phải làm ntn? (e đã đọc datasheet và cũng đã biết phải thiết lập thanh ghi CMCON như vậy)? e k muốn chèn đoạn mã asm vào trong chương trình.
Code:

#int_RB
void ngat_RB()
{
if((RBIF)&&(RBIE))
  {
      ngatRB=1;
      if(!RB4)
        {
              //ngatRB4=1;
          if(tg==0)
            {
              tg=30;
              goto Thoat;
            }
          if(tg==30)
            {
              tg=60;
              porta=6;             
              goto Thoat;
            }
          if(tg==60)
            {
              tg=90;
              porta=9;
              goto Thoat;
            }
          if(tg==90)
            {
              tg=120;
              porta=1;
              goto Thoat;
            }
        }// Xong RB4
      if(!RB5)
        {
              ngatRB5=1;
        }// Endif(RB5)
  thoat:
  RBIF=0; //Xoa co ngat RB
  } // Ket thuc if co ngat
}// Ket thuc ham void*/

a xem giúp e đoạn code trên xem tại sao e phải ấn 2 lần nút bấm tại RB4 thì nó mới chịu thực hiện ngắt? đoạn code đó chạy cho con 16f877a thì ngon lành nhưng khi đưa qua con 628a thì bị như vậy.
thanks!

cong1810 29-08-2008 11:36 AM

em đang thực hành về LCD 4 bit. sử dụng file lcd.c có sẵn trong thư viện của CCS C.nhưng trong file lcd.c các chân enable RS và RW nó sắp ko theo thứ tự để mỉnh cắm bus cho tiện. em muốn hỏi cách mình thay đổi thứ tự chân E,RW,RS trong file LCD.C. em tìm cả buổi rồi mà ko thấy chỗ nó khai báo.các huynh giúp đệ với!!!!

buiminhtu 29-08-2008 07:17 PM

bác nào có CCSC 3.242 cho em xin voi
thanks

namqn 29-08-2008 07:45 PM

Trích:

Nguyên văn bởi buiminhtu (Post 18482)
bác nào có CCSC 3.242 cho em xin voi
thanks

Bạn đọc kỹ post #1 của luồng này:
http://www.picvietnam.com/forum/showthread.php?t=958

Thân,

popeye_ts22 30-08-2008 12:29 AM

Đo tốc độ phản hồi về Lcd
 
1 Attachment(s)
Chào các bác.Có chút vướng mắc,các bác giúp em với.
Mục đích:Điều khiển động cơ phản hồi tốc độ về LCD
Thực hiện:Điều khiển được động cơ nhưng chưa phản hồi đc.
Em không biết sau mỗi lần gọi ngắt có cần phải để 1 vòng while() để đợi ngắt không.
Em dùng 16F877A,bây giờ điều khiển 1 kênh đã phải cần:TIMER2-PWM,TIMER 0:Đếm xung,TIMER1:Đếm thời gian,dùng để tính toán vận tốc.
Vậy nếu em dùng động cơ thứ 2 phải làm thế nào,có thuật toán nào ko ạ.
Có đoạn code và chương trình mô phỏng,các bác xem cho em:
Code:

#include <16f877a.h>
#include <def_877a.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=8000000)
#include <lcd_lib_4bit.c>
int16 cnt,cnt2,xung,v;
int8 a,b,c;
#int_TIMER0
void  TIMER0_isr(void) //TIMER0 dem xung ve
{
set_timer0(255);
if(tmr0if==1)
 {
 cnt++;
 tmr0if=0;
 }
}
#int_TIMER1          //TIMER1 dem tgian,tinh van toc
void  TIMER1_isr(void)
 {
 set_timer1(5565);
 if(tmr1if==1)
  {
    xung=get_timer0()*4; 
    v=(xung*60)/((100*60*0.001));
    tmr1if=0; 
  }
 }
void Lcd()
{
while(1)
  {
  a=(int)v/100;
  b=(int)(v-a*100)/10;
  c=(int)v%10;
  LCD_putcmd(0xC0);
  LCD_putchar("xung encoder");
  LCD_putcmd(0x80);
  LCD_putchar(a+48);
  LCD_putcmd(0x81);
  LCD_putchar(b+48);
    LCD_putcmd(0x82);
    LCD_putchar(c+48);
  } 
}
void Ngat()
{
  set_timer0(255);
  setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_4);
  enable_interrupts(INT_TIMER0);
  setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);
  set_timer1(5565);
  enable_interrupts(INT_TIMER1);
  enable_interrupts(GLOBAL);
  }
void PWM()
{
  setup_timer_2(T2_DIV_BY_16,255,1);
  setup_ccp1(CCP_PWM);
  setup_ccp2(CCP_PWM);
  set_pwm1_duty(1000);
  set_pwm2_duty(1022); 
}
void main()
{
  set_tris_d(0);
  set_tris_a(0xff);    //Cho tin hieu di vao RA4
  set_tris_c(0);
  LCD_Init();
  PWM();
  Ngat();
  Lcd();
  delay_ms(100);
}


popeye_ts22 31-08-2008 12:55 AM

Em đã sửa lại bài chỉn chu rùi,bác nào giúp đỡ em với.Đo vận tốc về nó cứ hiện 215,em thay đổi giá trị biến trở để thay đổi tốc độ mà hiển thị không thay đổi.
**.Em dùng encoder 100 xung/1 vòng

picpen 01-09-2008 12:32 AM

khúc mắc với RA4 ????
 
Mình vẫn theo dõi chuyên mục này đều đặn.Mình đợi mọi người trả lời câu hỏi của bạn Bean984 vì mình cũng đang thắc mắc như bạn, nhưng chưa thấy ai trả lời nên mình xin hỏi lại và nhờ mọi người trên diễn đàn chỉ giúp :
Làm thế nào để sử dụng chân RA4 như 1 chân I/O bình thường trong khi các chân còn lại của portRA vẫn sử dụng chức nằng đầu vào AD ?? trong ccs phải khai báo như nào ? vì nếu sử dụng câu lênh " set_tris_A(??) " để định thực hiện chức năng I/0 cho RA4 thì các chân còn lại của portRA cũng sẽ bị định dạng chức năng I/0 theo ,khi đó ko thể sử dụng làm cổng vào AD được

************ mong mọi người giúp đỡ .. Thanks ********

lion 01-09-2008 01:00 AM

Trích:

Nguyên văn bởi picpen (Post 18533)
Mình vẫn theo dõi chuyên mục này đều đặn.Mình đợi mọi người trả lời câu hỏi của bạn Bean984 vì mình cũng đang thắc mắc như bạn, nhưng chưa thấy ai trả lời nên mình xin hỏi lại và nhờ mọi người trên diễn đàn chỉ giúp :
Làm thế nào để sử dụng chân RA4 như 1 chân I/O bình thường trong khi các chân còn lại của portRA vẫn sử dụng chức nằng đầu vào AD ?? trong ccs phải khai báo như nào ? vì nếu sử dụng câu lênh " set_tris_A(??) " để định thực hiện chức năng I/0 cho RA4 thì các chân còn lại của portRA cũng sẽ bị định dạng chức năng I/0 theo ,khi đó ko thể sử dụng làm cổng vào AD được

************ mong mọi người giúp đỡ .. Thanks ********

bạn thử lam` như thế này xem :


...................
...................
...................

#bit TRISA4 = 0x85.4

..................
..................
..................

void main(void)
{
TRISA4=0 ;
............
............
............




};

cong1810 01-09-2008 07:23 PM

em cũng đang theo dõi câu trả lời cho bài dk động cơ của bạn popeyee mà chưa thấy sư huynh nào trả lời.nên em hỏi vấn đề của em luôn.
em cũng làm 1 bài tập tương tự.nhưng làm mạch thật.em dùng chính tần số PWM để kiểm tra chương trình đếm xung từ động cơ.nhưng khi percent PWM là 100 hay 0% thì LCD luôn hiện số 175 còn khi có xung thì sai lệch rất lớn 40-50%.đây là đoạn code của em.các huynh chỉ giáo!!!
Code:

#include <16f877a.h>
//#include <def_877a.h>
#fuses NOWDT,NOPROTECT,XT,NOLVP
#use delay(clock=4000000)
#define use_portd_lcd True
#define portb=0x06
#define portd=0x08
#include <lcd.c>
#define interr_per_second 20//khi set_timer1(15535)timer 1 16 bit=>65535-15535=50.000us
#define interr_per_100ms 2//khi set_timer1(15535)
int8 timer1over,value,percent;
int16 so_vong,count,tram,chuc,donvi,ngan;
#int_rtcc
void interrupt_timer0()//dem so vong dong co
{
++count;
}
#int_timer1 // ngat timer 1 khi timer 1 tran
void interrupt_timer1()
{
if (--timer1over==0)
{ timer1over=interr_per_second;
so_vong=(count*255+get_timer0());//100; //voi encoder la 100 xung tính trong 1 s
count=0;
set_timer0(15535);
}
}
#int_ext
void ngatngoai() // tang he so duty cho DC
{
if(percent==0)percent=0;
else
{
percent=percent-5;
value = percent*2;
}
}
void tao_ma_so_vong()
{
ngan=so_vong/1000;
tram=(so_vong-ngan*1000)/100;
chuc=(so_vong-ngan*1000-tram*100)/10;
donvi=so_vong%10;
}
void hienthi_lcd()
{
lcd_gotoxy(1,2);
lcd_putc(ngan+0x30);
lcd_putc(tram+0x30);
lcd_putc(chuc+0x30);
lcd_putc(donvi+0x30);

}
//ham main chinh
main()
{
delay_ms(100); //tao thoi gian tre de khoi tao LCD
lcd_init(); // khoi tao LCd
// cac cong I O
set_tris_a(0xff); //cho port a la port thu, su dung chan RA4
set_tris_b(0x01);
output_b(0x01); //tao muc cao cho ngat ngoai
set_tris_c(0);
// enable cac timer
setup_timer_0(rtcc_div_1|rtcc_ext_h_to_l); // timer 0 lam couter
set_timer0(0); // gia tri dau timer 0
setup_timer_1(t1_internal|t1_div_by_1); // dung inter clock,dinh thoi gian 1 s
set_timer1(15535); // gia tri de ngat xay ra 20lan/ 1 s
// configue cac ngat
enable_interrupts(global); //cho phep ngat
enable_interrupts(int_rtcc); // ngat timer 0
enable_interrupts(int_timer1); // ngat timer 1
enable_interrupts(int_ext); // cho ngat ngoai
ext_int_edge(h_to_l); // ngat ngoai canh xuong
// khoi tao che do PWm
setup_timer_2(t2_div_by_1,199,1); // t2div=1=>f=5khz,period=200
// setup_timer_2(t2_div_by_4,199,1); //t2div=4=>f=1250hz,period=200
// setup_timer_2(t2_div_by_16,199,1); //t2div=16=>f=312hz,period=200
setup_ccp1(CCP_PWM); // xung PWm tren chan CCP1 RC2
// khoi tao cac gia tri bien ban dau
count=0;
so_vong=0;
timer1over=interr_per_second;
value=200; // do phan cung dieu xung muc thap
percent=100; //phan cung dung xung muc thap
// tao mau cho lcd
lcd_gotoxy(1,1);
lcd_putc('s');
lcd_putc('o');
lcd_putc('-');
lcd_putc('v');
lcd_putc('o');
lcd_putc('n');
lcd_putc('g');
lcd_putc('-');
lcd_putc('1');
lcd_putc('s');
lcd_putc(':');
//bat dau vong lap
while(1)
{
set_pwm1_duty(value);
tao_ma_so_vong();
hienthi_lcd();

}
}


picpen 01-09-2008 07:31 PM

Thanks Lion !! mình làm như bạn hướng dẫn và mô phỏng proteus rất ổn....

namqn 01-09-2008 07:34 PM

Trích:

Nguyên văn bởi picpen (Post 18533)
Mình vẫn theo dõi chuyên mục này đều đặn.Mình đợi mọi người trả lời câu hỏi của bạn Bean984 vì mình cũng đang thắc mắc như bạn, nhưng chưa thấy ai trả lời nên mình xin hỏi lại và nhờ mọi người trên diễn đàn chỉ giúp :
Làm thế nào để sử dụng chân RA4 như 1 chân I/O bình thường trong khi các chân còn lại của portRA vẫn sử dụng chức nằng đầu vào AD ?? trong ccs phải khai báo như nào ? vì nếu sử dụng câu lênh " set_tris_A(??) " để định thực hiện chức năng I/0 cho RA4 thì các chân còn lại của portRA cũng sẽ bị định dạng chức năng I/0 theo ,khi đó ko thể sử dụng làm cổng vào AD được

************ mong mọi người giúp đỡ .. Thanks ********

Bạn bean984 hỏi về PIC16F628A, còn bạn hỏi về PIC16F877A hay PIC16F628A? Tôi hỏi bạn câu này vì PIC16F628A không hề có module AD, mà chỉ có module so sánh tương tự (analog comparator).

TRISA cho phép thiết lập trạng thái vào/ra cho từng chân riêng biệt, không có chuyện không thể dùng các chân RA khác độc lập với RA4.

Bạn cần phân biệt rõ khái niệm chức năng I/O của chân với chế độ làm việc digital hay analog. Nếu chân làm việc ở chế độ analog, nó là ngõ vào (vì PIC không có chức năng xuất tín hiệu analog, thông qua một module DAC). Nếu chân làm việc ở chế độ digital, nó có thể là ngõ vào hay ngõ ra. Nếu bit tương ứng của TRISA là '1', chân đó là ngõ vào, ngược lại, bit tương ứng của TRISA là '0', chân đó là ngõ ra. Điều này đúng cho cả hai chế độ analog và digital của chân I/O.

Thân,

picpen 01-09-2008 07:48 PM

LCD_Công
 
Công à ! mình chưa làm với encoder bao giờ lên ko thể góp ý với bạn về chương trình được .Nhưng mình thấy chương trình của bạn khá dài do viết mã cho LCD .bạn có thể dùng file LCD.C có sẵn trong thư viện CCS để cho chương trình ngắn gọn hơn, mọi người trên diễn đàn rễ đọc và chỉnh sửa giúp bạn. ví dụ nhé :
đoạn ct con này:
Code:

void hienthi_lcd()
{
lcd_gotoxy(1,2);
lcd_putc(ngan+0x30);
lcd_putc(tram+0x30);
lcd_putc(chuc+0x30);
lcd_putc(donvi+0x30);

}
..............
..............
// tao mau cho lcd
lcd_gotoxy(1,1);
lcd_putc('s');
lcd_putc('o');
lcd_putc('-');
lcd_putc('v');
lcd_putc('o');
lcd_putc('n');
lcd_putc('g');
lcd_putc('-');
lcd_putc('1');
lcd_putc('s');
lcd_putc(':');

bạn chỉ cần dùng 1 lệnh duy nhất để hiển thị:
Printf( lcd_putc,"so_vong_1s:%d",value )

lion 02-09-2008 12:14 AM

Công này đoạn code này gây ra lỗi sai :

//---------------------------------------------------------------
ngan=so_vong/1000;
tram=(so_vong-ngan*1000)/100;
chuc=(so_vong-ngan*1000-tram*100)/10;
donvi=so_vong%10;
//---------------------------------------------------------------

mình cũng đã từng gặp lỗi này , nhưng ko thể nào điều chỉnh được :
nguyên nhân là do trình dịch CCS không sử lý được phép chia > 8 bit :

vi du :

unsigned char so1,so2,so3,so4 ;
//---------------------------------------------------------

void tach_so( unsigned int data )
{
so1 = data / 1000 ;
so2 = (data % 1000)/100 ;
so3 = ((data % 1000)%100)/10 ;
so4 = ((data % 1000)%100)%10 ;
}

//----------------------------------------------------------
void main(void)
{
TRISA=0xff;
TRISB=0xff;
TRISC=0x00;
TRISD=0x00;

while(1)
{

tach_so( 1234 ) // cho kết quả hiển thị sai

hien_thi( so1 );
hien_thi( so2 );
hien_thi( so3 );
hien_thi( so4 );

};
}
//------------------------------------------------

nếu gán cho hàm : tach_so( 1234 ) ( data > 255 ) thì kết quả hiển thị sẽ sai , còn nếu gán cho hàm : tach_so( 223 ) ( data < 255 ) thì kết quả hiển thị đúng .

cong1810 02-09-2008 12:17 AM

cám ơn anh picpen.nhưng làm theo cách của anh thì em thấy có 1 hạn chế.có lẽ do em chưa tìm ra giải pháp.vần đề thế này.nếu dùng theo cách của anh.chương trình gọn gàng nhiểu lắm nhưng khi tốc độ thay đổi thì những số lớn sẽ ko bị mất.
vd thế này lcd hiển thị số 1111. sau đó vận tốc giảm còn 222.tức là chỉ 3 chữ số.nhưng trên lcd số thứ 4 ko bị mất.nên kết quả hiển thị là 2221.
cách làm của em thế này
Code:

lcd_gotoxy(1,1);
      Printf( lcd_putc,"so_vong_1s:%ld",so_vong);

do em khởi tạo vị trí đầu là cố định nên có hiện tương trên!!các anh góp ý khắc phục!!

lion 02-09-2008 12:21 AM

Ko biết có bậc tiền bối nào gặp nỗi này chưa ???
nếu gặp rồi, sửa được nỗi trên xin chi giúp .

cong1810 02-09-2008 12:25 AM

anh lion!!
em dùng cách hiển thị theo anh PICPEN hướng dẫn.nó cũng hiện lên giống như vậy! dùng lệnh printf! vậy để em thử với tần số nhỏ hơn 255 thử xem.do em dùng xung PWM để kiểm tra! hì hì!!

cong1810 02-09-2008 12:55 AM

hix!!vẫn ko đúng.chắc em phải mua cái encoder làm cho đàng hoàng thôi!!thanks các huynh đã để tâm!!

popeye_ts22 02-09-2008 10:32 PM

Mình test mãi và cũng đang nghi ngờ chân tín hiệu của encoder.Bác nào biết giúp em sửa bài đo và phản hồi tốc độ về LCD với.(Bài bên page6)..
Thank's các bác..

picpen 03-09-2008 01:13 AM

LCD_Công
 
trích:
Code:

cám ơn anh picpen.nhưng làm theo cách của anh thì em thấy có 1 hạn chế.có lẽ do em chưa tìm ra giải pháp.vần đề thế này.nếu dùng theo cách của anh.chương trình gọn gàng nhiểu lắm nhưng khi tốc độ thay đổi thì những số lớn sẽ ko bị mất.
vd thế này lcd hiển thị số 1111. sau đó vận tốc giảm còn 222.tức là chỉ 3 chữ số.nhưng trên lcd số thứ 4 ko bị mất.nên kết quả hiển thị là 2221.
cách làm của em thế này
Code:

 lcd_gotoxy(1,1);
      Printf( lcd_putc,"so_vong_1s:%ld",so_vong);

do em khởi tạo vị trí đầu là cố định nên có hiện tương trên!!các anh góp ý khắc phục!!

Bạn có thể khắc phục cách trên bằng cách: định dạng giá trị cần hiển thị là FLOAT, khi đó lệnh:
Printf( lcd_putc,"so_vong_1s:%f",so_vong);
sẽ in lên lcd giá trị của so_vong , khi so_vong thay đổi thì lcd in đúng giá trị,còn những số đằng sau dấu phẩy ' . ' sẽ là 000... ,cách này hiển thị đúng giá trị số vòng nhưng nhìn ko được đẹp mắt nắm
Cách khác: bạn chỉ cần chèn lệnh xóa màn hình trước khi hiển thị giá trị mới vậy là ok

cong1810 03-09-2008 07:27 PM

huynh PICPEN ơi.cách thứ 1 có lẽ đúng nhưng chỉ có thể giải quyết vấn đề nêu ra còn ko dùng được.bởi em có dùng đến lệnh % để lấy số dơn vị để hiển thị nên ko dùng được dạng float. cách thứ 2 cũng ko được luôn.bởi vì em cho cập nhật và hiển thị liên tục lên lcd trong vòng lặp while.có lẽ do chương trình còn ngắn nên thời gian giữa lệnh xóa và hiển thị ko đủ lớn =>lcd ko hiển thị gì hết.hì!!
lúc huynh làm thì huynh dùng cách nào vậy! có vướng phải vấn đề trên ko?

popeye_ts22 05-09-2008 01:41 AM

Mò mẫm mãi cũng ra bài đo tốc độ,đưa xung encoder lên tính vận tốc.Lúc đầu thì encoder hỏng,sau thì tính sai 1 chỗ trong vòng ngắt.hihi.Mới học Pic nên còn gà wá...Em post bài đã làm được lên share cho bác nào cũng mới nghiên cứu PIC như em,gặp phải bài toán này hi vọng các bác sẽ ko bị mất time nữa.
Compiler: CCSC 4.065
PIC:16F877A
Encoder:100xung/vòng
Code:
Code:

#include <16f877a.h>
#include <def_877a.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=8000000)
#include <lcd.c>
float vantoc,soxung;
int8 a,b,c,d,a1;
int16 sovong,i;
#int_TIMER1
void  TIMER1_isr(void)
{
soxung=get_timer0(); //Lay so xung Timer0 dem
set_timer1(55535);    // Trong 1ms
if(tmr1if==1)
 {
  intcon=0;              //stop ngat
  a1=1;
 }
}
void main()
{
  trisa=255;            //Cho RA4 di vao
  trisb=0;
  trisc=0;
  trisd=0;
  lcd_init();
  lcd_gotoxy(1,1);
  lcd_putc("Beginning....");
  delay_ms(1000);
  lcd_putc('\f');
    setup_timer_2(T2_DIV_BY_16,255,1);
    setup_ccp1(CCP_PWM);
  rd7=0;                    //Mo role,quay theo 1 chieu
for(i=0;i<1024;i++)      //0 la quay nhanh,1024 quay cham-->Do mach thiet ke.
  {
  set_pwm1_duty(i);  // Toc do giam dan
  delay_ms(1);
  set_timer0(0);
  set_timer1(55535);
  setup_timer_0(RTCC_EXT_H_TO_L|RTCC_DIV_1);  //Che do counter
  setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);       
  enable_interrupts(INT_TIMER1);
  enable_interrupts(GLOBAL);
  delay_ms(50);
if(a1==1) 
{
//while (1)
 //{
vantoc=((float)(60*soxung)/(0.01*100));  //Tinh van toc
a=vantoc/1000;                                    //Tach so..
b=(int)(vantoc-1000*a)/100;
c=(int)(vantoc-1000*a-100*b)/10;
d=(int)vantoc%10;
lcd_gotoxy(1,1);                      //Hien thi
lcd_putc(a+48);
lcd_gotoxy(2,1);
lcd_putc(b+48);
lcd_gotoxy(3,1);
lcd_putc(c+48);
lcd_gotoxy(4,1);
lcd_putc(d+48);
lcd_gotoxy(6,1);
lcd_putc("vong/ph");
lcd_gotoxy(3,2);
lcd_putc("toc do dc");
delay_ms(5);            //Vong for0->1024 nen delay it.
tmr0if=0;tmr1if=0;    //Xoa tran
}
  }
}

Chúc các bác thành công.

picpen 15-09-2008 03:04 PM

Khẩn cấp
 
1 Attachment(s)
Mọi người cho hỏi ,khi khai báo cấu hình cho pic thì lệnh này có ý nghĩa gì và hoạt động ra sao????

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

khi khai báo lệnh :" xmit=PIN_C6, rcv=PIN_C7 " thì 2 chân RC6,7 luôn ở mức cao ,ko thể sử dụng làm cổng ra được
khi mà xóa lệnh khai báo đó đi thì lại ảnh hưởng tới cổng chuyển đổi ADC .cụ thể như sau : khi mình bỏ lệnh đó đi thì mình thay đổi biến trở ở cổng vào tương tự An0 thấy điện áp tăng ko tuyến tính như khi có lệnh " xmit=PIN_C6, rcv=PIN_C7 " được khai báo .khi mới tăng biến trở từ mức 0% lên 1 it thì điện áp vào An0 đã nhảy tớ >1v ,rồi tăng vọt lên khoảng 4V ,khi này mình tăng biến trở lên thì gần như điện áp ko tăng lên được nữa .

Nói tóm lại là cổng ADC hoạt động ko còn đúng nữa
Rất mong mọi người giải thích cho .trong khi mình cần sử dụng cổng ADC và 2 chân Rc6,7 làm cổng ra

********* Cám ơn mọi người ,mình cần khắc phục vấn đề này gấp ( vì ko còn thời gian ,mình sắp phải bảo vệ rồi ) .......Thanks

cong1810 16-09-2008 03:39 PM

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) câu lệnh này là khai báo sử dụng cổng nối tiếp RS232,chân C6 là chân truyền data,C7 là nhận.tốc độc truyền là 9600 bauld.em thấy nó ko có liên quan gì đến ADC hết.chắc do chương trình mô phỏng rồi!!

quocloc.pham 16-09-2008 04:28 PM

CCSC 3.249 không hỗ trợ pic18xxx??
 
Mình viết code cho 18F452 nhưng không compiler được, nó báo lỗi "Unknown device type -- Try PCH", sau đó mình thử viết cho 18F2450,18f4550 đều bị lỗi như thế!
bạn nào biết vui lòng giúp với
mình sử dụng ccsc 3.249

picpen 17-09-2008 12:55 PM

Trich:
Code:

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) câu lệnh này là khai báo sử dụng cổng nối tiếp RS232,chân C6 là chân truyền data,C7 là nhận.tốc độc truyền là 9600 bauld.em thấy nó ko có liên quan gì đến ADC hết.chắc do chương trình mô phỏng rồi!!
Đọc kỹ lại tài liệu thì đúng là 2 vấn đề này chẳng liên quan gì đến nhau ,và chạy mạch thực tế thì cũng ok , vậy mà khi mô phổng bằng Proteus thì lại trục trặc.... cái thằng Proteus này nắm lúc nó giở trứng kỳ quặc quá ,sau khi cài lại proteus chạy thì lại ok ,nó làm mình hú vía giờ thì ổn rùi

leejongfan 23-09-2008 11:16 AM

Cho em hỏi: có cách nào convert tu CCS sang Mikro C ko ah?

cong1810 02-10-2008 10:23 PM

em khai báo chế độ power pwm cho pic18f4431.hoạt động ở chế độ independent.vậy mà khi set_power_pwm3_duty();cho các chân thì CCS C báo là undefined identify cho các chân 1,3,5. còn các chân 0,2,4 thì ok.vậy em phải khai báo thêm cho nó ở chỗ nào.
các anh giúp với ạ!!

cong1810 02-10-2008 10:38 PM

hình như không có cách nào làm theo yêu cầu em muốn được.bởi trong data sheet thì chỉ có 1 thanh ghi duty cycle cho 2 chân 0 và 1 .tức là 2 chân này sẽ xuất xung giống nhau ở chế độ independent!! các huynh check lại dùm đệ xem đúng vậy ko!!?

cong1810 02-10-2008 10:53 PM

các anh ui!! ai có file def_18f4431 .cho em xin với nhé.nếu chưa có thì chắc em phải mần hết 1 ngày quá!! thanks các huynh!!

bean984 16-10-2008 03:24 PM

giúp mình với!!!!
ai rành về counter xin chi mình cách thiết lập timer ở chế độ đếm?nếu có code thì tốt quá!!!
có phải cứ có 1 xung đếm thì timer sẽ ngắt 1 lần?
mình thử viết như thế này nhưng k thấy nó chạy j cả.
Code:

#include "16F877A.h" // PIC16F877A header file
#device 16F877A*=16 ADC=10
#include <defs_16F877A.h>
#fuses HS, NOWDT, PUT, NOPROTECT, NOLVP // for debug mode
#use delay(clock=8000000) // for 4Mhz crystal
#use fast_io(b)

int16 count0;
int8  b0;
///////////////////////////////////////////////////////////
#INT_TIMER0
TIMER0_ISR()
{
  ++count0;
  if (count0==100)
      {
        count0=0;
        b0=b0+1;// dich trai a 1bit
        //portd=170;
      }
  if (b0==2)
      {
        b0=0;
        count0=0;
        //HTGT0=1;
        portb=0;
        //portd=252;
        disable_interrupts(int_timer0);
      }
}
/////////////////////////////////////////////////////////////////////
void main(void)
{
  set_tris_a(255); // Chi co dau vao tuong tu
  set_tris_b(0);
  set_tris_d(0);
  portb=255;
  //portd=255;
  count0=b0=0;
  enable_interrupts(global);
  enable_interrupts(int_timer0);
  setup_TIMER_0(RTCC_EXT_L_TO_H );
  setup_COUNTERS(RTCC_EXT_L_TO_H,RTCC_DIV_2);
  set_TIMER0(1);
  while(true)
  {
     
  }
}

chương trình của mình định thử là nếu đếm đc 200 xung thì tắt hết led ở portB.nhưng khi thử k thấy có hiện tượng j cả.

cong1810 17-10-2008 12:50 AM

Trích:

Nguyên văn bởi bean984 (Post 19630)

Code:



  if (b0==2)
      {
        b0=0;
        count0=0;
        //HTGT0=1;
        portb=0;
        //portd=252;
        disable_interrupts(int_timer0);
      }
}


có lẽ là do đoạn code trên bạn ạ. bạn nhầm tại câu lệnh "disable_interrupts(int_timer0);" có phải bạn muốn xóa cờ ngắt cho lần tiếp theo nhưng câu lệnh trên là xóa bit enable cho ngắt timer0. bạn đọc kĩ lại help CCS C và datasheet của 877a nhé. xem mình có đúng ý bạn ko!! good luck!!

bá vinh 29-10-2008 06:47 PM

chào các bác
các bác cho em hỏi la:khi viết bàng CSS ma mình sài chức năng UART voi máy tinh. ma khi khai báo ngắt của no thi không bao giờ dược cả ,vi khi dó nó sẽ báo là ngắt toàn cục bị cấm trong khi chương trình chính đang thực hiện :
vd:
puts i

ma trong khai báo ngắt
#int_tbe()
{
led=!led;
}

thi không bao giờ led nay chớp tăt nghĩa la nó không bao giờ nhảy vao ngát la so vây.
mình thi sử dụng được hết các chức năng khác nhưng chỉ con ngắt của Uart la không sai dược, bực mình quá.
nhưng mình viết bằng hợp ngữ thi ok.
mong cac bác chỉ giáo .

dientudong 06-11-2008 07:17 PM

các bạn cho mình hỏi về đoạn code này :khai báo hàm if(tmr1if==1) sao ki vay tmr1if là gì vậy.Với intcon là gì vậy ? Cảm ơn các bạn .Mình còn yếu.
//////////////////////////////////khai bao va chuong trinh ngat cho TIMER1
#int_TIMER1
void TIMER1_isr(void)
{
soxung=get_timer0(); //Lay so xung ma Timer0 dem
set_timer1(55535); // Trong 1ms
if(tmr1if==1)
{
intcon=0; //stop ngat
a1=1;
}
}

cong1810 06-11-2008 10:34 PM

có lẽ đó là 1 biến hay đó là bit cờ ngắt của timer 1!! người sử dụng đặt trong file define!!bạn xem trong 2 file mà họ include trong code mẫu!!! có thể từ "if" làm bạn nghĩ là lệnh IF ! thực ra nó là interrupt flag!!
chúc may mắn!

delpiero10 08-11-2008 03:14 PM

Mới học lập trình ccs ai cho e hỏi file defs_16f877A.h và file def_16f877A.h khác nhau thế nào? Ai có file defs_16F877A up lên cho e được kô. Thanks!

bá vinh 09-11-2008 05:47 PM

bác F ơi cho em xin phần mềm css cho dsp đi ,em tìm hoài mà không thấy . con thằng mikroe thì không biết làm sao ma nạp nó không chạy ,chắc là nó có nhiều fuse quá em không biết chon cái nào cả ,bác có thể giúp em được không.
sẵn cho em hỏi luôn là sử dụng chức năng usb của pic18f4550 như thế nào và máy tính khai báo ra sao khi em dùng VB để giao tiếp vời pic.

luongnhut 09-11-2008 07:48 PM

hỏi về dinh thời gian trong ngắt dung timer
 
em sử dụng thạch anh 20MHZ cho 16f877a, em viet chuong trình ngắt timer0 1s, nhưng em kiểm tra thấy nó nhanh hon 1s rất nhiều, bác nào chỉ em cho sai chổ nao với. chương trinh của e như sau:


#include <16f877a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#byte PORTB = 0x06

int16 count;
int8 a;
//Chuong trinh ngat TMR0
#int_timer0
void interrupt_timer0()
{
set_timer0(251);
++count;
if(count == 1000000) // 1000000*1us = 1000000us = 1s
{
count=0;
rotate_left(&a,1);
}
}
//Chuong trinh chinh
void main(void)
{
set_tris_b(0);
enable_interrupts(int_timer0);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
enable_interrupts(global);

a = 0x01;

while(true)
{
PORTB = a;
}
}

cong1810 09-11-2008 09:22 PM

do bạn set prescale cho timer là 2 nên timer tăng lên sau mỗi 0.4us tức là 0.4*5=2us thì timer ngắt 1 lần chứ ko phải là 1us. bạn nên tham khảo thêm trong phần Help củ PIC C!!
vấn đề thứ 2 là biến count của bạn là biến int 16 bit tức giá trị tối đa chỉ là 2^16=65536!! thì điều kiện If của bạn liệu có đúng ko??
thân!!

picpen 10-11-2008 12:23 AM

trích :
Code:

vấn đề thứ 2 là biến count của bạn là biến int 16 bit tức giá trị tối đa chỉ là 2^16=65536!! thì điều kiện If của bạn liệu có đúng ko??
Thực ra giá trị dương của biến " INT16 " nằm trong khoảng từ : 0 >> 2^15 = 32768
Mọi người chú ý đến phạm vi hoạt động của biến được khai báo nếu không sẽ bị tràn làm sai kết quả


Múi giờ GMT. Hiện tại là 02:59 AM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam