Thông báo

Collapse
No announcement yet.

Phát FSK chuẩn V23 bằng PIC 18F452 +DAC 12bit

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

  • #16
    Đây là 1 hình minh họa tín hiệu FSK. các tìn hiệu tần số 1200Hz và 2200Hz được nối với nhau rất trơn. các ô vuông là các điểm lấy mẫu.
    Giải thưởng thêm 1 LCD128x64 như ảnh trên diễn đàn.
    Nhà sản xuất chuyên nghiệp các sản phẩm OEM cho gia dụng và công nghiệp.

    Biến tần
    Máy giặt
    Lò vi sóng
    Bếp từ.
    Tủ lạnh.
    Điều hòa

    Comment


    • #17
      Dùng một mảng hình sin đầy đủ với tần số lấy mẫu bằng bội của 2 hình sin.
      Hihi.. em giờ phải đi học.. tối nay em sẽ lấy toàn bộ tài LCD trên của anh..hihi..

      Comment


      • #18
        Hihi, chẳng nhẽ lại giành giật giải thưởng với 3T. Đợi đến tối vậy.
        Vẫn biết mỗi lần xa là một lần về lại...

        Comment


        • #19
          Hihi.. đáp án.

          Hình sin 1200 khz, có dạng: sin x =sin(54*i+pt)
          Hình sin 2200 khz, có dạng: sin x = sin(99*i+pt)
          Với tốc độ lấy mẫu 8Khz, Pt là phase của hình sin trước.
          (Tính theo độ với đk: if(x>=360) x=x-360; với i=0…N)
          Để đơn giản, nên tất cả các biểu thức trên dùng bảng tra thay thế việc tính hàm sin.

          //Để giảm khối lượng tính toán, gọi Pt là phase

          Dùng ngắt timer T1 (8khz) cho việc Out DAC.
          {
          Pt=Pt+k;
          If(Pt>=360) Pt=Pt-360;
          Out=sin(Pt);//Nên dùng Bảng tra
          }

          Dùng ngắt timer T2 (1200khz) cho sự thay đổi bit
          {
          đọc giá trị T1 là z: (0<z<125 uS)
          Pt=Pt+k*z/125;//Tính phase hiện tại; Cũng nên Out DAC tại đây Out=sin(Pt);
          if (bit1) k=54;else k=99;
          Pt=Pt+k*(1-z/125)-k=Pt-k*z/125;//Tính cho phase gốc cho lần sau ;
          }
          //Thêm một số lệnh để bài toán chặt hơn, bố cục lại thứ tự lệnh.
          //Theo em, tần số Out DAC chỉ 8Khz,do vậy ko nên dùng DAC 12 bit, chỉ dùng 8 bit là phù hợp nhất.

          Comment


          • #20
            Nếu cách này đúng, thì cách trên của em cũng đúng, thậm chí đơn giản hơn, nhất là khi thêm một số lệnh tại ngắt T2 để thêm trơn vị trị chuyển bit này.

            Comment


            • #21
              Nguyên văn bởi thaithutrang
              Hihi.. đáp án.

              Hình sin 1200 khz, có dạng: sin x =sin(54*i+pt)
              Hình sin 2200 khz, có dạng: sin x = sin(99*i+pt)
              Với tốc độ lấy mẫu 8Khz, Pt là phase của hình sin trước.
              (Tính theo độ với đk: if(x>=360) x=x-360; với i=0…N)
              Để đơn giản, nên tất cả các biểu thức trên dùng bảng tra thay thế việc tính hàm sin.

              //Để giảm khối lượng tính toán, gọi Pt là phase

              Dùng ngắt timer T1 (8khz) cho việc Out DAC.
              {
              Pt=Pt+k;
              If(Pt>=360) Pt=Pt-360;
              Out=sin(Pt);//Nên dùng Bảng tra
              }

              Dùng ngắt timer T2 (1200khz) cho sự thay đổi bit
              {
              đọc giá trị T1 là z: (0<z<125 uS)
              Pt=Pt+k*z/125;//Tính phase hiện tại; Cũng nên Out DAC tại đây Out=sin(Pt);
              if (bit1) k=54;else k=99;
              Pt=Pt+k*(1-z/125)-k=Pt-k*z/125;//Tính cho phase gốc cho lần sau ;
              }
              //Thêm một số lệnh để bài toán chặt hơn, bố cục lại thứ tự lệnh.
              //Theo em, tần số Out DAC chỉ 8Khz,do vậy ko nên dùng DAC 12 bit, chỉ dùng 8 bit là phù hợp nhất.
              Hihi rất xứng đáng được thưởng LCD nhưng còn chưa chuẩn một số chỗ.
              Vẫn biết mỗi lần xa là một lần về lại...

              Comment


              • #22
                Nguyên văn bởi thaithutrang
                Hihi.. đáp án.

                Hình sin 1200 khz, có dạng: sin x =sin(54*i+pt)
                Hình sin 2200 khz, có dạng: sin x = sin(99*i+pt)
                Với tốc độ lấy mẫu 8Khz, Pt là phase của hình sin trước.
                (Tính theo độ với đk: if(x>=360) x=x-360; với i=0…N)
                Để đơn giản, nên tất cả các biểu thức trên dùng bảng tra thay thế việc tính hàm sin.

                //Để giảm khối lượng tính toán, gọi Pt là phase

                Dùng ngắt timer T1 (8khz) cho việc Out DAC.
                {
                Pt=Pt+k;
                If(Pt>=360) Pt=Pt-360;
                Out=sin(Pt);//Nên dùng Bảng tra
                }

                Dùng ngắt timer T2 (1200khz) cho sự thay đổi bit
                {
                đọc giá trị T1 là z: (0<z<125 uS)
                Pt=Pt+k*z/125;//Tính phase hiện tại; Cũng nên Out DAC tại đây Out=sin(Pt);
                if (bit1) k=54;else k=99;
                Pt=Pt+k*(1-z/125)-k=Pt-k*z/125;//Tính cho phase gốc cho lần sau ;
                }
                //Thêm một số lệnh để bài toán chặt hơn, bố cục lại thứ tự lệnh.
                //Theo em, tần số Out DAC chỉ 8Khz,do vậy ko nên dùng DAC 12 bit, chỉ dùng 8 bit là phù hợp nhất.
                Ý tưởng hay xứng đáng nhận giải.
                Lời giải chi tiết hơn:

                Thứ nhất theo chuẩn V23 thì các thông số sau:
                Fmark(1) = 2300 Hz +-10Hz
                Fspace(0) = 1300 Hz +-10Hz
                Baudrate = 1200 Baud
                Tần số lấy mẫu Fs = 8000Hz (Thỏa Shanon)
                (Bác Hà hình như nhầm chỗ này ???)

                Giải quyết bài toán như sau:
                Chọn thạch anh 24MHz tần số giao động thực sẽ là 6MHz
                Chu kỳ giao động Tclk = 1,666E-7
                - Ngắt DAC có chu kỳ 1/8K = 125uS = 750.Tclk
                - Ngắt Baud có chu kỳ 1/1200Hz = 5000.Tclk
                Để ý rằng nếu ngắt Baud đồng bộ với DAC ở chu kỳ đầu tiên thì:
                - Ở lần ngắt Baud tiếp theo lúc đấy DAC 500/750
                - Ở lần ngắt Baud tiếp theo lúc đấy DAC 250/750
                - Sau ba chu kỳ Baud đồng bộ lại bình thường.
                Có thể tận dụng điều này để tính kỹ pha cho 'mượt' hơn.

                Đầu tiên tôi tính theo rad nhưng sau thấy dùng 'độ' như của Trang dễ hiểu hơn.
                Chuyển sang dùng độ. Bài toán giải như các của 3T.
                Thiết lập bảng tra sin. SIN[n] [n = 0 - 359 (độ)]
                Chú ý vì đề bài dùng DAC 12bit nên làm như sau.
                Giả sửa max là 5V.
                Ứng với mỗi n [n = 0 - 359 độ] giá trị bảng tra sẽ là:
                2^11.{sin(n) + 1}
                Có thể dùng Excell để lập bảng.
                Có thể tối ưu kích thước bảng tra hơn ???

                Ta có theo định lý lấy mẫu.
                x(t) = sin(w.t)=sin(2.pi.(F/Fs).n)
                Rồi 2.pi tương đương với 360 độ.
                Với Fmark(1) = 2300 Hz -> sin(360.(2300/8000).n) = sin(104.n) (sai số 11Hz)
                Với Fspace(0) = 1300 Hz -> sin(360.(1300/8000).n) = sin(59.n) (sai số 11Hz)
                (Thực ra tính kiểu này là sai số vượt chuẩn nếu dùng rad có thể tăng độ chính xác lên.
                Nhưng thôi giải kiểu 3T cho dễ hiểu quan trọng là ý tưởng)

                Giải như em Trang:

                Ngắt DAC
                {
                DACValue=SIN[P];
                P=P+k;
                If (P>=360) P=P-360; ; Tính Pha kế tiếp
                }
                Ngắt Baud
                {
                if (i++==3) i=0;
                switch (i)
                { case 1: P = P - k*(1/3)
                break;
                case 2: P = P - k*(2/3)
                break;
                }
                Lấy bit kế tiếp.
                if (bit = 1) {k = 104;}
                else k = 59;
                switch (i)
                { case 1: P = P + k*(1/3)
                break;
                case 2: P = P + k*(2/3)
                break;
                }
                }
                Ngắt cổng Com
                {
                Đưa giá trị vào bộ đệm.
                }
                Em 3T có hơi vội một tẹo ở phần này.
                Thứ nhất nếu xung nhịp IC mà kô phải 1us đọc về thế là sai.
                Thứ 2 vì DAC nếu dùng ngắt ngoài khó sử dụng kiểu này. Nếu DAC tốc độ max 8KHz thì Out cũng chẳng ăn thua nếu DAC chưa Ready.
                Thứ 3 cái đoạn tính pha mới của 3T đến khi có ngắt DAC nó lại cộng thêm 1 k nữa dẫn đến sai pha. Cái này là sai nhất.
                Last edited by qmk; 22-02-2006, 09:48. Lý do: Sửa một chút chỗ 1/3 - 2/3
                Vẫn biết mỗi lần xa là một lần về lại...

                Comment


                • #23
                  Hình như anh qmk có post bài nhưng ko thấy hiển thị thì phải?

                  Comment


                  • #24
                    -Việc chọn tần số 1200 hay ... ko quan trọng, doanh MH đưa ra tần số đó nên em giải theo thôi.

                    Hihi.. anh qmk quá nhiều sự ko hợp lý trong lời giải:
                    1-Không nên chọn tốc độ là 24Mhz cả. Vì lượng xử lý ko ít. Theo em chọn 10Mhz và PLL*4, có tốc độ là 40mhz (max), chu kỳ lệnh max là 10mhz. 10Mhz và dùng timer16 bit đủ để trong giải số cho phép. Hơn nữa, ngoài việc trên,uC còn rất nhiều việc phải làm khác.

                    2-DAC thường có tốc độ Out ra rất cao, nó khác với ADC, nên anh qmk nói đến điểm tốc ở trên không chính xác lắm thì phải. Theo nguyên lý DAC mà anh có thể suy ra tốc độ thôi. Bởi vậy chuyện anh bắt bí ở đây ko hợp lý? và thực tế điều này còn phải xem kỹ càng, bởi ko ai lúc làm thực tế lại quên mất chuyện tốc độ DAC được.
                    3-Bảng n[0..359] tức là 360 giá trị thôi thì không đúng được rồi. Bởi bỏ qua sự tăng không đều của hình sin, thì 360 chỉ hợp với khoảng 8 bit Bởi vậy vô tình anh bỏ mất điều kiện DAC12 bit. Bởi vậy bảng tra ở đây phải chia nhiều phần tử hơn. Đê hợp với DAC12 bit thì cũng phải 2 mũ 12 giá trị.Thực tế có thể giảm cho phù hợp bộ nhớ.
                    4-Đoạn tính phase mới của em ko sai đâu, lúc tính phase mới kế tiếp(cho lần sau Out ra DAC), phải tính đúng tại thời điểm chuyển bit, sau đó suy ra giá trị cho pha mới kế tiếp dựa vào các dữ kiện:
                    +Phase tại thời điểm chuyển bit
                    +Thời gian từ thời điểm Out DAC lần trước gần nhất đến thời điểm chuyển bit, tạm gọi nó là z (0<z<125uS) ,và sau đó biết được thờigian từ thời điểm chuyển bit đến Out_DAC lần sau: 125-z.

                    Comment


                    • #25
                      Anh qmk xem lại cách tính theo i của anh đoạn chuyển tốc độ bit, có vẻ anh sai rồi đó.

                      Comment


                      • #26
                        -Việc chọn tần số 1200 hay ... ko quan trọng, doanh MH đưa ra tần số đó nên em giải theo thôi.

                        Hihi.. anh qmk quá nhiều sự ko hợp lý trong lời giải:
                        1-Không nên chọn tốc độ là 24Mhz cả. Vì lượng xử lý ko ít. Theo em chọn 10Mhz và PLL*4, có tốc độ là 40mhz (max), chu kỳ lệnh max là 10mhz. 10Mhz và dùng timer16 bit đủ để trong giải số cho phép. Hơn nữa, ngoài việc trên,uC còn rất nhiều việc phải làm khác.

                        2-DAC thường có tốc độ Out ra rất cao, nó khác với ADC, nên anh qmk nói đến điểm tốc ở trên không chính xác lắm thì phải. Theo nguyên lý DAC mà anh có thể suy ra tốc độ thôi. Bởi vậy chuyện anh bắt bí ở đây ko hợp lý? và thực tế điều này còn phải xem kỹ càng, bởi ko ai lúc làm thực tế lại quên mất chuyện tốc độ DAC được.

                        3-Bảng n[0..359] tức là 360 giá trị thôi thì không đúng được rồi. Bởi bỏ qua sự tăng không đều của hình sin, thì 360 chỉ hợp với khoảng 8 bit Bởi vậy vô tình anh bỏ mất điều kiện DAC12 bit. Bởi vậy bảng tra ở đây phải chia nhiều phần tử hơn. Đê hợp với DAC12 bit thì cũng phải 2 mũ 12 giá trị.Thực tế có thể giảm cho phù hợp bộ nhớ.
                        4-Đoạn tính phase mới của em ko sai đâu, lúc tính phase mới kế tiếp(cho lần sau Out ra DAC), phải tính đúng tại thời điểm chuyển bit, sau đó suy ra giá trị cho pha mới kế tiếp dựa vào các dữ kiện:
                        +Phase tại thời điểm chuyển bit
                        +Thời gian từ thời điểm Out DAC lần trước gần nhất đến thời điểm chuyển bit, tạm gọi nó là z (0<z<125uS) ,và sau đó biết được thờigian từ thời điểm chuyển bit đến Out_DAC lần sau: 125-z.
                        1. Chọn tần số quan trọng chứ vì nếu lệch quá thì nó thành chuẩn V3T hoặc VMH rồi đâu còn là V23 nữa. Thứ nữa tần số lẻ mới khó giải quyết.

                        2. Tùy người thôi chọn 24 MHz nó sẽ ra giá trị chẵn hơn với 1200.
                        Nhưng mà với tần số 40Mhz thì phase em sai ngay.

                        3. 12 bit là biên độ. i của em là phase nhé. Nếu mà bảng có 4096 phần tử thì chương trình của em kô còn đúng nữa.

                        4. OK cách tính phase của em đúng. Xin lỗi vì nhận xét chưa đúng

                        5. Hình như cái đoạn bù pha anh với em đều quên khả năng kết quả bị âm.
                        Last edited by qmk; 22-02-2006, 10:21.
                        Vẫn biết mỗi lần xa là một lần về lại...

                        Comment


                        • #27
                          Nguyên văn bởi qmk
                          1. Chọn tần số quan trọng chứ vì nếu lệch quá thì nó thành chuẩn V3T hoặc VMH rồi đâu còn là V23 nữa. Thứ nữa tần số lẻ mới khó giải quyết.

                          2. Tùy người thôi chọn 24 bit nó sẽ ra giá trị chẵn hơn với 1200.
                          Nhưng mà với tần số 40Mhz thì phase em sai ngay.

                          3. 12 bit là biên độ. i của em là phase nhé. Nếu mà bảng có 4096 phần tử thì chương trình của em kô còn đúng nữa.

                          4. OK cách tính phase của em đúng. Xin lỗi vì nhận xét chưa đúng
                          Gửi anh qmk:
                          Câu 1,2---Hihi...
                          Nếu anh nói dùng để chẵn tốc độ bit trong module nối tiếp thì còn có lý, bởi nó là module phần cứng. Nó sẽ đúng như thế vì ko phụ thuộc vào thời gian thực thi lệnh. Nhưng ở đây, thực thi ngắt nó lại phụ thuộc vào code. Việc dùng ngắt timer chia ra để chẵn giá trị 1200hz thì vô cùng khó. Bởi chương trình thực thi bởi phần mềm. Khi thực hiện ngắt nó phải làm một loạt các thao tác vào ngắt: ví dụ: thực hiện hết lệnh asm hiện tại, rồi mất 1 thời gian nhảy vào ngắt, rồi chưa kể đến trường hợp xấu như: đúng thời điểm đó, nó đang ở một ngắt khác???hihi...có những sai số hệ thống phần nào xử lý được, nhưng ở đây??? bởi thế để ngắt đúng 1200hz phải chấp nhận một sai số. Hơn nữa, cũng như yêu cầu bất cứ bài toán nào, cũng có dung sai một sai sô 1200+-delta. Bởi vậy việc chọn dao động 40Mhz là hợp lý nhất.
                          Câu 3-- quan trọng là ý tưởng đưa ra, chứ việc cụ thể hóa tính toán lại chỉ là sự tỷ lệ giữa 360 phần tử và MAX phần tử thôi.
                          Câu 4--Hihi.. em hỏi nhỏ tý, anh lấy các hệ số 1/3, 2/3 ở đâu ra?

                          Câu 5--Gửi anh Minh Hà? sao không thấy anh trả lời gì vậy?hihi... nếu lời giải của em đúng thì .. em cũng ko nỡ lấy LCD của anh đâu.. Mà nếu có thì không lấy LCD 16*2(vì thị trường đã có), chỉ mua rẻ cái LCD Graphic bằng giá gốc thôi..hihi..
                          À , lời giải trên mới là ý tưởng, cần bố cục lại , và bẫy lỗi, chặt chẽ thêm một số vị trí nữa mới chính xác.

                          Comment


                          • #28
                            Kết quả bên trên vẫn chưa SIN trơn. Cách thử như sau. Chuyển sang viết trên PC tạo thành 1 mảng data cho 1 byte cần phát ( ví dụ 55 F8) sau đó vẽ dạng tín hiệu vừ tạo ra. Kết quả vẫn còn bị gấp khúc tại điểm nối của 2 tần số.
                            Mong các bạn chạy thử và cho ý kiến. MH dùng phần mềm audio ( cool edit) để vẽ dạng tín hiệu
                            Nhà sản xuất chuyên nghiệp các sản phẩm OEM cho gia dụng và công nghiệp.

                            Biến tần
                            Máy giặt
                            Lò vi sóng
                            Bếp từ.
                            Tủ lạnh.
                            Điều hòa

                            Comment


                            • #29
                              1/3, 2/3 có giải thích rồi mà vì chọn thạch anh 24MHz nên nó chẵn thế. Thực ra việc tạo một xung đúng 5000 hoàn toàn có thể làm đc. Pic thì hơi khó hơn một tẹo.
                              Vẫn biết mỗi lần xa là một lần về lại...

                              Comment


                              • #30
                                Hihi.. đúng rồi đó anh, thì em mới viết là cần chặt chẽ hơn. Lỗi đó sửa lại bằng cách viết lệnh: if (p<0) p=360+p;

                                Comment

                                Về tác giả

                                Collapse

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

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

                                Collapse

                                Đang tải...
                                X