Daha çox

Çox asan python kodunda bir səhv (Tampon 1 - Tampon 2- Silmə 2 fom 1)

Çox asan python kodunda bir səhv (Tampon 1 - Tampon 2- Silmə 2 fom 1)


Nöqtələr (şəhərlər) ətrafında 500m üzüklər (tam dairə deyil) düzəltməliyəm. 1. tampon etməyə çalışıram: 2500 - 8500 m (hər 500 m) və ikinci tampon 3000 - 9000 (hər biri 500 m) və sonra 2500 m - 3000 m, 3000 m (1. tampon) - 3500 m (ikinci tampon) dən silmək… 500 m üzüklər. Ancaq hər dəfə bir səhv alıram.

idxal arcpy.sa… k = 3000… k <= 9000:… arcpy.Buffer_analysis ("sidla", "sidlaBuff"+str (k), k)… k = k+500… l = 2500… l <= 8500:… arcpy.Buffer_analysis ("sidla", "vyrezBuff"+str (l), l)… l = l+500 arcpy.Erase_analysis ("sidlaBuff"+str (k), "vyrezBuff"+str (l), "vysledek"+str (l))

Səhv, sidlaBuff9500 və vyrezBuff9000 qatını edə bilməməsi ilə əlaqəli bir şeydir, amma bunu etmək istəmədiyim təbəqələr ... amma bu kodu silmədən işləsəm, bütün tampon düzgün işləyir. Kimsə kömək edə bilərmi?


Ssenariniz işlədikdən sonra K və L yadda saxlanılır. Son K və L, səhvinizdən göründüyü kimi, 9500 və 9000 olacaq, çünki hər tampondan sonra bu dəyişənlərin dəyərinə 500 əlavə edir və silməniz yalnız WHILE döngəsinin xaricində olduğu üçün son dəyəri çağırır. Başqa bir yineleme yaradardım və hər bir K və L işlədikdən sonra içərisində silməyi qoyaram ki, etibarlı K və L dəyərləri hələ də yaddaşda olarkən işlənər.


Səbəbiniz ikiqat 'while' ola bilər. İki təkrarlayıcıdan istifadə etmək əvəzinə, k və l, yalnız birini istifadə edin. Qoyun i = iterasiya sayı. i = 0 ikən i <20 Tampon1 = 2500+500*i Tampon2 = 3000+500*i Tampon2-Tampon1 = Nəticə i = i+1


Birincisi, bunun üçün məkan analitikinə ehtiyac yoxdur

İkincisi, bunu etmək üçün birdən çox zəng tamponundan istifadə edə bilərdiniz, amma bütün ara xüsusiyyət siniflərinə ehtiyacınız olduğunu düşünürəm

üçüncüsü, kodunuzda bəzi girinti problemləri var

idxal arcpy… k = 2500… isə k <= 8500:… arcpy.Buffer_analysis ("sidla", "sidlaBuff"+str (k), k)… arcpy.Buffer_analysis ("sidla", "vyrezBuff"+str (k+) 500), k+500)… arcpy.Erase_analysis ("vyrezBuff"+str (k+500), "sidlaBuff"+str (k), "vysledek"+str (k))… k+= 500

Zəng Buferinin C ++ 14 -də tətbiqi

Bir halqa tamponu və ya dairəvi tampon, məlumatları daşımaqdansa, baş və quyruq göstəricilərini modulo şəkildə irəli aparan sabit ölçülü bir növbədir. Üzük tamponları tez -tez quraşdırılmış kompüter dizaynında istifadə olunur.

Pete Goodliffe -in ACCU məqaləsindən və Chris Riesbeck veb səhifəsindən ilhamlanan c ++ 14 uyğun halqa tamponunun bu tətbiqi.

Bir hobbi proqramçı olaraq, şablonlardan istifadə haqqında daha çox məlumat əldə etmək üçün bu layihəyə başladım. Onları tam başa düşmədiyim üçün ayırıcılardan qəsdən qaçdım. Eyni səbəbdən "emplace_back" cəhd etmədim, amma bu barədə öyrənmək istərdim. Varsayılan kopyalama/hərəkət konstruktorlarından istifadə etdim. Stil, dizayn və sinifin tamlığı haqqında əldə edə biləcəyim hər hansı bir təklif və ya rəyiniz təqdir ediləcəkdir. İeratorun əsasən STL uyğun olduğuna inanıram, amma layihənin bu tərəfi ilə bağlı rəydən də məmnun olaram.

