|
發布時間: 2022-4-2 16:43
正文摘要:問題:DI口輸入一組400*24bit的數據,如何使用單片機實現:前40*24bit的數據不接收,剩下的數據全部轉給DO口輸出,并保證輸出數據的準確性,不亂碼。輸入數據0碼高電平時間為300ns左右。 已嘗試方法: 使用單 ... |
以夢為舟 發表于 2022-4-12 16:42 所以, 你既然 確定了, CLK_DIV |= 0x10 的中繼輸出 可以滿足你的輸出需要,(如果輸出高電平的驅動力不夠,開推挽輸出) 你現在唯一需要的就是: 理清楚,前面放棄數據的“過濾條件”, 達到這個條件后, 打開 中繼輸出 通道,然后達到什么條件以后 再次關閉中繼輸出, 就是那么簡單的一個工作而已。 |
|
你這個需要的mcu要支持雙邊沿觸發中斷,并且時鐘夠快。 現在所有的mcu都能做到。 引腳變化中斷了解下。 |
以夢為舟 發表于 2022-4-8 17:00 把你的代碼改了下,應該能做到前20*24bit不接收。
|
|
其實不太確定你的意圖, 你的計數到底計數的什么, 如果是 計數480個下降沿的話, 是不是應該這樣? void int4_Routine(void) interrupt 16 { if(++count==480) { CLK_DIV |= 0x10; } if(++count>=9600) { count = 0; CLK_DIV &= 0xEF; } } 這只是一個建議, 因為我沒理解你希望的 效果,CLK_DIV 你應該理解為一個 開關,在你認為適當的時候,打開開關 讓 P3.1 輸出 P3.0 不需要的時候關閉。這個開關只是一個動作,你在某一個中斷中 設置 開/關 即可,不需要再while里面反復去操作這個開關。你要知道,STC15系列 即便你 頻率定為 35MHz, 1us 可以有35個機器時鐘,處理一個if 判斷 一個雙字節16位數字 需要20個時鐘 已經超過 0.5us了,所以,按你的需要你必須把不必要的步驟精簡再精簡。 |
以夢為舟 發表于 2022-4-6 15:30 設置 CLK_DIV |= 0x10; 之后, P3.1 是 無縫輸出 P3.0 電平的,這個過程類似于中繼功能是不會有任何差錯的(硬件電路問題除外)。檢查一下你的外部電路,比如,下載電路是否有斷開等等。 作為你的問題“怎么最快將DI口數據賦給DO口?” 就你這個單片機而言,這個方法應該是最快的了,沒有之一。 至于,你說的“輸入數據的電平被拉低且會使數據碼混亂” 我不太理解, 粗看你貼的代碼, 也沒看出你程序的運行原理, 比如: 1)你 外部中斷設定的是 下降沿觸發,換句話說只能 DI == 0 的瞬間才觸發,你中斷里卻判斷 DI == 1 還是0。 個人認為這是毫無意義的行為。 2)雖然你寫了定時期中斷, 但是只看到 TR0 = 0 沒看到 TR0 =1, 感覺 count = 0 這個操作,對 外部中斷沒有任何實際作用, 分析不出你貼著兩段代碼的目的。 最后,你解碼必定要有一個接收解析過程吧? 按你說的時序要求,這個解碼,或者解析需要嚴格時間控制的吧? 也沒看你在定時器里面解碼,所以,諸多不解,看你有什么補充說明再說吧。 |
188610329 發表于 2022-4-4 00:31 把DI定在p3.0口后發現輸入數據的電平被拉低且會使數據碼混亂,導致整體不受控,這是什么原因.... |
|
把 DI 定在 P3.0 DO定在 P3.1, 通過: CLK_DIV |= 0x10; 可以直接在 DO 輸出 DI 的電平,無需中斷,無需任何其他代碼,幾乎沒有延時。 至于你之前說的計數,可以通過 外部中斷 EX4 進行計數 來控制打開DO輸出:CLK_DIV |= 0x10; 還是關閉DO輸出: CLK_DIV &= 0xEF; |
|
這個是做WS2812的驅動的吧。單片機指令周期都一兩百ns了,用程序來處理肯定來不及了。數據400個一組也就是1.2kb,先存下來再轉發內存也不夠用。不借助外部硬件恐怕是難。你程序直接中轉都達到600ns的原因是因為循環跳轉和中斷出入的代碼。單單MOVE bit指令也要3個周期,就算跑到33MHZ也要100ns所以純軟件是不夠的。 其實外部借助兩顆二極管就可以了,做個簡易的與門。收到前期bit后開通這個與門,這樣信號就能通過這個與門向后傳遞。也就沒有速度上的問題了,4148處理1MHz這樣的信號問題還是不大的。 |