Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8

В beşa yekem Min hewl da ku ji endezyarên elektronîk ên hobî yên ku ji pantorên Arduino mezin bûne re bêjim ka ew çawa û çima divê daneyan û belgeyên din ên ji bo mîkrokontrolkeran bixwînin. Nivîs mezin derket, ji ber vê yekê min soz da ku di gotarek cihê de mînakên pratîkî nîşan bidim. Belê, wî ji xwe re digot kivarka şîr...

Îro ez ê nîşanî we bidim ka meriv çawa pelên daneyê bikar tîne da ku ji bo gelek projeyan, peywirên li ser kontrolkerên STM32 (Blue Pill) û STM8 pir hêsan, lê hewcedar çareser bike. Hemî projeyên demo ji LED-yên min ên bijare re têne veqetandin, em ê wan bi rêjeyên mezin ronî bikin, ji bo vê yekê em ê neçar in ku her cûre dorhêlên balkêş bikar bînin.

Nivîs dîsa mezin derket, ji ber vê yekê ji bo rehetiyê ez naverokê çêdikim:

STM32 Blue Pill: 16 LED bi ajokera DM634
STM8: Sazkirina şeş pinên PWM
STM8: 8 RGB LED li ser sê pinan, qut dike

Daxuyanî: Ez ne endezyar im, ez xwe nakim ku di elektronîkê de zanîna kûr im, gotar ji bo amatorên mîna min e. Bi rastî, min du sal berê xwe wekî temaşevanek armanc dihesiband. Ger yekî wê gavê ji min re bigota ku pelên daneyan ên li ser çîpek nenas ji xwendinê ne tirsnak bû, min ê gelek wext li hin perçeyên kodê li ser Înternetê bigerim û bi maqûr û kasêta zeliqandî kepçeyan îcad bikim.

Mebesta vê gotarê li ser daneyan e, ne projeyan, ji ber vê yekê dibe ku kod ne pir xweş û pir caran teng be. Proje bi xwe pir hêsan in, her çend ji bo nasîna yekem a bi çîpê nû re maqûl in.

Ez hêvî dikim ku gotara min dê di qonaxek wusa ya ku di hobiyê de ye bibe alîkar.

STM32

16 LED bi DM634 û SPI

Projeyek piçûk bi karanîna Blue Pill (STM32F103C8T6) û ajokera LED DM634 bikar tîne. Bi karanîna pelên daneyê, em ê ajoker, portên STM IO fêhm bikin û SPI-ê mîheng bikin.

DM634

Çîpa Taywanî ya bi 16 derketinên PWM 16-bit, dikare bi zincîran ve were girêdan. Modela kêm-end 12-bit ji projeyek navxweyî tê zanîn Lightpack. Carekê, hilbijartina di navbera DM63x û TLC5940-a naskirî de, min ji ber çend sedeman DM hilbijart: 1) TLC li ser Aliexpress bê guman sexte ye, lê ev yek ne; 2) DM xwedan PWMek xweser e ku bi jeneratora xweya frekansê re heye; 3) ew dikare li Moskowê bi erzan were kirîn, li şûna ku li benda pakêtek ji Alî bimîne. Û, bê guman, balkêş bû ku meriv fêr bibe ka meriv çawa çîpê bi xwe kontrol dike, ji bilî karanîna pirtûkxaneyek amade. Çîp naha bi gelemperî di pakêta SSOP24 de têne pêşkêş kirin; ew hêsan e ku meriv bi adapterek veşêre.