İşdə sınamaq üçün istifadə etdiyim kod budur.

Və bu testin nəticəsidir.


Mətn xüsusiyyətləri qlobal olaraq sətir üçün deyil, simli hər bir xarakter üçün təyin olunur. Buna görə, sətirlər fərqli olduqda mətn xüsusiyyətlərini sözün həqiqi mənasında köçürmək olmaz.

Fərqli obyektlərin oxşar xüsusiyyətlərə malik olmasına baxmayaraq, xüsusiyyətlər hər bir obyekt üçün özünəməxsusdur. Mətn xüsusiyyətləri, dəyərindən asılı olmayaraq hər bir obyekt üçün xüsusi olaraq təyin olunur.

Xassələri qoruyarkən simli məzmunu dəyişdirmək üçün setf və ya bənzər bir şeydən istifadə etmək üçün heç bir yol tapmadım.

Yeniləmə: Orijinal sətirdən yeni sətrə xüsusiyyət əlavə etmək üçün alt sətrin setf qabiliyyətini yenidən təyin edə bilərsiniz. Bu cl-lib.el-də 616-cı sətirdən kodun yüngül şəkildə uyğunlaşdırılmış versiyasıdır

Bunun yaxşı bir fikir olduğunu söyləyə bilmədim, çünki yalnız 0 xarakterindən xassələri alır. Sizin vəziyyətinizdə bu yaxşı görünür, amma ümumiyyətlə belə olmaya bilər. Yeni simli qoymaq üçün bu bölgədəki hər bir xarakterdən bütün xüsusiyyətləri əldə etmək mənalı ola bilər və ya olmaya bilər.

Bir sətir sahibi olsam və onu dəyişənə saxlasam, mətn xüsusiyyətlərini dəyişdirmədən həmin dəyişənin daxilindəki sətri necə dəyişə bilərəm?

AFAIK, ən ümumi halda bu mümkün deyil (və ya praktik), çünki fərqli sətirlər uzunluğuna görə fərqlənə bilər və buna görə də Fólkvangr tərəfindən qeyd edildiyi kimi, onların müvafiq mətn xüsusiyyət intervalları uyğun gələ bilməz. Bu cür uyğunsuzluqları necə bağlayacağınızı əvvəlcədən bilirsinizsə, əldə etməyə çalışdığınız hər şeyə daha yaxşı bir alqoritmik yanaşma ola bilər.

Sətrin bütün uzunluğu boyunca sabit qalan sadə mətn nümunələri üçün John Kitchin cavabına baxın.

Bununla birlikdə, bu yanaşma birdən çox mətn xüsusiyyət aralığı ilə pozulur:

Orta xarakterə əlavə edilən b mətn xüsusiyyətinin itirilməsinə diqqət yetirin. Mümkün bir həll yolu, mətn xüsusiyyətlərinin xarakterini xarakterə görə kopyalamaqdır, lakin bu da ümumi vəziyyətdə işləməyə bilər.

String uzunluğuna təsir etmədən simli simvolların yerində dəyişdirilməsinin digər sadə bir vəziyyətdə, mətn xüsusiyyətlərini qoruyan aset, fillaray, subst-char-in-string və store-substring kimi funksiyalardan istifadə edə bilərsiniz:

Bir şərhdə Fólkvangr tərəfindən qeyd edildiyi kimi, ümumiyyətlə sətirləri dəyişdirmək tövsiyə edilmir, lakin (elisp) Ardıcıllıq Funksiyalarına baxın.

Emacs 26-da (çox məhdud hallarda işləyən) başqa bir yanaşma, əvəz-tampon-məzmun funksiyasından istifadə etməkdir:

