Thông báo

Collapse
No announcement yet.

Hỏi về các lệnh xuất Port

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Hỏi về các lệnh xuất Port

    Mình muốn xuất mức 1 ra Port C ở 4 bit thấp mà không làm ảnh hưởng đến 4 bit cao thì dùng lệnh nào? Mình dùng lệnh OR Port 4 với 0x0Fh nhưng không được.
    Chạy Proteus thì thấy Port C không xuất ra mức Logic nào cả
    ...
    portC || 0x0f;
    ...
    Ngoài ra xin các cao nhân chỉ giúp cái vụ set_tris_x(); có mục đích gì.Mình có nghe nói nó dùng để quy định cổng vào cổng ra nhưng chưa biết sử dụng thế nào.
    Help!!!


    email:
    Giá mà mạch điện tử không có nhiễu (noise) thì mình bây giờ đã là ... đại gia

  • #2
    set_tris_x(0b11111111)//tất cả portx là nhập dữ liệu
    set_tris_x(0b00000000)//tất cả portx là xuất dữ liệu
    portC=portC || 0x0f;//xuất mức 1 ra Port C ở 4 bit thấp mà không làm ảnh hưởng đến 4 bit cao.
    |

    Comment


    • #3
      Mình dùng lệnh này:
      +portC=portC || 0xff;
      thay cho lệnh
      +output_C(0xff);
      Rõ ràng là 2 lệnh này cùng đưa về 1 kết quả là PortC = (0x0f)
      Nhưng đưa lên Proteus thì cái lệnh portC=portC || 0x0f; lại không chạy đúng.Không hiểu là có gì sai ở đây.
      P/S: Đây là ct quét phím bấm 5x5,mình Post lên để các bạn tham khảo.Ct đã chạy được trên Proteus.Giờ mình muốn tối ưu nó để sử dụng các chân còn dư trên 2 Port C và D để dùng cho việc khác.

      void read_key()
      {
      output_C(0xff);
      delay_us(10);
      rotate = 0xfe;
      for(n=1;n<6;++n) //n la gia tri cot
      {
      output_D(rotate);
      delay_us(10);
      col=portC; //doc vao tu PortC
      if(col!=0xff)
      goto have_key1;
      else
      rotate=rotate<<1; //dich trai 1 bit
      }
      key_release=0xff;
      key_value=0;
      goto let_out;
      have_key1:
      if(key_release==0xff)
      {
      for(k=1;k<6;k++) //k la gia tri hang
      {
      if(!bit_test(col,k-1))
      {
      key_valuek-1)*5+(n-1)+1); //gia tri phim bam tu 1-25
      key_release=0x00; //keypressed
      }
      }
      }
      let_out:
      delay_us(5);
      }


      email:
      Giá mà mạch điện tử không có nhiễu (noise) thì mình bây giờ đã là ... đại gia

      Comment


      • #4
        col=portC; //doc vao tu PortC
        theo minh phải viết như sau:
        col=input_C();doc giá trị 8 bit đang hiện hữu tại PortC
        phần quét phím chưa được sử lí chống nảy phím (proteus có thể chạy,nhưng chạy trên mạch thật sẽ khác.)
        bạn đưa toàn bộ ct và file mô phỏng proteus mọi người sẽ cùng nhau giải quyết.
        |

        Comment


        • #5
          Chương trình thì chạy ngon lành trên Proteus,cái nguyên lý quét phím này mình sử dụng như hồi học con AT89 nên chắc không có vấn đề gì.Chương trình này đọc và hiển thị trên Led7s từ 1-25 tương ứng.Có chức năng Key pressed và Key release,tất nhiên là nó chống nảy phím khá tốt(đã test trên phần cứng của dòng 89).
          Các bác thử xem dùm cái SUB read_key,nếu chỉ cần đổi giá trị của dòng output_C(0xff); là thằng Proteus chạy không đúng.

          Theo mình nghĩ là do thằng Proteus còn nhiều Bug về cái vụ mô phỏng này nhưng mà chưa có thời gian để Test trên Board.A e có đ/k thì test rồi hú 1 tiếng



          #include <16F887.H>
          #fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
          #use delay(clock=4000000)
          //#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
          byte CONST MAP[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6 f};
          byte CONST MAP2[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xe f}; //co dau cham
          #use fast_io(a)
          //#use fast_io(b)
          //#use fast_io(c)
          //#use fast_io(d)
          //#use fast_io(e)
          #byte portA=0x05
          #byte portB=0x06
          #byte portC=0x07
          #byte portD=0x08
          #byte portE=0x09

          int analog1;
          int analog2;

          int rotate,n,k,col,key_value,key_release;
          void read_key()
          {
          output_C(0xff);
          delay_us(10);
          rotate = 0xfe;
          for(n=1;n<6;++n) //n la gia tri cot
          {
          output_D(rotate);
          delay_us(10);
          col=portC; //doc vao tu PortC
          if(col!=0xff)
          goto have_key;
          else
          rotate=rotate<<1; //dich trai 1 bit
          }
          key_release=0xff;
          key_value=0;
          goto let_out;
          have_key:
          if(key_release==0xff)
          {
          for(k=1;k<6;k++) //k la gia tri hang
          {
          if(!bit_test(col,k-1))
          {
          key_valuek-1)*5+(n-1)+1); //gia tri phim bam tu 1-25
          key_release=0x00; //keypressed
          }
          }
          }
          let_out:
          delay_us(5);
          }

          void display(int16 n)
          {

          //set_tris_e(0x00);
          char b;
          bMAP[n/1000]) ^ 0xff); //hang ngan
          if ((n/1000)==(0)) b=0xff; //kill Led not Value
          output_b(b);
          output_low(PIN_A7);
          delay_ms(1);
          output_high(PIN_A7);

          bMAP[(n%1000)/100]) ^ 0xff); //hang tram
          if ((n/100)==(0)) b=0xff; //kill Led not Value
          output_b(b);
          output_low(PIN_E2);
          delay_ms(1);
          output_high(PIN_E2);

          bMAP[(n%100)/10]) ^ 0xff); //hang chuc
          if ((n/100)==(0)&&(n/10)==(0))
          b=0xff; //kill Led not Value
          output_b(b);
          output_low(PIN_E1);
          delay_ms(1);
          output_high(PIN_E1);

          output_b((MAP2[n%10]) ^ 0xff); //hang dv
          output_low(PIN_E0);
          delay_ms(1);
          output_high(PIN_E0);
          }


          int16 count;
          int16 count2;

          int dem=0;
          int dem1;
          int dem2;
          int16 tanso;
          int16 tanso2;
          int16 pr2_value;
          int16 pr2_value2;
          #int_timer1
          void ngat_timer1()
          {
          dem++;
          if(dem>10) //Mac dinh la 19 =1s
          {
          tanso = pr2_value ;
          dem1 = analog1; //su dung khi do tan so
          tanso2 = pr2_value2;
          dem2 = analog2; //su dung khi do tan so
          count++;
          count2++;
          count2++;
          dem=0;
          if(count>9999)
          count=0;
          if(count2>9999)
          count2=0;
          }
          //T= 20 x (66536-15535) x 1 x4/4000000 = 1s
          set_timer1(15535); // defaut 15535
          }

          //=======================
          void main()
          {

          setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
          set_timer1(15535);
          enable_interrupts(int_timer1);
          enable_interrupts(GLOBAL);

          while(1)
          {
          read_key();

          display(key_value);

          }
          }


          ///////////////////////////////////////////////////////////
          Attached Files


          email:
          Giá mà mạch điện tử không có nhiễu (noise) thì mình bây giờ đã là ... đại gia

          Comment


          • #6
            các port của pic không như 89xx .muốn port làm xuất hay nhập phải cấu hình thanh ghi
            tris_x.
            code của bạn tôi sửa lại tận dụng RC5..RC7 để d/k T1,T2,T3.
            Code:
            #include <16F887.H>
            #fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
            #use delay(clock=4000000)
            //#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
            byte CONST MAP[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
            byte CONST MAP2[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //co dau cham
            #use fast_io(a)
            //#use fast_io(b)
            //#use fast_io(c)
            //#use fast_io(d)
            //#use fast_io(e)
            #byte portA=0x05
            #byte portB=0x06
            #byte portC=0x07
            #byte portD=0x08
            #byte portE=0x09
            
            int analog1;
            int analog2;
            
            int rotate,n,k,col,key_value,key_release,luu,tang_hang;
            void read_key()
            {
            tang_hang=0;
            delay_us(10);
            rotate = 0xfe;
            for(n=1;n<6;++n) //n la gia tri cot
            {
            output_D(rotate);
            delay_us(10);
            if(!bit_test(PORTC,0))
              {
               luu=0;
             goto have_key;
              }
             else if (!bit_test(PORTC,1))
             {
               luu=1;
             goto have_key;
              }
              else if (!bit_test(PORTC,2))
             {
               luu=2;
             goto have_key;
              }
              else if (!bit_test(PORTC,3))
             {
               luu=3;
             goto have_key;
              }
              else if (!bit_test(PORTC,4))
             {
               luu=4;
             goto have_key;
              }
            else
            rotate=rotate<<1; //dich trai 1 bit
            tang_hang++;
            }
            key_release=0xff;
            key_value=0;
            goto let_out;
            have_key:
            if(key_release==0xff)
            {
            key_value=tang_hang*5+luu+1; //gia tri phim bam tu 1-25 
            key_release=0x00; //keypressed
            
            }
             
            let_out: 
            delay_us(5);
            }
            
            void display(int16 n)
            {
            
            //set_tris_e(0x00);
            char b;
            b=MAP[n/1000] ^ 0xff; //hang ngan
            if ((n/1000)==(0)) b=0xff; //kill Led not Value
            output_b(b);
            output_low(PIN_A7);
            delay_ms(1);
            output_high(PIN_A7); 
            
            b=MAP[n%1000/100] ^ 0xff; //hang tram
            if ((n/100)==(0)) b=0xff; //kill Led not Value
            output_b(b);
            output_low(PIN_C7);
            delay_ms(1);
            output_high(PIN_C7); 
            
            b=MAP[n%100/10] ^ 0xff; //hang chuc
            if ((n/100)==(0)&&(n/10)==(0))
            b=0xff; //kill Led not Value 
            output_b(b);
            output_low(PIN_C6);
            delay_ms(1);
            output_high(PIN_C6);
            
            output_b((MAP2[n%10]) ^ 0xff); //hang dv
            output_low(PIN_C5);
            delay_ms(1);
            output_high(PIN_C5); 
            }
            
            
            int16 count;
            int16 count2;
            
            int dem=0;
            int dem1;
            int dem2;
            int16 tanso;
            int16 tanso2;
            int16 pr2_value; 
            int16 pr2_value2; 
            #int_timer1
            void ngat_timer1()
            {
            dem++;
            if(dem>10) //Mac dinh la 19 =1s
            {
            tanso = pr2_value ;
            dem1 = analog1; //su dung khi do tan so
            tanso2 = pr2_value2; 
            dem2 = analog2; //su dung khi do tan so
            count++;
            count2++;
            count2++;
            dem=0;
            if(count>9999)
            count=0;
            if(count2>9999)
            count2=0;
            }
            //T= 20 x (66536-15535) x 1 x4/4000000 = 1s
            set_timer1(15535); // defaut 15535
            }
            
            //=======================
            void main()
            {
            set_tris_c(0x1f);//TU C0...C4 NHAP DU LIEU
            // 3BIT CAO C5...C7 D/K T1,T2,T3
            set_tris_d(0x00);
            set_tris_b(0x00);
            setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); 
            set_timer1(15535);
            enable_interrupts(int_timer1);
            enable_interrupts(GLOBAL);
            
            while(1)
            { 
            read_key();
            
            display(key_value); 
            
            }
            }
            mô phỏng proteus :từ c1....c5 kéo một r=10k lên nguồn +
            Last edited by tdm; 20-11-2010, 21:49.
            |

            Comment


            • #7
              gửi kèm file:
              Attached Files
              |

              Comment


              • #8
                Chương trình của bạn chạy OK lắm,theo mình phân tích đoạn code và có xem thêm về tập lệnh của CCS thì mới nhận ra là các lệnh liên quan đến xuất/nhập đều không thể tùy biến như 1 giá trị Variable,chẳng hạn như portB thì tương ứng với ô nhớ 0x06,nhưng nếu thay đổi giá trị của ô nhớ 0x06 thì cũng không làm cho PortB thay đổi theo.Điều này làm cho việc lập trình trở nên nhàm chán vì phải viết ct theo kiểu liệt kê rất dài dòng,viết code dài sẽ sinh ra nhiều mã và sẽ chạy chậm.

                Về cái sub read_key của bạn thì mình đã hiểu và tối ưu cho gọn lại như sau:

                int rotate,n,k,key_value,key_release;
                void read_key()
                {
                delay_us(10);
                rotate = 0xfe;
                for(n=0;n<5;++n) //n la gia tri cot
                {
                output_D(rotate);
                delay_us(10);
                for(k=0;k<5;++k) //k la gia tri hang
                if(!bit_test(PORTC,k))
                goto have_key;
                rotate=rotate<<1; //dich trai 1 bit
                }
                key_release=0xff;
                key_value=0;
                goto let_out;
                have_key:
                if(key_release==0xff)
                {
                key_value=(n*5+k+1); //gia tri phim bam tu 1-25
                key_release=0x00; //keypressed
                }
                let_out:
                delay_us(5);
                }


                Hiện giờ mình đang tìm cách sử lý cái portD,vì khi xuất lệnh portD=0feh thì nó sẽ ảnh hưởng đến các chân D5,D6,D7,giả sử 3 chân này nối vào mạch đk on/off 1 cái động cơ thì rất nguy hiểm,mình đang bí vì cái tập lệnh CCSC hơi bị chuối
                Attached Files


                email:
                Giá mà mạch điện tử không có nhiễu (noise) thì mình bây giờ đã là ... đại gia

                Comment


                • #9
                  Đề tài tưởng thiết thực mà ai dè không mấy người quan tâm đến nhỉ,vậy mình tự biên tự diễn vậy.Đây là ct quét phím 5x5 như mình đã đề cập,lần này mình đã cách ly được các chân không sử dụng trên 2 Port C và Port D bằng lệnh set_tris,như vậy là ta tận dụng được 6 chân để dùng cho việc khác:

                  int rotate,n,k,key_value,key_release;
                  void read_key()
                  {
                  delay_us(10);
                  set_tris_D(0xe0);
                  set_tris_C(0xff);
                  rotate = 0xff;
                  for(n=0;n<5;++n) //n la gia tri cot
                  {
                  bit_clear(rotate,n);
                  output_D(rotate);
                  delay_us(10);
                  for(k=0;k<5;++k) //k la gia tri hang
                  if(!bit_test(PORTC,k))
                  goto have_key;
                  }
                  key_release=0xff;
                  key_value=0;
                  goto let_out;
                  have_key:
                  if(key_release==0xff)
                  {
                  key_value=(n*5+k+1); //gia tri phim bam tu 1-25
                  key_release=0x00; //keypressed
                  }
                  let_out:
                  delay_us(5);
                  }
                  CCSC của mình không biết có bị làm sao kô nữa
                  Lệnh portC=portC || 0x0f; không làm thay đổi được giá trị trên port C,có vẻ như nó chỉ làm thay đổi nội dung của ô nhớ 07h mà kô xuất ra ngoài -->đến chán


                  email:
                  Giá mà mạch điện tử không có nhiễu (noise) thì mình bây giờ đã là ... đại gia

                  Comment

                  Về tác giả

                  Collapse

                  otacon Tìm hiểu thêm về otacon

                  Bài viết mới nhất

                  Collapse

                  Đang tải...
                  X