Ji ber ku çêker Taywanî ye, datasheet çîp bi Îngilîzî ya Çînî hatiye nivîsandin, ku tê vê wateyê ku ew ê xweş be. Pêşî em li pinoutê dinêrin (Girêdana Pin(Pin Danasîna). 16 pin:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Çavkaniyên DC Sink (Drain vekirî)

Cilşo / Hilberîna vekirî-drain - rijandin; çavkaniya herikîna herikînê; encam di rewşa çalak de bi erdê ve girêdayî ye - LED bi katodan bi ajokerê ve têne girêdan. Ji hêla elektrîkê ve, bê guman, ev ne "dravek vekirî" ye (drain vekirî), lê di pelên daneyan de ev binavkirin ji bo pinên di moda dravê de pir caran tê dîtin.

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Berxwedêrên derveyî di navbera REXT û GND de ji bo danîna nirxa heyî ya derketinê

Di navbera pîneya REXT û erdê de berxwedêrek referansê tê saz kirin, ku berxwedana hundurîn a derkan kontrol dike, li grafîkê li ser rûpela 9-ê ya danezanê binêre. Di DM634 de, ev berxwedan dikare ji hêla nermalavê ve jî were kontrol kirin, ronahiya giştî saz dike (şewqa gerdûnî); Ez ê di vê gotarê de neçim hûrguliyan, ez ê tenê berxwedanek 2.2 - 3 kOhm li vir bidim.

Ji bo ku hûn fêm bikin ka meriv çawa çîpê kontrol dike, em li danasîna navgîniya cîhazê binêrin:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8

Erê, li vir ew e, Îngilîziya Çînî bi hemû rûmeta xwe. Wergerandina vê pirsgirêk e, heke hûn bixwazin hûn dikarin wê fêm bikin, lê rêyek din jî heye - binihêrin ka girêdana bi TLC5940-a fonksiyonel a wekhev di datasheet de çawa tête diyar kirin:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
... Ji bo têketina daneyê di nav cîhazê de tenê sê pin hewce ne. Rêjeya bilindbûna sînyala SCLK daneyê ji pînê SIN diguhezîne tomara navxweyî. Piştî ku hemî dane hatin barkirin, îşaretek XLAT-ya bilind a kurt daneyên ku bi rêzê ve hatî veguheztin di nav tomarên hundurîn de digire. Tomarên hundurîn dergeh in ku ji hêla asta sînyala XLAT ve têne rêve kirin. Hemî daneyan yekem bit-a herî girîng têne şandin.

Girtok - kildan / kildan / kilît.
Rabûna qiraxa - qiraxa sereke ya nebzê
MSB yekem - herî girîng (herî çepê) bit pêş.
ji bo daneyên demjimêrê - daneyan bi rêkûpêk (bit bi bît) veguhezîne.

Gotina girtok pir caran di belgeyên ji bo chips de tê dîtin û bi awayên cihêreng tê wergerandin, ji ber vê yekê ji bo têgihîştinê ez ê destûrê bidim xwe

bernameyek perwerdehiya piçûkAjokera LED-ê bi bingehîn qeydek veguherînê ye. "Shift" (tarloqî) di nav de - tevgera bitalî ya daneyê di hundurê cîhazê de: her bitek nû ya ku li hundur tê xistin, tevahiya zincîra li ber xwe dide pêş. Ji ber ku kes naxwaze di dema veguheztinê de tîrêjên kaotîk ên LED-an bişopîne, pêvajo di qeydên tampon ên ku ji tomarên xebatê ve ji hêla damperê ve têne veqetandin pêk tê (girtok) celebek jûreyek bendewariyê ye ku bit di rêza xwestî de têne rêz kirin. Dema ku her tişt amade ye, şûşe vedibe û bit diçin kar, li şûna koma berê. Bêje girtok di belgenameyê de ji bo mîkrocircuitan hema hema her gav pêvekek wusa vedibêje, ne girîng e ku ew di kîjan berhevokan de tê bikar anîn.

Ji ber vê yekê, veguheztina daneyê li DM634 bi vî rengî pêk tê: ketina DAI-yê li ser nirxa bit-a herî girîng a LED-a dûr bicîh bikin, DCK-ê bikişîne jor û jêr; ketina DAI-ê li ser nirxa bit-a paşîn saz bike, DCK-ê bikişîne; û bi vî awayî heya ku hemî bit nehatin şandin (saet di nav de), piştî ku em LAT dikişînin. Ev dikare bi destan were kirin (bit-bang), lê çêtir e ku meriv pêvekek SPI-ya ku bi taybetî ji bo vê hatî çêkirin bikar bîne, ji ber ku ew li ser STM32-a me di du kopiyan de tê pêşkêş kirin.

Pill Blue STM32F103

Destpêk: Kontrolkerên STM32 ji Atmega328 pir tevlihevtir in ku ew tirsnak xuya dikin. Wekî din, ji ber sedemên teserûfa enerjiyê, hema hema hemî periferîk di destpêkê de têne girtin, û frekansa demjimêrê ji çavkaniya hundurîn 8 MHz e. Xwezî, bernamenûsên STM kodek nivîsand ku çîpê digihîje 72 MHz-ya "hesabkirî" û nivîskarên hemî IDE-yên ku ez dizanim ew di prosedûra destpêkirinê de cîh girtine, ji ber vê yekê em ne hewce ne ku demjimêr bikin (lê hûn dikarin eger hûn bi rastî dixwazin). Lê hûn ê neçar bibin ku dorhêlan vekin.

Belgekirin: Blue Pill bi çîpê populer STM32F103C8T6 ve hatî stend, ji bo wê du belgeyên kêrhatî hene:

Di datasheet de dibe ku em bala xwe bidin:

  • Pinouts - çip pinouts - eger em biryar bidin ku panelan bi xwe çêbikin;
  • Nexşeya Bîrê - nexşeya bîranînê ji bo çîpek taybetî. Destûra Referansê ji bo tevaya rêzê nexşeyek heye, û tê de qeydên ku yên me tune ne vedibêje.
  • Tabloya pênaseyên pin - navnîşkirina fonksiyonên sereke û alternatîf ên pinan; ji bo "pîla şîn" hûn dikarin li ser Înternetê wêneyên hêsantir bi navnîşek pin û fonksiyonên wan bibînin. Ji ber vê yekê, em tavilê li pinouta Blue Pill google dikin û vê wêneyê li ber destê xwe digirin:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
NB: Di wêneya Înternetê de xeletiyek hebû, ku di şîroveyan de hate destnîşan kirin, spas ji bo wê. Wêne hate guheztin, lê ev dersek e - çêtir e ku meriv agahdariya ne ji pelên daneyê kontrol bike.

Em pelgeya daneyê jê dikin, Destana Referansê vedikin, û ji nuha û pê ve em tenê wê bikar tînin.
Pêvajo: em bi têketin/derketina standard re mijûl dibin, SPI-ê mîheng dikin, dorhêlên pêwîst vedikin.

Enput Output

Li ser Atmega328, I/O pir bi hêsanî tête bicîh kirin, ji ber vê yekê pirbûna vebijarkên STM32 dikare tevlihev be. Naha ji me re tenê encam hewce ne, lê tewra çar vebijark jî hene:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
rijandin vebûn, pêl-kişandin, kêş-kişandina alternatîf, vekêşana vekirina alternatîf

"Push-push" (kişandin-kişandin) derana asayî ya Arduino ye, pîne dikare nirxê BİXWÎNE an LOW bigire. Lê bi "vekêşana vekirî" hene zehmetiyan, her çend di rastiyê de her tişt li vir hêsan e:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Veavakirina derketinê / dema ku bender ji derketinê re tê veqetandin: / tampona derketinê çalak e: / - moda avêtinê veke: "0" di qeyda derketinê de N-MOS çalak dike, "1" di qeyda derketinê de ji portê di moda Hi-Z de derdikeve ( P-MOS nayê çalak kirin ) / – Moda push-kişandinê: "0" di qeyda derketinê de N-MOS-ê çalak dike, "1" di qeyda derketinê de P-MOS-ê çalak dike.

Hemî cûdahiya di navbera dravê vekirî (drain vekirî) ji "push-kişandin" (kişandin-kişandin) ev e ku di pîneya yekem de nikare rewşa BİXWÎNE qebûl bike: dema ku yek ji qeyda derketinê re dinivîse, ew diçe moda berxwedana bilind (impedance bilind, Hi-Z). Dema ku sifir dinivîsin, pin di her du awayan de, hem ji hêla mantiqî û hem jî ji hêla elektrîkê ve bi heman rengî tevdigere.

Di moda derketinê ya normal de, pin bi tenê naveroka qeyda derketinê belav dike. Di "alternatîf" de ew ji hêla dorhêlên têkildar ve tê kontrol kirin (binêre 9.1.4):

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Ger bitek portê wekî pinek fonksiyonek alternatîf were mîheng kirin, qeyda pinê tê neçalak kirin û pîne bi pîneya derdorê ve tê girêdan.

Karbidestiya alternatîf a her pinê di nav de tête diyar kirin Danasînên Pin Daneyên li ser wêneya dakêşandî ye. Ji bo pirsa ku hûn ê çi bikin ger pinek çend fonksiyonên alternatîf hebin, bersiv ji hêla jêrînek di pelê de tê dayîn:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Ger gelek dorhêl heman pînê bikar bînin, ji bo ku ji nakokiya di navbera fonksiyonên alternatîf de dûr nekevin, divê her carê tenê yek dorhêl were bikar anîn, bi karanîna bit çalakkirina demjimêra dorhêlê (di qeyda RCC ya guncan de) were guheztin.

Di dawiyê de, pinên di moda derketinê de jî leza demjimêrê heye. Ev taybetmendiyek din a teserûfa enerjiyê ye; di doza me de, em tenê wê herî zêde destnîşan dikin û wê ji bîr dikin.

Ji ber vê yekê: em SPI bikar tînin, ku tê vê wateyê ku du pin (bi daneyan û bi îşaretek demjimêrê) divê "fonksiyona push-kêşanê ya alternatîf", û yeka din (LAT) divê "push-kişandina birêkûpêk" be. Lê berî ku wan tayin bikin, em bi SPI re mijûl bibin.

SPI

Bernameyek perwerdehiya piçûk a din

SPI an Navbera Peripheral ya Serî (navbera dorhêl a serial) ji bo girêdana MK bi MK-yên din û bi gelemperî cîhana derve re navgînek hêsan û pir bi bandor e. Prensîba xebata wê jixwe li jor hatîye diyar kirin, li ku derê di derbarê ajokera LED-a Chineseînî de (di manuala referansê de, li beşa 25 binêre). SPI dikare di moda master ("master") û xulam ("xulam") de bixebite. SPI çar kanalên bingehîn hene, ku ne hemî dikarin bêne bikar anîn:

  • MOSI, Derketina Master / Ketina Slave: ev pin di moda masterê de daneyan dişîne, û di moda xulam de daneyan distîne;
  • MISO, Ketina Mamoste / Derketina Slave: Berevajî vê, ew di master de distîne, û di xulamê de vediguhezîne;
  • SCK, Saeta Serial: Frekansa veguheztina daneyê di master de destnîşan dike an di xulamê de îşaretek demjimêrê distîne. Esas lêxistina lêdan;
  • SS, Slave Select: bi alîkariya vê kanalê, xulam dizane ku tiştek ji wî tê xwestin. Li ser STM32 jê re NSS tê gotin, ku N = neyînî, yanî. ger di vê kanalê de zemîn hebe kontrolkar dibe kole. Ew bi moda Outputê ya Open Drain re baş tevdigere, lê ew çîrokek din e.

Mîna her tiştê din, SPI li ser STM32 ji hêla fonksiyonê ve dewlemend e, ku fêmkirina wê hinekî dijwar dike. Mînakî, ew dikare ne tenê bi SPI, lê di heman demê de bi navgînek I2S-ê re jî bixebite, û di belgeyê de raveyên wan tevlihev in, pêdivî ye ku meriv zêde di wextê xwe de qut bike. Karê me pir hêsan e: em tenê hewce ne ku daneyan bi tenê MOSI û SCK bikar bînin. Em diçin beşa 25.3.4 (ragihandina nîv-duplex, pêwendiya nîv-duplex), li wir em dibînin 1 saet û 1 têl daneya yekalî (1 sînyala saetê û 1 herikîna daneya yekalî):

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Di vê modê de, serîlêdan SPI-ê di moda tenê veguheztinê an jî tenê wergirtinê de bikar tîne. / Moda tenê veguheztinê dişibe moda dupleksê: Daneyên li ser pîneya veguheztinê (MOSI di moda master de an MISO di moda koledar de) têne şandin, û pina wergirtinê (bi rêzê ve MISO an MOSI) dikare wekî pinek I/O ya birêkûpêk were bikar anîn. . Di vê rewşê de, serîlêdan tenê hewce dike ku tampona Rx paşguh bike (heke ew were xwendin, dê li wir daneya veguheztin tune).

Baş e, pînê MISO belaş e, bila em sînyala LAT pê ve girêbidin. Ka em li Slave Select binêrin, ku li ser STM32 dikare bi bernamekî were kontrol kirin, ku pir hêsan e. Em di beşa 25.3.1 Danasîna Giştî ya SPI de paragrafa bi heman navî dixwînin:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Kontrola nermalavê NSS (SSM = 1) / Agahdariya hilbijartina xulamê di bit SSI ya qeyda SPI_CR1 de heye. Pîneya NSS ya derveyî ji bo hewcedariyên serîlêdanê yên din belaş dimîne.

Dem dema nivîsandina qeydan e. Min biryar da ku SPI2 bikar bînim, li navnîşana wê ya bingehîn di pelgeyê de bigerim - di beşa 3.3 Nexşeya Bîrê de:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8

Erê, em dest pê bikin:

#define _SPI2_(mem_offset) (*(volatile uint32_t *)(0x40003800 + (mem_offset)))

Beşa 25.3.3 bi sernavê xwe-ravekirî "Mîhengkirina SPI di Moda Mamoste de" vekin:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8

1. Di qeyda SPI_CR2 de frekansa demjimêra rêzefîlmê bi bitsên BR[0:1] saz bikin.

Qeyd di beşa manuala referansê ya bi heman navî de têne berhev kirin. Guhertina navnîşan (Navnîşan jihevkirî) ji bo CR1 - 0x00, ji hêla xwerû ve hemî bit têne paqij kirin (Reset nirx 0x0000):

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8

Biteyên BR dabeşkera demjimêra kontrolker destnîşan dikin, bi vî rengî frekansa ku dê SPI tê de bixebite destnîşan dikin. Frekansa meya STM32 dê 72 MHz be, ajokera LED-ê, li gorî daneya wê, bi frekansa heya 25 MHz kar dike, ji ber vê yekê divê em bi çar (BR[2:0] = 001) dabeş bikin.

#define _SPI_CR1 0x00

#define BR_0        0x0008
#define BR_1        0x0010
#define BR_2        0x0020

_SPI2_ (_SPI_CR1) |= BR_0;// pclk/4

2. Bitikên CPOL û CPHA bicîh bikin da ku têkiliya di navbera veguheztina daneyê û dema demjimêra rêzefîlmê de diyar bikin (li diagrama rûpel 240 binêre)

Ji ber ku em li vir danehevek dixwînin û li şematîkan nanihêrin, werin em ji nêz ve li danasîna nivîsê ya bitên CPOL û CPHA yên li ser rûpela 704-ê binihêrin (Daneya Giştî ya SPI):

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Qonaxa saetê û polarîte
Bi karanîna bitsên CPOL û CPHA yên qeyda SPI_CR1, hûn dikarin bi bernameyî çar têkiliyên demê hilbijêrin. Bit CPOL (polarîteya demjimêrê) rewşa sînyala demjimêrê dema ku ti dane neyên şandin kontrol dike. Ev bit modên master û xulamê kontrol dike. Ger CPOL ji nû ve were vegerandin, pînê SCK di moda bêhnvedanê de kêm e. Ger bit CPOL were danîn, di moda bêhnvedanê de pînê SCK bilind e.
Dema ku bit CPHA (qonaxa demjimêrê) tê danîn, stroba xefika bit ya bilind qeraxa duyemîn a sînyala SCK ye (ger CPOL zelal be dikeve, ger CPOL were danîn bilind dibe). Daneyên bi guherîna duyemîn a sînyala demjimêrê ve têne girtin. Ger bit CPHA zelal be, stroba xefika bit-a bilind qeraxa bilindbûna sînyala SCK ye (heke CPOL were saz kirin keviya davêje, ger CPOL were paqij kirin keviya bilindbûnê ye). Daneyên di yekem guherîna sînyala demjimêrê de têne girtin.

Piştî ku em vê zanînê hildan, em gihîştin vê encamê ku divê her du bit sifir bimînin, ji ber Em dixwazin ku sînyala SCK dema ku neyê bikar anîn kêm bimîne, û dane li ser keviya bilindbûna pêlê were şandin (binêre Fig. Rising Edge di daneya DM634 de).

Bi awayê, li vir me pêşî rastî taybetmendiyek peyvsaziyê di pelên daneyên ST-yê de hat: di wan de hevoka "bitikê vegerîne sifirê" hatiye nivîsandin. ji bo reset hinekîû ne hinekî paqij kirin, wek nimûne, Atmega.

3. Bit DFF-ê bicîh bikin ku hûn diyar bikin ka bloka daneyê 8-bit an 16-bit e

Min bi taybetî DM16 634-bit girt da ku ez bi veguheztina daneyên PWM-ya 12-bit, mîna DM633, aciz nebim. Wateya wê ye ku meriv DFF-ê wekî yek saz bike:

#define DFF         0x0800

_SPI2_ (_SPI_CR1) |= DFF; // 16-bit mode

4. Di qeyda SPI_CR1 de bit LSBFIRST mîheng bike da ku formata blokê diyar bike

LSBFIRST, wekî ku navê wê diyar dike, pêşî bi bîta herî kêm girîng veguheztinê mîheng dike. Lê DM634 dixwaze ku daneyan ji bîta herî girîng dest pê bike. Ji ber vê yekê, em wê ji nû ve bihêlin.

5. Di moda hardware de, heke têketina ji pînê NSS-ê hewce be, di tevahiya rêzika veguheztina byte de îşaretek bilind li pina NSS-ê bicîh bikin. Di moda nermalava NSS de, bitên SSM û SSI di qeyda SPI_CR1 de bicîh bikin. Ger pin NSS-ê wekî encamek were bikar anîn, tenê pêdivî ye ku bit SSOE were danîn.

SSM û SSI saz bikin da ku moda hardware ya NSS-ê ji bîr bikin:

#define SSI         0x0100
#define SSM         0x0200

_SPI2_ (_SPI_CR1) |= SSM | SSI; //enable software control of SS, SS high

6. Divê bitsên MSTR û SPE bêne danîn (ew tenê ger sînyala NSSyê bilind be sazkirî dimînin)

Bi rastî, bi van bittan em SPI-ya xwe wekî master destnîşan dikin û vedikin:

#define MSTR        0x0004
#define SPE         0x0040

_SPI2_ (_SPI_CR1) |= MSTR; //SPI master
//когда все готово, включаем SPI
_SPI2_ (_SPI_CR1) |= SPE;

SPI hatiye mîheng kirin, ka em tavilê fonksiyonên ku bytes ji ajokerê re dişînin binivîsin. Xwendina 25.3.3 bidomînin "Mîhengkirina SPI di moda sereke de":

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Fermana veguhestina daneyan
Veguhastina dest pê dike dema ku byte li tampona Tx tê nivîsandin.
Byte daneyan di qeyda veguheztinê de tê barkirin dûberîn moda (ji otobusa hundurîn) di dema veguheztina bita yekem de, piştî ku ew tê veguheztin rêzdar Moda pinê ya MOSI, bitka yekem an ya paşîn li pêş ve girêdayî li gorî mîhengê bit LSBFIRST di qeyda CPI_CR1 de. Ala TXE piştî veguhestina daneyê tê danîn ji tampona Tx-ê heya qeyda veguherînê, û her weha navberek çêdike heke bit TXEIE di qeyda CPI_CR1 de were danîn.

Min di wergerê de çend peyvan ronî kir da ku balê bikişînim ser yek taybetmendiyek pêkanîna SPI-yê di kontrolkerên STM de. Li ser Atmega ala TXE (Tx Empty, Tx vala ye û ji bo wergirtina daneyan amade ye) tenê piştî ku tevahiya byte hate şandin tê danîn ji derve. Û li vir ev ala piştî ku byte di qeyda veguheztina hundurîn de hate danîn tê danîn. Ji ber ku ew bi hemî bîtan re di heman demê de (parallel) li wir tê dehf kirin, û dûv re danehev bi rêz têne veguheztin, TXE berî ku byte bi tevahî were şandin tê danîn. Ev girîng e ji ber ku di doza ajokera meya LED-ê de, pêdivî ye ku em pînê LAT piştî şandinê bikişînin всех dane, yanî. Tenê ala TXE têra me nake.

Ev tê wê wateyê ku pêwîstiya me bi aleke din heye. Ka em li 25.3.7 binêrin - "Alayên Rewşê":

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
<…>
Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
ala BUSY
Ala BSY ji hêla hardware ve hatî danîn û paqij kirin (nivîsandina wê ti bandorek nîne). Ala BSY rewşa qata ragihandinê ya SPI destnîşan dike.
Ew ji nû ve vedike:
gava veguheztin qediya (ji bilî di moda masterê de heke veguheztin berdewam be)
dema ku SPI neçalak e
gava ku xeletiyek moda sereke çêdibe (MODF=1)
Ger veguheztin ne berdewam be, ala BSY di navbera her veguheztina daneyê de tê paqij kirin

Okay, ev dê bi kêr were. Ka em fêr bibin ka tampona Tx li ku ye. Ji bo vê yekê, "Qeyda Daneyên SPI" bixwînin:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Bit 15:0 DR[15:0] Qeyda daneyan
Daneyên hatine wergirtin an daneyên ku werin veguheztin.
Tomara daneyê li du tamponan tê dabeş kirin - yek ji bo nivîsandinê (tampona veguheztinê) û yek jî ji bo xwendinê (tampona wergirtinê). Nivîsandina qeyda daneyê li tampona Tx dinivîse, û xwendina ji qeyda daneyê dê nirxa ku di tampona Rx de heye vegerîne.

Welê, û qeyda statûyê, ku alayên TXE û BSY têne dîtin:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8

Em dinivîsin:

#define _SPI_DR  0x0C
#define _SPI_SR  0x08

#define BSY         0x0080
#define TXE         0x0002

void dm_shift16(uint16_t value)
{
    _SPI2_(_SPI_DR) = value; //send 2 bytes
    while (!(_SPI2_(_SPI_SR) & TXE)); //wait until they're sent
}

Welê, ji ber ku em hewce ne ku 16 carî du byte, li gorî hejmara derhênerên ajokerê LED-ê, tiştek bi vî rengî veguhezînin:

void sendLEDdata()
{
    LAT_low();
    uint8_t k = 16;
    do
    {   k--;
        dm_shift16(leds[k]);
    } while (k);

    while (_SPI2_(_SPI_SR) & BSY); // finish transmission

    LAT_pulse();
}

Lê em hîn nizanin ka meriv pînê LAT-ê çawa bikişîne, ji ber vê yekê em ê vegerin I/O.

Destnîşankirina pîneyan

Di STM32F1 de, qeydên berpirsiyar ên rewşa pîneyan pir ne asayî ne. Eşkere ye ku ji Atmega bêtir ji wan hene, lê ew ji çîpên STM yên din jî cûda ne. Beş 9.1 Danasîna Giştî ya GPIO:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Her yek ji portên I/O yên armanca giştî (GPIO) du qeydên vesazkirinê yên 32-bit hene (GPIOx_CRL û GPIOx_CRH), du tomarên daneya 32-bit (GPIOx_IDR û GPIOx_ODR), qeydek 32-bit set/reset (GPIOx_BSRR), qeydek vesazkirina 16-bit (GPIOx_BRR) û qeyda astengkirina bit (GPIOx_LCKR).

Du tomarên yekem ne asayî ne, û di heman demê de pir nerehet in, ji ber ku 16 pinên portê di forma "çar bit her bira" de li ser wan têne belav kirin. Ewan. pîneyên sifir heta heftan di CRL de ne, û yên mayî di CRH de ne. Di heman demê de, tomarên mayî bi serfirazî bitikên hemî pîneyên portê dihewîne - bi gelemperî nîv "veşartî" dimînin.

Ji bo sadebûnê, em ji dawiya navnîşê dest pê bikin.

Pêdiviya me bi qeydek astengkirinê nîne.

Qeydên danîn û vesazkirinê pir bikêr in ku ew bi qismî hevdu dubare dikin: hûn dikarin her tiştî tenê di BSRR-ê de binivîsin, ku 16 bitên bilind dê pînê vegerînin sifir, û yên jêrîn dê li 1-ê bêne danîn, an jî hûn dikarin BRR-ê bikar bînin, 16 bitên jêrîn ên ku tenê pinê ji nû ve saz bikin. Ez ji vebijarka duyemîn hez dikim. Van qeydan girîng in ji ber ku ew gihîştina atomî ji pinan re peyda dikin:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Set Atomî an Reset
Dema ku GPIOx_ODR di asta bit de bername dike ne hewce ye ku qutbûnên neçalak bikin: yek an çend bit dikarin bi yek operasyona nivîsandina atomê APB2 ve werin guheztin. Ev bi nivîsandina "1" li ser qeyda danîn/vesazkirin (GPIOx_BSRR an, tenê ji bo vesazkirinê, GPIOx_BRR) ya bit-a ku divê were guheztin tê bidestxistin. Bîstikên din dê neguherî bimînin.

Tomarên daneyan navên pir xwe-ravekirî hene - IDR = Beyan Tomarkirina rênîşandanê, qeyda têketinê; ODR = Karûabr Qeyda derhêneriyê, qeyda deranê. Di projeya heyî de em ê hewce nebin.

Û di dawiyê de, qeydên kontrolê. Ji ber ku em bi pîneyên SPI-ya duyemîn, ango PB13, PB14 û PB15 re eleqedar dibin, em tavilê li CRH dinêrin:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8

Û em dibînin ku em ê hewce bikin ku ji 20 heta 31-an tiştek bi bit binivîsin.

Me berê li jor fêhm kir ku em ji pîneyan çi dixwazin, ji ber vê yekê li vir ez ê bêyî dîmenek dîmenê bikim, ez ê tenê bibêjim ku MODE rêgezê diyar dike (heke her du bit li ser 0-ê hatine danîn) û leza pînê (pêdiviya me bi 50 MHz heye, yanî. hem pîne li "1"), hem jî CNF modê destnîşan dike: birêkûpêk "push-kişandin" - 00, "alternatîf" - 10. Wekî xwerû, wekî ku em li jor jî dibînin, hemî pîneyan bit-a sêyemîn ji binî (CNF0) heye. ew wan dixe modê ketina herikîn.

Ji ber ku ez plan dikim ku bi vê çîpê tiştek din bikim, ji bo sadebûnê min hem ji bo qeydên kontrolê yên jêrîn û hem jî yên jorîn hemî nirxên gengaz ên MODE û CNF diyar kiriye.

Hinekî bi vî rengî

#define CNF0_0 0x00000004
#define CNF0_1 0x00000008
#define CNF1_0 0x00000040
#define CNF1_1 0x00000080
#define CNF2_0 0x00000400
#define CNF2_1 0x00000800
#define CNF3_0 0x00004000
#define CNF3_1 0x00008000
#define CNF4_0 0x00040000
#define CNF4_1 0x00080000
#define CNF5_0 0x00400000
#define CNF5_1 0x00800000
#define CNF6_0 0x04000000
#define CNF6_1 0x08000000
#define CNF7_0 0x40000000
#define CNF7_1 0x80000000
#define CNF8_0 0x00000004
#define CNF8_1 0x00000008
#define CNF9_0 0x00000040
#define CNF9_1 0x00000080
#define CNF10_0 0x00000400
#define CNF10_1 0x00000800
#define CNF11_0 0x00004000
#define CNF11_1 0x00008000
#define CNF12_0 0x00040000
#define CNF12_1 0x00080000
#define CNF13_0 0x00400000
#define CNF13_1 0x00800000
#define CNF14_0 0x04000000
#define CNF14_1 0x08000000
#define CNF15_0 0x40000000
#define CNF15_1 0x80000000

#define MODE0_0 0x00000001
#define MODE0_1 0x00000002
#define MODE1_0 0x00000010
#define MODE1_1 0x00000020
#define MODE2_0 0x00000100
#define MODE2_1 0x00000200
#define MODE3_0 0x00001000
#define MODE3_1 0x00002000
#define MODE4_0 0x00010000
#define MODE4_1 0x00020000
#define MODE5_0 0x00100000
#define MODE5_1 0x00200000
#define MODE6_0 0x01000000
#define MODE6_1 0x02000000
#define MODE7_0 0x10000000
#define MODE7_1 0x20000000
#define MODE8_0 0x00000001
#define MODE8_1 0x00000002
#define MODE9_0 0x00000010
#define MODE9_1 0x00000020
#define MODE10_0 0x00000100
#define MODE10_1 0x00000200
#define MODE11_0 0x00001000
#define MODE11_1 0x00002000
#define MODE12_0 0x00010000
#define MODE12_1 0x00020000
#define MODE13_0 0x00100000
#define MODE13_1 0x00200000
#define MODE14_0 0x01000000
#define MODE14_1 0x02000000
#define MODE15_0 0x10000000
#define MODE15_1 0x20000000

Pînên me li ser porta B (navnîşana bingehîn - 0x40010C00), kod:

#define _PORTB_(mem_offset) (*(volatile uint32_t *)(0x40010C00 + (mem_offset)))

#define _BRR  0x14
#define _BSRR 0x10
#define _CRL  0x00
#define _CRH  0x04

//используем стандартный SPI2: MOSI на B15, CLK на B13
//LAT пусть будет на неиспользуемом MISO – B14

//очищаем дефолтный бит, он нам точно не нужен
_PORTB_ (_CRH) &= ~(CNF15_0 | CNF14_0 | CNF13_0 | CNF12_0);

//альтернативные функции для MOSI и SCK
_PORTB_ (_CRH) |= CNF15_1 | CNF13_1;

//50 МГц, MODE = 11
_PORTB_ (_CRH) |= MODE15_1 | MODE15_0 | MODE14_1 | MODE14_0 | MODE13_1 | MODE13_0;

Û, li gorî vê yekê, hûn dikarin ji bo LAT-ê pênase binivîsin, ku dê ji hêla qeydên BRR û BSRR ve werin kişandin:

/*** LAT pulse – high, then low */
#define LAT_pulse() _PORTB_(_BSRR) = (1<<14); _PORTB_(_BRR) = (1<<14)

#define LAT_low() _PORTB_(_BRR) = (1<<14)

(LAT_low tenê ji hêla bêhêziyê ve, her gav wusa bû, bila bimîne)

Niha her tişt baş e, lê ew ne kar dike. Ji ber ku ev STM32 e, ew elektrîkê teserûf dikin, ku tê vê wateyê ku hûn hewce ne ku demjimêra dorhêlên pêwîst çalak bikin.

Saetê vekin

Saet, ku jê re Saet jî tê zanîn, berpirsiyariya demjimêrê ye. Û me ji berê ve dikaribû kurteya RCC-ê bibînin. Em di belgeyê de lê digerin: ev Reset û Kontrola Saetê ye.

Wekî ku li jor hate gotin, bi bextewarî, beşa herî dijwar a mijara demjimêrê ji hêla kesên STM ve ji bo me hate kirin, ji bo vê yekê em gelek spasiya wan dikin (carek din ez ê lînkê bidim Malpera Di Halt, da ku diyar bike ka ew çiqas tevlihev e). Ji me re tenê qeydên ku ji bo çalakkirina demjimêra dorhêlê berpirsiyar in hewce ne (Saeta Peripheral Enable Registers). Pêşîn, em navnîşana bingehîn a RCC-ê bibînin, ew di destpêka "Nexşeya Bîrê" de ye:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8

#define _RCC_(mem_offset) (*(volatile uint32_t *)(0x40021000 + (mem_offset)))

Û dûv re an li ser zencîreya ku hûn hewl didin ku tiştek di plakê de bibînin, bikirtînin, an jî, pir çêtir, li ravekirinên qeydên çalak ên ji beşên di derbarê qeydan çalak bike. Li ku derê em ê RCC_APB1ENR û RCC_APB2ENR bibînin:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8

Û ew, bi vî rengî, bit hene ku demjimêra SPI2, IOPB (I/O Port B) û fonksiyonên alternatîf (AFIO) vedigirin.

#define _APB2ENR 0x18
#define _APB1ENR 0x1C

#define IOPBEN 0x0008
#define SPI2EN 0x4000
#define AFIOEN 0x0001

//включаем тактирование порта B и альт. функций
_RCC_(_APB2ENR) |= IOPBEN | AFIOEN;

//включаем  тактирование SPI2
_RCC_(_APB1ENR) |= SPI2EN;

Koda dawî dikare were dîtin vir.

Ger derfet û daxwaza we ya ceribandinê heye, wê hingê DM634 bi vî rengî ve girêdin: DAI bi PB15, DCK bi PB13, LAT bi PB14. Em ajokerê ji 5 voltan hêz dikin, ji bîr nekin ku zemînan girêdin.

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8

STM8 PWM

PWM li ser STM8

Gava ku min tenê vê gotarê plan dikir, min biryar da, wekî mînak, ez hewl bidim ku hin fonksiyonên çîpek nenas bi tenê pelgeyek daneyê serwer bikim, da ku ez neçim pêlavvanek bê pêlav. STM8 ji bo vê rolê îdeal bû: Ya yekem, min çend tabloyên çînî bi STM8S103 re hebûn, û ya duyemîn jî, ew ne pir populer e, û ji ber vê yekê ceribandina xwendin û dîtina çareseriyek li ser Înternetê li ser nebûna van çareseriyan dimîne.

Çîp jî heye datasheet и referansa manual RM0016, di ya yekem de navnîşanên pinout û qeydkirinê hene, di ya duyemîn de - her tiştê din. STM8 di C-ê de di IDE-ya tirsnak de bernamekirî ye ST Visual Develop.

Saetkirin û I/O

Bi xwerû, STM8 bi frekansa 2 MHz dixebite, divê ev tavilê were rast kirin.

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Saeta HSI (Lezbûna Bilind a Navxweyî).
Nîşana demjimêra HSI ji oscilatorek hundurîn a RC ya 16 MHz bi dabeşkerek bernamekirî (1 heta 8) tête peyda kirin. Ew di qeyda dabeşkera demjimêrê (CLK_CKDIVR) de hatî danîn.
Nîşe: di destpêkê de, oscilatorek HSI RC bi dabeşkerek 8 wekî çavkaniya sereke ya sînyala demjimêrê tê hilbijartin.

Em navnîşana qeydê di datasheet de, şiroveya di refman de dibînin û dibînin ku pêdivî ye ku qeyd were paqij kirin:

#define CLK_CKDIVR *(volatile uint8_t *)0x0050C6

CLK_CKDIVR &= ~(0x18);

Ji ber ku em ê PWM-ê bimeşînin û LED-an ve girêbidin, em li pinoutê binêrin:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8

Çîp piçûk e, gelek fonksiyon li ser heman pinan têne sekinandin. Tiştê ku di kemberên çargoşe de ye "fonksiyona alternatîf" e, ew ji hêla "bytes vebijarkî" ve tê guheztin (bytes option) - tiştek wekî Atmega sîgorteyan. Hûn dikarin nirxên wan bi bername biguherînin, lê ew ne hewce ye, ji ber ku Karbidestiya nû tenê piştî nûvekirinê tê çalak kirin. Bikaranîna ST Visual Programmer (bi Visual Develop ve hatî dakêşandin) hêsantir e, ku dikare van bytes biguhezîne. Pîneyê nîşan dide ku pîneyên CH1 û CH2 yên demjimêra yekem di nav çeperên çargoşe de veşartî ne; Pêdivî ye ku di STVP-ê de bit AFR1 û AFR0 were danîn, û ya duyemîn jî dê derketina CH1 ya demjimêra duyemîn ji PD4 veguhezîne PC5.

Bi vî rengî, 6 pin dê LED-an kontrol bikin: PC6, PC7 û PC3 ji bo demjimêra yekem, PC5, PD3 û PA3 ji bo ya duyemîn.

Sazkirina pîneyên I/O bi xwe li ser STM8 ji ya STM32 sadetir û mentiqîtir e:

  • ji qeyda rêberiya daneya Atmega DDR naskirî (Data Direction Register): 1 = encam;
  • qeyda kontrolê ya yekem CR1, dema ku derdikeve, moda pêlkêş-kişandinê (1) an rijandina vekirî (0) saz dike; ji ber ku ez LED-an bi katodan bi çîpê ve girêdidim, ez li vir sifiran dihêlim;
  • qeyda kontrolê ya duyemîn CR2, dema derdikeve, leza demjimêrê destnîşan dike: 1 = 10 MHz

#define PA_DDR     *(volatile uint8_t *)0x005002
#define PA_CR2     *(volatile uint8_t *)0x005004
#define PD_DDR     *(volatile uint8_t *)0x005011
#define PD_CR2     *(volatile uint8_t *)0x005013
#define PC_DDR     *(volatile uint8_t *)0x00500C
#define PC_CR2     *(volatile uint8_t *)0x00500E

PA_DDR = (1<<3); //output
PA_CR2 |= (1<<3); //fast
PD_DDR = (1<<3); //output
PD_CR2 |= (1<<3); //fast
PC_DDR = ((1<<3) | (1<<5) | (1<<6) | (1<<7)); //output
PC_CR2 |= ((1<<3) | (1<<5) | (1<<6) | (1<<7)); //fast

mîhengê PWM

Pêşîn, em şertan diyar bikin:

  • Frequency PWM - frekansa ku bi demjimêrê ve girêdayî ye;
  • Vebarkirina otomatîkî, AR - nirxa xwebarkirî heya ku demjimêr dê bihejmêre (serdema pêlê);
  • Bûyer nûve bike, UEV - Bûyerek ku diqewime dema ku demjimêr li AR jimartin;
  • PWM Duty Cycle - çerxa peywira PWM, ku pir caran jê re "faktora peywirê" tê gotin;
  • Nirx girtin / Berawirdkirin - nirxa ji bo girtina/berhevberdanê, ya ku demjimar jê re jimartin dê tiştekî bike (di doza PWM de, ew sînyala derketinê berovajî dike);
  • Nirxa Preload - nirxa berê barkirî. Nirx bidin hev Dema ku demjimêr dihejîne nikare biguhezîne, wekî din çerxa PWM dê bişkê. Ji ber vê yekê, nirxên nû yên hatine veguheztin di tamponek de têne danîn û dema ku demjimêr digihîje dawiya hejmartina xwe û ji nû ve tê derxistin;
  • Edge-aligned и Modên navend-aligned - lihevhatina li ser sînor û li navendê, wekî ya Atmel PWM zû и Qonaxa-rast PWM.
  • OCiREF, Nîşaneya Referansa Berhevberdana Derketî - sînyala derana referansê, bi rastî, tiştê ku di moda PWM de li ser pina têkildar xuya dike.

Wekî ku ji pinoutê jixwe diyar e, du demjimêr xwedan kapasîteyên PWM hene - ya yekem û ya duyemîn. Her du jî 16-bit in, ya yekem xwedan gelek taybetmendiyên zêde ye (bi taybetî, ew dikare hem jor û hem jî jêrîn bijmêre). Pêdivî ye ku em her du jî wekhev bixebitin, ji ber vê yekê min biryar da ku ez bi ya duyemîn xizantir dest pê bikim, da ku bi xeletî tiştek ku li wir tune bikar nekim. Hin pirsgirêk ev e ku ravekirina fonksiyona PWM ya hemî demjimêran di manuala referansê de di beşa derbarê demjimêra yekem de (17.5.7 Moda PWM) de ye, ji ber vê yekê hûn neçar in ku her dem li seranserê belgeyê paş û paş ve bizivirin.

PWM li ser STM8 li ser PWM li Atmega xwedan avantajek girîng e:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Boundary Aligned PWM
Veavakirina hesabê ji jêr berbi jor
Ger bit-a DIR-ê di qeyda TIM_CR1 de were paqij kirin jimartina jêrîn çalak e
Nimûne:
Mînak moda yekem a PWM bikar tîne. Nîşana referansa PWM OCiREF heya ku TIM1_CNT < TIM1_CCRi bilind tê girtin. Wekî din ew astek nizm digire. Ger nirxa berhevdanê di qeyda TIM1_CCRi de ji nirxa barkirina otomatîkî (qeyda TIM1_ARR) mezintir be, nîşana OCiREF li 1-ê tê girtin. Ger nirxa berhevdanê 0 be, OCiREF li sifir tê girtin....

timer STM8 di dema bûyera nûvekirinê pêşî kontrol dike nirx bidin hev, û tenê hingê nîşanek referansê çêdike. Demjimêra Atmega pêşî dişewitîne û dûv re berhev dike, di encamê de compare value == 0 derziyek derziyek e, ku divê bi rengekî jê re were girtin (mînak, bi bernamegerîkirina mantiqê).

Ji ber vê yekê tiştê ku em dixwazin bikin: 8-bit PWM (AR == 255), ji binî ber bi jor ve jimartin, lihevhatina li ser sînor. Ji ber ku ampûlên ronahiyê bi katodan bi çîpê ve girêdayî ne, divê PWM 0 (LED li ser) derxe heya ku nirx bidin hev û 1 piştî.

Me berê li ser hinekan xwendiye Moda PWM, ji ber vê yekê em bi lêgerîna di manuala referansê de ji bo vê hevokê (18.6.8 - TIMx_CCMR1) qeyda pêdivî ya demjimêra duyemîn peyda dikin:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
110: Moda PWM ya yekem - dema ku ji binî ber bi jor ve tê hejmartin, kanala yekem çalak e dema TIMx_CNT < TIMx_CCR1. Wekî din, kanala yekem neçalak e. [bêtir di belgeyê de ji demjimêra 1-ê kopî-pasteyek xelet heye] 111: Moda PWM ya duyemîn - dema ji binî ber bi jor ve tê hejmartin, kanala yekem neçalak e dema TIMx_CNT < TIMx_CCR1. Wekî din, kanala yekem çalak e.

Ji ber ku LED bi katodan bi MK-ê ve girêdayî ne, moda duyemîn li gorî me ye (ya yekem jî, lê em hîna wiya nizanin).

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Bit 3 OC1PE: Pîneya 1-a pêşbarkirî çalak bike
0: Qeyda berî barkirina li ser TIMx_CCR1 neçalak e. Hûn dikarin her dem ji TIMx_CCR1 re binivîsin. Nirxa nû yekser dixebite.
1: Tomara pêşbarkirina li ser TIMx_CCR1 çalak e. Operasyonên xwendin/nivîsandinê bigihînin qeyda pêşbarkirinê. Nirxa pêş-barkirî TIMx_CCR1 di dema her bûyerek nûvekirinê de di qeyda siyê de tê barkirin.
* Nîşe: Ji bo ku moda PWM bi rêkûpêk bixebite, divê qeydên pêşbarkirî werin çalak kirin. Ev di moda sînyala yekane de ne hewce ye (bit OPM di qeyda TIMx_CR1 de hatî danîn).

Baş e, em her tiştê ku ji bo sê kanalên demjimêra duyemîn hewce ne vekin:

#define TIM2_CCMR1 *(volatile uint8_t *)0x005307
#define TIM2_CCMR2 *(volatile uint8_t *)0x005308
#define TIM2_CCMR3 *(volatile uint8_t *)0x005309

#define PWM_MODE2   0x70 //PWM mode 2, 0b01110000
#define OCxPE       0x08 //preload enable

TIM2_CCMR1 = (PWM_MODE2 | OCxPE);
TIM2_CCMR2 = (PWM_MODE2 | OCxPE);
TIM2_CCMR3 = (PWM_MODE2 | OCxPE);

AR ji du qeydên heşt-bit pêk tê, her tişt hêsan e:

#define TIM2_ARRH  *(volatile uint8_t *)0x00530F
#define TIM2_ARRL  *(volatile uint8_t *)0x005310

TIM2_ARRH = 0;
TIM2_ARRL = 255;

Demjimêra duyemîn tenê dikare ji binî ber bi jor ve bijmêre, lihevhatina li ser sînor, ne hewce ye ku tiştek were guheztin. Werin em dabeşkera frekansê, mînakî, bikin 256. Ji bo demjimêra duyemîn, dabeşker di qeyda TIM2_PSCR de tête danîn û hêzek du ye:

#define TIM2_PSCR  *(volatile uint8_t *)0x00530E

TIM2_PSCR = 8;

Tiştê ku dimîne ev e ku meriv encaman û demjimêra duyemîn bixwe vegerîne. Pirsgirêka yekem bi qeydan çareser dibe Girtin / Berawirdkirin Bikêrkirin: du, sê kanal hene ku bi awayekî asimetrîk li ser wan belav bûne. Li vir em dikarin her weha fêr bibin ku gengaz e ku meriv polarîteya sînyalê biguhezîne, yanî. di prensîbê de, gengaz bû ku moda PWM 1 bikar bînin. Em dinivîsin:

#define TIM2_CCER1 *(volatile uint8_t *)0x00530A
#define TIM2_CCER2 *(volatile uint8_t *)0x00530B

#define CC1E  (1<<0) // CCER1
#define CC2E  (1<<4) // CCER1
#define CC3E  (1<<0) // CCER2

TIM2_CCER1 = (CC1E | CC2E);
TIM2_CCER2 = CC3E;

Û di dawiyê de, em demjimêra di qeyda TIMx_CR1 de dest pê dikin:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8

#define TIM2_CR1   *(volatile uint8_t *)0x005300

TIM2_CR1 |= 1;

Ka em analogek hêsan a AnalogWrite() binivîsin, ku dê ji bo berhevdanê nirxên rastîn veguhezîne demjimêrê. Tomar bi pêşbînî têne nav kirin Qeydên girtin / Compare, ji bo her kanalekê du ji wan hene: 8 bit-ên nizm di TIM2_CCRxL de û yên rêza bilind di TIM2_CCRxH de. Ji ber ku me PWM-ya 8-bit çêkiriye, bes e ku meriv tenê bitikên herî kêm girîng binivîsîne:

#define TIM2_CCR1L *(volatile uint8_t *)0x005312
#define TIM2_CCR2L *(volatile uint8_t *)0x005314
#define TIM2_CCR3L *(volatile uint8_t *)0x005316

void setRGBled(uint8_t r, uint8_t g, uint8_t b)
{
    TIM2_CCR1L = r;
    TIM2_CCR2L = g;
    TIM2_CCR3L = b;
}

Xwendevanê baldar dê bala xwe bide ku me PWMek piçek xelet heye, ku nekare% 100 dagirtin hilberîne (bi nirxek herî zêde 255, îşaret ji bo yek çerxa demjimêrê vedigere). Ji bo LED-an ev ne girîng e, û xwendevanê baldar jixwe dikare texmîn bike ka meriv wê çawa rast bike.

PWM li ser demjimêra duyemîn dixebite, em biçin ya yekem.

Demjimêra yekem di heman tomaran de tam heman bit hene (tenê ew bit ku di demjimêra duyemîn de "veşartî" mane, di ya yekem de ji bo her cûre tiştên pêşkeftî bi rengek çalak têne bikar anîn). Ji ber vê yekê, bes e ku meriv navnîşanên heman qeydan di pelgeyê de bibîne û kodê kopî bike. Welê, nirxa dabeşkera frekansê biguhezînin, ji ber ku ... demjimêra yekem dixwaze di du qeydan de ne hêzek du, lê nirxek tam 16-bit bistîne. Prescaler High и Nizm. Em her tiştî dikin û ... demjimêra yekem kar nake. Babet çîye?

Pirsgirêk tenê bi lênihêrîna tevahiya beşê di derbarê tomarên kontrolê yên demjimêr 1-ê de, ku em li ya ku demjimêra duyemîn tine lê digerin, çareser dibe. Dê hebin 17.7.30 Qeyda veqetînê (TIM1_BKR), li ku derê ev bit heye:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Hilberîna sereke çalak bike

#define TIM1_BKR   *(volatile uint8_t *)0x00526D

TIM1_BKR = (1<<7);

Naha ew hemî bê guman e, kod va.

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8

STM8 Multiplex

Multiplexing li ser STM8

Minî-projeya sêyemîn ev e ku di moda PWM de heşt LED-yên RGB bi demjimêra duyemîn ve girêbide û wan rengên cihêreng nîşan bide. Ew li ser bingeha têgîna pirrengkirina LED-ê ye, ku ev e ku heke hûn LED-ê pir, pir zû vekin û vemirînin, ew ê ji me re xuya bibe ku ew bi berdewamî pêve ne (berdewamiya dîtinê, bêhêziya têgihîştina dîtbar). Min carekê kir tiştekî wiha li ser Arduino.

Algorîtmaya xebatê wiha xuya dike:

  • anode ya yekem RGB LED ve girêdayî ye;
  • ronî kir, îşaretên pêwîst ji katodan re dişîne;
  • li benda dawiya çerxa PWM sekinî;
  • anode ya duyemîn RGB LED ve girêdayî ye;
  • vêxist...

Belê, hwd. Bê guman, ji bo operasyona xweşik, pêdivî ye ku anode were girêdan û LED di heman demê de "şewitandin". Baş, an hema. Di her rewşê de, pêdivî ye ku em kodek binivîsin ku dê di sê kanalên demjimêra duyemîn de nirxan derxîne, dema ku UEV gihîştiye wan biguhezîne, û di heman demê de LED-ya RGB ya niha ya çalak biguhezîne.

Ji ber ku veguheztina LED-ê otomatîk e, pêdivî ye ku em "bîra vîdyoyê" biafirînin ku jêderê navberê dê daneyan werbigire. Ev rêzek hêsan e:

uint8_t colors[8][3];

Ji bo ku hûn rengê LED-ya taybetî biguhezînin, ew ê bes be ku meriv nirxên pêwîst di vê rêzê de binivîse. Û guherbar dê ji bo hejmara LED-a çalak berpirsiyar be

uint8_t cnt;

Demux

Ji bo pirrengkirina rast, pêdivî ye ku em, pir ecêb, demultiplexerek CD74HC238. Demultiplexer - çîpek ku operatorê di hardware de bicîh dike <<. Bi sê pîneyên têketinê (bitên 0, 1 û 2) em wê jimareyek sê-bit X dixwin, û di bersivê de ew jimareya derketinê çalak dike (1<<X). Kevirên mayî yên çîpê ji bo pîvandina tevahî sêwiranê têne bikar anîn. Em ji vê çîpê ne tenê ji bo kêmkirina hejmara pîneyên dagîrkirî yên mîkrokontroller, lê di heman demê de ji bo ewlehiyê jî hewce ne - da ku bi xeletî ji mimkun zêdetir LED-ê venekin û MK-ê neşewitînin. Çîp quncikek lêçû û divê her gav di kabîneya dermanê weya malê de were girtin.

CD74HC238 me dê berpirsiyarê peydakirina voltaja li anodê ya LED-a xwestî be. Di multiplexek bêkêmasî de, ew ê voltaja stûnê bi P-MOSFET re peyda bike, lê di vê demoyê de ew rasterast gengaz e, ji ber ku ew 20 mA dikişîne, li gorî ratings herî zêde mutleq di datasheet de. Ji Daneyên CD74HC238 ji me re pinouts û ev pelika xapandinê hewce ne:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
H = asta voltaja bilind, L = asta voltaja nizm, X - xem neke

Em E2 û E1 bi erdê, E3, A0, A1 û A3 bi pinên PD5, PC3, PC4 û PC5 yên STM8 ve girêdidin. Ji ber ku tabloya li jor hem astên nizm û hem jî bilind dihewîne, em van pîneyan wekî pinên push-kêşanê mîheng dikin.

PWM

PWM li ser demjimêra duyemîn bi heman rengî wekî di çîroka berê de, bi du cûdahiyan ve hatî mîheng kirin:

Pêşîn, em hewce ne ku navberê li ser çalak bikin Bûyer nûve bike (UEV) ya ku dê fonksiyonek ku LED-ya çalak vedigire bang bike. Ev bi guhertina bit pêk tê Nûvekirina Navberê Çalak bike di qeydek bi navek diyar

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
Qeyda çalak bike

#define TIM2_IER   *(volatile uint8_t *)0x005303

//enable interrupt
TIM2_IER = 1;

Cûdahiya duyemîn bi fenomena piralîbûnê ve girêdayî ye, wekî rijandin - şewqa parazît a dîodan. Di rewşa me de, dibe ku ji ber vê yekê xuya bibe ku demjimêr, ku bûye sedema qutbûnek li ser UEV-ê, berdewam dike, û rêvekerê navberê wextê guheztina LED-ê tune berî ku demjimêr dest bi nivîsandina tiştek li ser pinan bike. Ji bo ku hûn li dijî vê yekê şer bikin, hûn ê neçar bin ku mantiqê berevajî bikin (0 = ronahiya herî zêde, 255 = tiştek ronî nabe) û ji nirxên çerxa karûbarê zehf dûr bixin. Ewan. piştrast bikin ku piştî UEV-ê LED ji bo yek çerxa PWM bi tevahî derdikevin.

Guhertina polarîteyê:

//set polarity 
    TIM2_CCER1 |= (CC1P | CC2P);
    TIM2_CCER2 |= CC3P;

Ji danîna r, g û b 255-an dûr bixin û ji bîr mekin ku gava wan bikar bînin wan berevajî bikin.

Dibire

Esasê qutbûnê ev e ku di bin hin mercan de çîp pêkanîna bernameya sereke rawestîne û hin fonksiyonên derveyî vedixwîne. Astengkirin ji ber bandorên derve an hundurîn, di nav de demjimêr, çêdibin.

Dema ku me yekem car di ST Visual Develop de projeyek çêkir, ji bilî main.c me pencereyek bi dosyayek razdar wergirt stm8_interrupt_vector.c, bixweber di projeyê de tête kirin. Di vê pelê de, ji her navberê re fonksiyonek tê destnîşankirin NonHandledInterrupt. Pêdivî ye ku em fonksiyona xwe bi qutbûna xwestinê ve girêbidin.

Danezana tabloyek vektorên navberê heye, li wir em yên ku hewce ne bibînin:

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8
13 TIM2 nûvekirin/herikîn
14 TIM2 girtin/berhevkirin

Pêdivî ye ku em LED-ê li UEV-ê biguhezînin, ji ber vê yekê em hewce ne ku #13 qut bikin.

Li gorî vê yekê, pêşî, di dosyayê de stm8_interrupt_vector.c navê xwerû yê fonksiyona ku ji qutkirina No. 13 (IRQ13) berpirsiyar e bi ya xwe biguhezîne:

{0x82, TIM2_Overflow}, /* irq13 */

Ya duyemîn, em ê neçar in ku pelek çêbikin main.h bi naveroka jêrîn:

#ifndef __MAIN_H
#define __MAIN_H

@far @interrupt void TIM2_Overflow (void);
#endif

Û di dawiyê de, vê fonksiyonê di xwe de binivîse main.c:

@far @interrupt void TIM2_Overflow (void)
{
    PD_ODR &= ~(1<<5); // вырубаем демультиплексор
    PC_ODR = (cnt<<3); // записываем в демультиплексор новое значение
    PD_ODR |= (1<<5); // включаем демультиплексор

    TIM2_SR1 = 0; // сбрасываем флаг Update Interrupt Pending

    cnt++; 
    cnt &= 7; // двигаем счетчик LED

    TIM2_CCR1L = ~colors[cnt][0]; // передаем в буфер инвертированные значения
    TIM2_CCR2L = ~colors[cnt][1]; // для следующего цикла ШИМ
    TIM2_CCR3L = ~colors[cnt][2]; // 

    return;
}

Tiştê ku dimîne ev e ku navberan çalak bikin. Ev bi karanîna fermana assembler pêk tê rim - Divê hûn lê bigerin Manual Programming:

//enable interrupts
_asm("rim");

Fermanek din a assembler e sim - astengiyan vedike. Dema ku nirxên nû li "bîra vîdyoyê" têne nivîsandin divê ew bêne girtin, da ku qutbûnek ku di demek xelet de çêbibe rêzê xera neke.

Hemî kod - li ser GitHub.

Daneyên daneyan 2 bixwînin: SPI li ser STM32; PWM, demjimêr û astengiyên li ser STM8

Ger bi kêmanî kesek vê gotarê kêrhatî bibîne, wê hingê min ew vala nenivîsî. Ez ê kêfxweş bibim ku şîrove û têbînîyan bistînim, ez ê hewl bidim ku bersiva her tiştî bidim.

Source: www.habr.com

Add a comment