Bütün bunları söyləyən Elisp, mətni dinamik şəkildə mülkiyyətə gətirmək üçün bir yol təqdim edir: bufer örtükləri. Qatlama intervalları, mətn daxil edildikdə və silindikdə deterministik bir şəkildə hərəkət edən markerlər tərəfindən təyin olunur, buna görə də müvafiq örtük xüsusiyyətlərini qoruyarkən tampon məzmununu dəyişə bilərsiniz. Bindirmələri olan bir tamponun mətn xüsusiyyətlərinə malik bir tampon sətrinə çevrilməsi oxucu üçün bir məşq olaraq qalır. )


2 Cavab 2

362 880 imkan olduqda niyə kodunuzu optimallaşdırmalısınız, optimallaşdırmanın ən yaxşı yolu imkanların sayını azaltmaqdır. Burada mürəkkəblikdir O (n²!) hesablamaq tez bir zamanda mümkünsüz olur (4x4 5 trilyon üçün 20 trilyon ehtimal və 15 septilyondur).

Bu vəziyyətdə stringsin istifadə edilməsinin əleyhinə mübahisə edərdim, çünki onlar dəyişməzdir, yəni hər zaman yeni nümunələr yaratmalısınız. (numpy serial?)

Son 50 sətir çox təkrarlanan hiss edir (həm də move_xxxx ()) və təkmilləşdirilə bilər

Dəyişdirdiyim şey budur (> əlavə etmək deməkdir, & lt silinmək deməkdir):

Kodunuzu daha dərindən oxuyacağam və bu cavabı yeniləyəcəyəm.

Burada bir neçə məqam var:

Sənədlərinizi və şərhlərinizi sənəd sənədlərinə köçürməlisiniz:

__İnit__ zəngi zamanı parametrlərinizi doğrulayın ki, bir daha bunu etməyəsiniz! Doğru rəqəmlərin, alt işarənin, boşluqların və s. Mövcud olub olmadığını yoxlayın. Heç bir şeyin təkrarlanmadığından əmin olun.

"String" dən "square" formatına keçmək üçün çox vaxt sərf edirsiniz. Bunu etməyi dayandırın və kodunuzu hər zaman simli olaraq yenidən yazın.

Move_up -un kaydırıcıya (_get_old_configuration adlı) və sonra move_up -a zəng etdiyinə diqqət yetirin _get_old_configuration adlı! Sadəcə funksiyaya zəng vurdunuz, nəticəni atdınız və funksiyanı yenidən çağırdınız.

Ən pisi odur ki, kaydırıcı heç vaxt istifadə olunmayan bir matris qurur. Yuxarı hərəkət edə biləcəyinizi yoxlamaq üçün yalnız kaydırıcının mövcud mövqeyindən istifadə edirsiniz.

Lövhənizi bir simli olaraq düşünün: "123456789". İlk üç dəyər üst sıradır. Son üç dəyər alt sətirdir. İndi sol və sağ sütunlar haqqında düşünün: sadəcə simli bir indeksi hesablaya və bir xarakterin hansı sütunda olduğunu müəyyən etmək üçün % 3 indeksindən istifadə edə bilərsiniz: index % 3 == 0 sol sütun deməkdir. == 2 sağ sütun deməkdir.

Beləliklə, kaydırıcının indeksini bilmək (bunun üçün str.index var) satır və ya sütunu da tanımağa imkan verir. Str.index -ə dörd dəfə zəng etmək əvəzinə, davam edəcək və çağırılacaq üsulları ehtiva edən bir Sıra [Ardıcıllıq [Çağırıla bilən]] qurun:

İndi str.index () üçün tək bir zəngdən istifadə etmək, onları təkrarlamaq və yoxlama və ya parçalanma etməmək üçün üsullara baxa bilərsiniz.

Eynilə, yalnız simli formatda necə "hərəkət etməyi" bilirsiniz. Kaydırıcı mövqeyini (indeksi) ya bir uzaqda (solda/sağda) və ya üçdə uzaqda (yuxarı/aşağı) dəyişdirin.

Node_id -i kodlarınızdan kodlaşdırmaq və deşifr etmək üçün çox vaxt sərf edirsiniz. Yalnız ayrı bir məlumat obyekti edin! collections.namedtuple bunun üçün idealdır:

Öz __init__ metodunuzu təmin etmək üçün yeni növü alt siniflərə ayıra və qlobal node_id += 1 məntiqini tətbiq etmək üçün istifadə edə bilərsiniz.


2 Cavab 2

1. Giriş

30 saata işləyən kodu tərk etmək yaxşı bir plan deyil. Kodu təhlil etməyincə və işləmə müddətinin girişin ölçüsünə görə necə dəyişdiyini öyrənməyincə, bunun nə qədər çəkəcəyi barədə heç bir fikriniz yoxdur. Bəlkə 31 saat çəkəcək, amma bəlkə də bir milyon saat çəkəcək.

Bu vəziyyətdə (i) işləmə müddətinin mürəkkəbliyi üçün bir ifadə əldə etmək üçün alqoritmi təhlil etməlisiniz (yəni işləmə müddəti girişin ölçüsündən asılıdır) (ii) kiçik girişlərdə kodun işini ölçmək (iii) (i) və (ii) nəticələrini tam məlumat dəsti üçün iş vaxtına ekstrapolyasiya etmək üçün istifadə edin.

2. Baxış

Sənədlər yoxdur. Bu funksiyalar nə etməlidir?

math.hypot istifadə edərək dist sadələşdirilə bilər:

Join_pairs adı heç bir şeyə qoşulmadığı üçün yanıltıcıdır. Daha yaxşı bir ad seçə biləcəyinizə əminəm.

Saxta olana dönənə qədər join_pairs çağıran bir funksiyaya sahib olmaq (test və performans ölçümü üçün) faydalı olardı. Bu funksiyanı istifadə edəcəyəm:

Xalların bir nüsxəsini götürməyimin səbəbi (orijinalı dəyişdirmək əvəzinə), bu funksiyanı giriş məlumatlarını məhv etmədən test və ya performans ölçümü üçün çağıra bilərəm. Bəzi nümunələr üçün aşağıya baxın.

3. Performans

Burada 1000 təsadüfi baldan ibarət test nümunəsi var:

Yazıdakı kodu, ən azı 0,04 aralığında olan 286 ballıq seyrək bir alt qrupa endirmək üçün təxminən 11 saniyə çəkir:

Niyə bu qədər uzun çəkir? Problem ondadır ki, join_pairs hər dəfə çağırıldıqda yalnız bir nöqtəni silir. Bu o deməkdir ki, onu bir döngədə axtarmalısan, amma hər dəfə çağıranda əvvəlki iterasiyada müqayisə olunan eyni cüt nöqtələri müqayisə etməklə başlayır. Bu alqoritm nəticəsində iş vaxtı $ O (n^3) $: yəni iş vaxtı giriş uzunluğunun kubu kimi böyüyür.

Bu kub davranışını $ n $ bir sıra ölçülərdə funksiyanın götürdüyü vaxtı ölçərək və $ t = an^3 $ ən uyğun olan bir tənlik taparaq görə bilərik:

Bunu matplotlib istifadə edərək bir günlük qeyd qrafiki üzərində qura bilərik:

Bu analizdən və ölçmədən ekstrapolyasiya edərək, $ n = 300000 $ olarsa, alınmış vaxtın təxminən olacağını təxmin edirik:

Bu təxminən on ildir! Qrafikə baxdıqda, məlumatların yamacının ən yaxşı uyğunluq xətti qədər dik olmadığı görünür, buna görə də həqiqi eksponent 3-dən bir qədər azdır və ekstrapolyasiya edilmiş vaxt on ildən bir qədər azdır. Ancaq kobud bir analiz olaraq, bu, bir neçə saat ərzində bitəcəyinə heç bir ümid olmadığını və buna görə də daha yaxşı bir yanaşma tapmalı olduğumuzu söyləyir.

İşi bu nöqtələr siyahısının üzərində bir keçiddə etmək daha yaxşı olardı:

Bu, siyahı nəticəsindəki dəyişdirilmiş nöqtə buludunu yaradır və geri qaytarır (giriş nöqtələrini dəyişdirmək əvəzinə). Kod, girişdəki hər bir nöqtəni nəzərdən keçirir və nəticəyə əvvəllər əlavə edilmiş bütün nöqtələrdən kifayət qədər uzaq olduğu müddətdə nəticəyə əlavə edir.

Bunun doğru olduğunu yoxlamaq üçün çıxışı kodun orijinal versiyası ilə müqayisə edə bilərik:

Bu yenidən işlənmiş kod $ O (nm) $ alır, burada $ n $ girişdəki nöqtələrin sayıdır və $ m $ çıxışdakı nöqtələrin sayıdır. Ən pis halda $ m = n $ və kod hər cüt nöqtəni müqayisə etməlidir. 1000 ballıq test qutusunda, bu yazıdakı koddan yüz qat daha sürətlidir:

Performansı daha da yaxşılaşdırmaq üçün a məkan indeksi, yəni səmərəli yaxın qonşu sorğularını dəstəkləyən bir məlumat quruluşu. Bu problem üçün, R-ağac məlumat quruluşunu tətbiq edən Python Paket İndeksindən Rtree paketini istifadə edəcəyəm. Bir R ağacı, düzbucaqlılar toplusunu (və ya axtarış sahəsinin iki ölçüdən çox olması halında hiper düzbucaqlı) saxlayır və sorğu düzbucaqlı ilə kəsişən düzbucaqlıları səmərəli şəkildə tapa bilir.

Bu kod nəticə siyahısına bir nöqtə əlavə etdikdə, R ağacına uyğun bir düzbucaq da əlavə edir. Bu düzbucağın sıfır genişliyi və hündürlüyü var, buna görə də tək bir nöqtəni təmsil edir. Nəticə dəstinə daxil olmaq üçün p nöqtəsi nəzərdən keçirilərkən, kod eni və hündürlüyü 2 * r olan p üzərində mərkəzləşdirilmiş düzbucaqlı sorğu aparır. R məsafəsindəki bütün nöqtələr bu düzbucağın içərisindədir, lakin düzbucağın künclərində r -dən daha uzaq olan bəzi nöqtələr də ola bilər. Buna görə kod, sorğu düzbucağının hər bir nöqtəsini daha da yoxlamalıdır.

Yenə də bunun doğru olub olmadığını yoxlamalıyıq:

Bir R ağacı $ m $ düzbucaqlı indeksində kəsişən bir düzbucaq tapmaq üçün $ O ( log m) $ alır, buna görə də sparse_subset3-ün işləmə müddətinin $ O (n log m) olmasını gözləyirik $, burada $ n $ girişdəki nöqtələrin sayıdır və $ m $ çıxışdakı nöqtələrin sayıdır.

100.000 bal ilə daha böyük bir test işi edək:

Sparse_subset2 və sparse_subset3 -ün performansı $ m $ nəticəsindəki xal sayından asılıdır. R böyük olduqda $ m $ kiçik olacağını və buna görə də çox fərq olmayacağını gözləyirik. Burada r = 0.05 istifadə edirik və 287 ballıq bir alt dəsti alırıq və iki alqoritmin işləmə müddəti demək olar ki, eynidir:

Ancaq r-ni 0,01-ə endirsək, 5994 ballıq bir dəstə alsaq, R ağacı parlayır:

(Bu test işində sparse_subset1 sınamadım, çünki çox saat çəkəcək.)

Sparse_subset3 üçün ən pis vəziyyət r sıfır olduğu və nəticədə girişdəki bütün nöqtələrin sona çatmasıdır:

Buradan çıxış edərək, 300.000 ballıq çantanızı bir dəqiqədən az müddətdə işə salmalısınız ki, bu da on il üçün böyük qənaətdir.


7 Cavab 7

Winbond SPI flaşını işləyərkən istifadə etmək üçün oxuyacağı "əvvəlcədən yüklənmiş" məlumatlarla proqramlaşdırmaq üçün bir yol axtarırsınızsa, baxmaq istədiyiniz şey, dövrə daxilində proqramlaşdırma edə bilən bir proqramçıdır. SPI Flash çipinin. Bu, sistem içi proqramlaşdırma (ISP) olaraq da bilinir.

Bir seçim DediProg proqramçısıdır. Lövhənizi düzgün tərtib etsəniz, bu USB -yə qoşulmuş cihaz dövrədə proqramlaşdıra bilər. Lövhənizdə ayrı bir proqramlaşdırma başlığı dizayn etmədən SOW-16 paketinə qoşula bilən bir adapter klipi də satırlar. DediProg, dövrə istifadəsi üçün düzgün dizaynla kömək edə biləcək tətbiq məlumat bülletenlərinə malikdir. Dizaynın əsas strategiyası, MCU sisteminizdəki SPI interfeys sürücülərini SPI proqramlaşdırma bölməsindəki sürücülərə müdaxilə etməmək üçün təcrid etməyin sadə bir yolunu tapmaqdır. Bunun ən sadə yolu MCU ilə SPI Flash arasındakı MCU idarə olunan xətlərə seriyalı rezistorlar qoymaqdır. Proqramçı seriyalı rezistorların SPI flaş tərəfinə qoşulurdu. Alternativ üsullar idarə olunan interfeys xətlərinə MUX və ya analoq açarların əlavə edilməsini əhatə edə bilər. Daha da ağıllı bir sxem, proqram təminatının SPI Flash çipindən bütün SPI G/Ç -lərini ayıran MCU -ya "proqramlaşdırma imkanları" daxil etməkdir (yəni bütün bu GPIO -ları giriş kimi etmək).

Nəzərə almaq lazım olan ikinci seçim ASIX -dən olan USB proqramçısıdır. Presto, SPI Flash cihazları da daxil olmaqla müxtəlif növ SPI və I 2 C cihazları edə bilir. Xüsusilə Atmel MCU və müxtəlif növ SPI Flash cihazlarını proqramlaşdırmaq üçün bu cihazlardan birinə sahibəm. Yuxarıda göstərilən qurğudan daha qənaətli bir həlldir, lakin o qədər də çevik deyil. Forte adlı daha bahalı cihazı daha çox şey edə bilir, çünki daha çox hədəf interfeys pininə malikdir.

Bəzən proqramlaşdırma başlığını əlavə etmədən bir proqramçıyı hədəf lövhəsinə bağlaya bilmək faydalı ola bilər. Bunun üçün gözəl bir həll, TagConnect adlı bir şirkətin təyin etdiyi xüsusi bir ərazidə kiçik bir yastıq dəsti yerləşdirməkdir. Lövhədə xüsusi ayaq izi olan pogo pinləri olan bir sıra sürətli əlaqə proqramlaşdırma kabelləri istehsal edir və satır. Kabelin bir sıra tətbiqlərə uyğun olaraq 6, 10 və 14 pinli versiyaları mövcuddur. Kabellərin qiyməti çox münasibdir.

40 dollar. $ endgroup $ & ndash markrages 23 yanvar '15 saat 22:22

Əminəm ki, MCU -dan keçmədən bunu bir Avtobus Piratı ilə edə bilərsiniz. Bu, SPI, I2C və ya UART ünsiyyətindən istifadə edərək birbaşa bir çiplə bir qədər ixtiyari ardıcıl qarşılıqlı əlaqə qurmağa imkan verir. "Ssenari yazmaq" üçün bir az iş tələb oluna bilər, amma yəqin ki, bu işi görməyinizə icazə verərdi.

EEPROM -u birbaşa I2C üzərindən yükləmək üçün xüsusi vasitələr gördüm, ancaq xüsusi olaraq SPI deyil, flaş deyil.

SPI -nin belə bir çiplə birbaşa danışdığını heç vaxt eşitməmişəm və düşünürəm ki, "bütün" çiplər fərqli əməliyyatlar üçün fərqli çağırışlar tələb edir.

Çipin yazmaq, oxumaq, sektoru dəyişdirmək, məlumat ölçüsü və s. Altında SPI çağırışlarına ehtiyacı var 7.2 Təlimatlar məlumat cədvəlində, ona göndərə biləcəyiniz bütün SPI əmrlərini görə bilərsiniz. Beləliklə, bütün xarici flash yaddaşlarında eyni təlimat dəsti olmadığı üçün bunun üçün xüsusi bir proqram yazmalısınız.

EDIT: Bir təqib olaraq, Atmels -in SPI flash yaddaşlarından birini tövsiyə edərdim, çünki əksəriyyəti artıq onlar üçün açıq kod yazmışdır. AVRFreaks -dən bu yazıya baxanda sizə bəzi Atmels AT45xxxx seriyalı fiş çiplərinin kodu veriləcək.

Müzakirəyə bir qədər gec, ancaq axtarışdan sonra oxuyanlar üçün.

Görmədiyim bir şey, SPI Flash çiplərini proqramlaşdırarkən tamamilə vacib olan Chip Select (CS_) pininin nəzarətidir. Chip Select pin, əmrləri SPI Flash -da işarələmək üçün istifadə olunur. Xüsusilə, CS_ yüksəkdən CS_ aşağıya keçid hər hansı bir Yazma əməliyyatı kodunun (WREN, BE, SE, PP) verilməsindən dərhal əvvəl olmalıdır. CS_ keçidi arasında (yəni CS_ aşağı düşdükdən sonra) və yazma kodu ötürülməzdən əvvəl bir aktivlik varsa, yazma kodu ümumiyyətlə yazılmayacaq.

Ayrıca, SPI Flash məlumat cədvəllərində çox açıqlanmayan şey, SPI protokolunun ayrılmaz bir hissəsidir, çünki bu da hər bir baytın SPI avtobusunda ötürdüyünün əvəzində bir bayt almasıdır. Ayrıca, bir bayt ötürməyincə heç bir bayt ala bilməz.

Tipik olaraq, istifadəçinin əmr etdiyi SPI Master, SPI avtobusunun MOSI xəttinə bayt göndərən və SPI avtobusunun MISO xəttindən bayt qəbul edən Qəbul Tamponuna malikdir.

Hər hansı bir məlumatın Alma tamponunda görünməsi üçün bəzi məlumatların Göndərmə Tamponundan göndərilmiş olması lazımdır. Eynilə, hər hansı bir məlumat ötürmə buferindən göndərildikdə, məlumatlar Qəbul Tamponunda görünəcək.

Transmit yazma və Alma oxunuşlarını balanslaşdırmaqda diqqətli deyilsinizsə, Qəbul buferində nə gözlədiyinizi bilməyəcəksiniz. Qəbul buferi daşsa, məlumatlar ümumiyyətlə sadəcə tökülür və itirilir.

Belə ki, bir bayt op kodu və üç ünvan baytı olan bir oxumaq əmri göndərildikdə, əvvəlcə SPI Master Qəbul tamponunda dörd bayt "zibil" alınacaq. Bu dörd bayt zibil, op koduna və üç ünvan baytına uyğundur. Bunlar ötürülərkən, Flash hələ nə oxuyacağını bilmir, ona görə də yalnız dörd söz zibili qaytarır.

Bu dörd söz zibil qaytarıldıqdan sonra, Alma Buferində başqa bir şey əldə etmək üçün Oxumaq istədiyiniz məbləğə bərabər miqdarda məlumat ötürməlisiniz. Əməliyyat kodundan və ünvandan sonra nəyi ötürməyinizin əhəmiyyəti yoxdur, Read DAta -nı SPI Flash -dan Qəbul Tamponuna itələmək kifayətdir.

İlk dörd geri qaytarılmış zibil sözünü diqqətlə izləməsəniz, onlardan birinin və ya bir neçəsinin geri qaytarılmış Oxu Verilərinizin bir hissəsi olduğunu düşünə bilərsiniz.

Beləliklə, alma tamponundan əslində nə əldə etdiyinizi bilmək üçün tamponunuzun ölçüsünü bilmək, boş və ya dolu olub olmadığını necə bilmək vacibdir (bunu bildirmək üçün adətən qeyd statusu biti var) və necə ötürdüyünüz və aldığınız çox şey.

Hər hansı bir SPI Flash əməliyyatına başlamazdan əvvəl, Receive FIFO -nu "boşaltmaq" yaxşı bir fikirdir. Bu, qəbul tamponunun vəziyyətini yoxlamaq və onu boşaltmaq deməkdir (adətən Qəbul Tamponunun "oxunması" ilə aparılır) əgər hələ boş deyilsə. Adətən, artıq boş olan Alma Buferinin boşaldılması (oxunması) heç bir zərər vermir.

Aşağıdakı məlumatlar SPI Flaşlarının məlumat cədvəlindəki vaxt diaqramlarından əldə edilə bilər, lakin bəzən insanlar bitləri görməzdən gəlirlər. Bütün əmrlər və məlumatlar SPI avtobusu istifadə edərək SPI flaşına verilir. Bir SPI Flash oxumaq ardıcıllığı belədir:

Nəzərə alın ki, 6 və 7 -ci addımlar oxunuşun ölçüsünə və Qəbul və Göndərmə Tamponlarınızın ölçüsünə görə aralığa qoyulmalı və təkrarlanmalıdır. Qəbul Tamponunuzun saxlaya biləcəyindən daha çox söz bir anda ötürsəniz, bəzi məlumatları tökəcəksiniz.

Səhifə Proqramı və ya Yazma əmrini əvvəlcədən hazırlamaq üçün bu addımları yerinə yetirin. Səhifə Ölçüsü (adətən 256 bayt) və Sektor Ölçüsü (adətən 64K) və əlaqəli sərhədlər istifadə etdiyiniz SPI Flash -ın xüsusiyyətləridir. Bu məlumatlar Flash məlumat cədvəlində olmalıdır. Tamponların Alınması və Alınması balansının təfərrüatlarını buraxacağam.

Nəhayət, yazma ünvanınız bir səhifə sərhədində deyilsə (adətən 256 baytdan çoxdur) və aşağıdakı səhifə sərhədini keçmək üçün kifayət qədər məlumat yazırsınızsa, sərhədi keçməli olan məlumatlar səhifənin əvvəlinə yazılacaq proqram ünvanınız düşür. Beləliklə, 0x0FE ünvanına üç bayt yazmağa cəhd edirsinizsə. İlk iki bayt 0x0fe və 0x0ff olaraq yazılacaq. Üçüncü bayt 0x000 ünvanına yazılacaq.

Səhifə ölçüsündən daha çox sayda məlumat baytı ötürsəniz, ilk baytlar atılacaq və səhifəni proqramlaşdırmaq üçün yalnız son 256 (və ya səhifə ölçüsü) bayt istifadə ediləcək.

Həmişə olduğu kimi, yuxarıdakı səhvlərin, yazım səhvlərinin, səhvlərin və ya pozğunluqların nəticələrindən və ya necə istifadə etməyinizdən məsuliyyət daşımır.


2 Cavab 2

(Gələcək oxuculara qeyd: buradakı hirs tonu sual üçün deyil, cavab verməyə çalışdığım səhvlər və çoxlu düzəlişlər üçündür.)

Ah, yazığa görə. Problem quyruqdadır. Bu yaxşı işləyir:

Bu boru deyil, qrup deyil. Quyruqdur. Necə ki, öz quyruğumuzu təqib edirik!

Beləliklə, tail -f uğursuz oldu, çünki nədənsə dərhal çıxmır. Python -u -nun niyə uğursuz olduğuna əmin deyiləm, amma bunun ssenaridə heç bir şey olduğunu düşünmürəm. Bəlkə də buferdən çıxarmağa çalışın. Ssenarinizi heç olmasa pişiklə sınayın və bu vəziyyətdə tamponlanmadığını yoxlayın.

Əvvəlki uğursuz cəhd qəsdən buradan ayrıldı, beləliklə gələcək oxucular şərhləri anlamalıdır.

Bu skript, aldığınız eyni növ tamponlama problemini nümayiş etdirir:

Bu yoxdur. Qrupun daxilindəki çıxışlar stderr -ə yönləndirilir, sonra bütün qrupdan olan stderr əmrə ötürülür. Stderr olduğu üçün bufersizdir.

Bu suala Wang HongQin cavabından uyğunlaşdırılmışdır. Çətinlik, açıq bir əmrdən daha çox borunun aşırma ilə açılmasının yolunu tapmaqda idi. Yenidən yönləndirmənin düzgün işləməsi üçün bir müddət skripka etmək lazım idi.


Videoya baxın: Python لغة البايثون بالعربي للمبتدئين