డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు

В మొదటి భాగం నేను Arduino ప్యాంటు నుండి పెరిగిన హాబీ ఎలక్ట్రానిక్స్ ఇంజనీర్‌లకు మైక్రోకంట్రోలర్‌ల కోసం డేటాషీట్‌లు మరియు ఇతర డాక్యుమెంటేషన్‌లను ఎలా మరియు ఎందుకు చదవాలో చెప్పడానికి ప్రయత్నించాను. వచనం పెద్దదిగా మారింది, కాబట్టి నేను ప్రత్యేక కథనంలో ఆచరణాత్మక ఉదాహరణలను చూపుతానని వాగ్దానం చేసాను. బాగా, అతను తనను తాను పాలు పుట్టగొడుగు అని పిలిచాడు ...

STM32 (బ్లూ పిల్) మరియు STM8 కంట్రోలర్‌లలోని అనేక ప్రాజెక్ట్‌లు, టాస్క్‌లకు చాలా సులభమైన, కానీ అవసరమైన వాటిని పరిష్కరించడానికి డేటాషీట్‌లను ఎలా ఉపయోగించాలో ఈ రోజు నేను మీకు చూపుతాను. అన్ని డెమో ప్రాజెక్ట్‌లు నాకు ఇష్టమైన LED లకు అంకితం చేయబడ్డాయి, మేము వాటిని పెద్ద పరిమాణంలో వెలిగిస్తాము, దీని కోసం మేము అన్ని రకాల ఆసక్తికరమైన పెరిఫెరల్స్‌ను ఉపయోగించాల్సి ఉంటుంది.

వచనం మళ్లీ పెద్దదిగా మారింది, కాబట్టి సౌలభ్యం కోసం నేను కంటెంట్‌ని తయారు చేస్తున్నాను:

STM32 బ్లూ పిల్: DM16 డ్రైవర్‌తో 634 LEDలు
STM8: ఆరు PWM పిన్‌లను ఏర్పాటు చేస్తోంది
STM8: మూడు పిన్‌లపై 8 RGB LEDలు, అంతరాయాలు

నిరాకరణ: నేను ఇంజనీర్‌ని కాదు, ఎలక్ట్రానిక్స్‌లో లోతైన జ్ఞానం ఉన్నట్లు నటించను, వ్యాసం నాలాంటి ఔత్సాహికుల కోసం ఉద్దేశించబడింది. నిజానికి రెండేళ్ల క్రితం నేనే టార్గెట్ ఆడియన్స్‌గా భావించాను. తెలియని చిప్‌లోని డేటాషీట్‌లు చదవడానికి భయంగా ఉండవని ఎవరైనా నాకు అప్పుడు చెబితే, నేను ఇంటర్నెట్‌లో కొన్ని కోడ్ ముక్కల కోసం వెతుకుతూ, కత్తెర మరియు అంటుకునే టేపుతో క్రచెస్‌ను కనిపెట్టడానికి ఎక్కువ సమయం వెచ్చించను.

ఈ కథనం యొక్క దృష్టి డేటాషీట్‌లపై ఉంది, ప్రాజెక్ట్‌లపై కాదు, కాబట్టి కోడ్ చాలా చక్కగా మరియు తరచుగా ఇరుకైనది కాకపోవచ్చు. కొత్త చిప్‌తో మొదటి పరిచయానికి తగినది అయినప్పటికీ, ప్రాజెక్టులు చాలా సరళంగా ఉంటాయి.

అభిరుచిలో ఇమ్మర్షన్ ఇదే దశలో ఉన్నవారికి నా వ్యాసం సహాయపడుతుందని నేను ఆశిస్తున్నాను.

STM32

DM16 మరియు SPIతో 634 LED లు

బ్లూ పిల్ (STM32F103C8T6) మరియు DM634 LED డ్రైవర్‌ని ఉపయోగించే చిన్న ప్రాజెక్ట్. డేటాషీట్‌లను ఉపయోగించి, మేము డ్రైవర్, STM IO పోర్ట్‌లను గుర్తించి SPIని కాన్ఫిగర్ చేస్తాము.

DM634

16 16-బిట్ PWM అవుట్‌పుట్‌లతో తైవానీస్ చిప్, చైన్‌లలో కనెక్ట్ చేయబడుతుంది. తక్కువ-ముగింపు 12-బిట్ మోడల్ దేశీయ ప్రాజెక్ట్ నుండి తెలుసు లైట్‌ప్యాక్. ఒక సమయంలో, DM63x మరియు ప్రసిద్ధ TLC5940 మధ్య ఎంచుకోవడం, నేను అనేక కారణాల వల్ల DMని ఎంచుకున్నాను: 1) Aliexpressలో TLC ఖచ్చితంగా నకిలీ, కానీ ఇది కాదు; 2) DM దాని స్వంత ఫ్రీక్వెన్సీ జనరేటర్‌తో స్వయంప్రతిపత్త PWMని కలిగి ఉంది; 3) అలీ నుండి పార్శిల్ కోసం ఎదురుచూడకుండా, మాస్కోలో చవకగా కొనుగోలు చేయవచ్చు. మరియు, వాస్తవానికి, రెడీమేడ్ లైబ్రరీని ఉపయోగించడం కంటే చిప్‌ను మీరే ఎలా నియంత్రించాలో తెలుసుకోవడం ఆసక్తికరంగా ఉంది. చిప్స్ ఇప్పుడు ప్రధానంగా SSOP24 ప్యాకేజీలో ప్రదర్శించబడ్డాయి; అవి అడాప్టర్‌కు టంకము చేయడం సులభం.

తయారీదారు తైవానీస్ అయినందున, సమాచార పట్టిక చిప్ చైనీస్ ఆంగ్లంలో వ్రాయబడింది, అంటే ఇది సరదాగా ఉంటుంది. మొదట మనం పిన్‌అవుట్‌ని చూస్తాము (పిన్ కనెక్షన్) ఏ కాలును ఏమి కనెక్ట్ చేయాలో అర్థం చేసుకోవడానికి మరియు పిన్స్ యొక్క వివరణ (పిన్ వివరణ) 16 పిన్స్:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
DC సింక్ సోర్సెస్ (ఓపెన్ డ్రెయిన్)

సింక్ / ఓపెన్-డ్రెయిన్ అవుట్‌పుట్ - హరించడం; ఇన్ఫ్లోయింగ్ కరెంట్ యొక్క మూలం; అవుట్‌పుట్ సక్రియ స్థితిలో భూమికి అనుసంధానించబడి ఉంది - LED లు కాథోడ్‌ల ద్వారా డ్రైవర్‌కు కనెక్ట్ చేయబడతాయి. విద్యుత్తుగా, ఇది "ఓపెన్ డ్రెయిన్" కాదు (ఓపెన్ డ్రెయిన్), కానీ డేటాషీట్‌లలో డ్రెయిన్ మోడ్‌లోని పిన్‌ల కోసం ఈ హోదా తరచుగా కనుగొనబడుతుంది.

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
అవుట్‌పుట్ ప్రస్తుత విలువను సెట్ చేయడానికి REXT మరియు GND మధ్య బాహ్య రెసిస్టర్‌లు

REXT పిన్ మరియు గ్రౌండ్ మధ్య రిఫరెన్స్ రెసిస్టర్ ఇన్‌స్టాల్ చేయబడింది, ఇది అవుట్‌పుట్‌ల అంతర్గత నిరోధాన్ని నియంత్రిస్తుంది, డేటాషీట్‌లోని 9వ పేజీలోని గ్రాఫ్‌ను చూడండి. DM634లో, ఈ ప్రతిఘటనను సాఫ్ట్‌వేర్ ద్వారా కూడా నియంత్రించవచ్చు, మొత్తం ప్రకాశాన్ని సెట్ చేస్తుంది (ప్రపంచ ప్రకాశం); నేను ఈ కథనంలో వివరాలలోకి వెళ్లను, నేను ఇక్కడ 2.2 - 3 kOhm రెసిస్టర్‌ని ఉంచుతాను.

చిప్‌ను ఎలా నియంత్రించాలో అర్థం చేసుకోవడానికి, పరికర ఇంటర్‌ఫేస్ వివరణను చూద్దాం:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు

అవును, ఇదిగో, చైనీస్ ఇంగ్లీష్ దాని గొప్పతనం. దీన్ని అనువదించడం సమస్యాత్మకం, మీరు కోరుకుంటే మీరు అర్థం చేసుకోవచ్చు, కానీ మరొక మార్గం ఉంది - డేటాషీట్‌లో క్రియాత్మకంగా సారూప్య TLC5940కి కనెక్షన్ ఎలా వివరించబడిందో చూడండి:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
... పరికరంలోకి డేటాను నమోదు చేయడానికి కేవలం మూడు పిన్‌లు మాత్రమే అవసరం. SCLK సిగ్నల్ యొక్క పెరుగుతున్న అంచు డేటాను SIN పిన్ నుండి అంతర్గత రిజిస్టర్‌కి మారుస్తుంది. మొత్తం డేటా లోడ్ అయిన తర్వాత, ఒక చిన్న అధిక XLAT సిగ్నల్ అంతర్గత రిజిస్టర్‌లలోకి వరుసగా బదిలీ చేయబడిన డేటాను లాక్ చేస్తుంది. అంతర్గత రిజిస్టర్‌లు XLAT సిగ్నల్ స్థాయి ద్వారా ప్రేరేపించబడిన గేట్లు. అన్ని డేటా అత్యంత ముఖ్యమైన బిట్ మొదట ప్రసారం చేయబడుతుంది.

గొళ్ళెం - గొళ్ళెం / గొళ్ళెం / తాళం.
పెరుగుతున్న అంచు - పల్స్ యొక్క ప్రధాన అంచు
మొదట MSB - అత్యంత ముఖ్యమైన (ఎడమవైపు) బిట్ ఫార్వర్డ్.
గడియారం డేటాకు - డేటాను వరుసగా ప్రసారం చేయండి (బిట్ బై బిట్).

పదం గొళ్ళెం చిప్‌ల కోసం డాక్యుమెంటేషన్‌లో తరచుగా కనుగొనబడుతుంది మరియు వివిధ మార్గాల్లో అనువదించబడుతుంది, కాబట్టి అవగాహన కోసం నేను నన్ను అనుమతిస్తాను

ఒక చిన్న విద్యా కార్యక్రమంLED డ్రైవర్ తప్పనిసరిగా షిఫ్ట్ రిజిస్టర్. "మార్పు" (మార్పు) పేరులో - పరికరం లోపల డేటా యొక్క బిట్‌వైజ్ కదలిక: లోపలికి నెట్టబడిన ప్రతి కొత్త బిట్ మొత్తం గొలుసును దాని ముందు ముందుకు నెట్టివేస్తుంది. షిఫ్ట్ సమయంలో LED లు అస్తవ్యస్తంగా మెరిసిపోవడాన్ని ఎవరూ గమనించనక్కరలేదు కాబట్టి, డ్యాంపర్ ద్వారా పని చేసే రిజిస్టర్‌ల నుండి వేరు చేయబడిన బఫర్ రిజిస్టర్‌లలో ప్రక్రియ జరుగుతుంది (గొళ్ళెం) బిట్‌లు కావలసిన క్రమంలో అమర్చబడిన ఒక రకమైన వెయిటింగ్ రూమ్. ప్రతిదీ సిద్ధంగా ఉన్నప్పుడు, షట్టర్ తెరుచుకుంటుంది మరియు మునుపటి బ్యాచ్ స్థానంలో బిట్స్ పనికి వెళ్తాయి. మాట గొళ్ళెం మైక్రోసర్క్యూట్‌ల కోసం డాక్యుమెంటేషన్‌లో దాదాపు ఎల్లప్పుడూ అలాంటి డంపర్‌ని సూచిస్తుంది, అది ఏ కలయికలలో ఉపయోగించినప్పటికీ.

కాబట్టి, DM634కి డేటా బదిలీ ఇలా జరుగుతుంది: DAI ఇన్‌పుట్‌ను చాలా ముఖ్యమైన LED యొక్క అత్యంత ముఖ్యమైన బిట్ విలువకు సెట్ చేయండి, DCKని పైకి క్రిందికి లాగండి; DAI ఇన్‌పుట్‌ను తదుపరి బిట్ విలువకు సెట్ చేయండి, DCKని లాగండి; మరియు అన్ని బిట్‌లు ప్రసారం చేయబడే వరకు (క్లాక్ చేయబడింది), దాని తర్వాత మేము LATని లాగుతాము. ఇది మానవీయంగా చేయవచ్చు (బిట్-బ్యాంగ్), అయితే దీని కోసం ప్రత్యేకంగా రూపొందించిన SPI ఇంటర్‌ఫేస్‌ను ఉపయోగించడం మంచిది, ఎందుకంటే ఇది మా STM32లో రెండు కాపీలలో ప్రదర్శించబడుతుంది.

బ్లూ పిల్ STM32F103

ఉపోద్ఘాతం: STM32 కంట్రోలర్‌లు Atmega328 కంటే చాలా క్లిష్టంగా ఉంటాయి, అవి భయానకంగా అనిపించవచ్చు. అంతేకాకుండా, శక్తి పొదుపు కారణాల దృష్ట్యా, దాదాపు అన్ని పెరిఫెరల్స్ ప్రారంభంలో ఆఫ్ చేయబడతాయి మరియు క్లాక్ ఫ్రీక్వెన్సీ అంతర్గత మూలం నుండి 8 MHz. అదృష్టవశాత్తూ, STM ప్రోగ్రామర్లు చిప్‌ను "లెక్కించబడిన" 72 MHz వరకు తీసుకువచ్చే కోడ్‌ను వ్రాసారు మరియు నాకు తెలిసిన అన్ని IDEల రచయితలు దీన్ని ప్రారంభ ప్రక్రియలో చేర్చారు, కాబట్టి మేము క్లాక్ చేయవలసిన అవసరం లేదు (కానీ మీకు నిజంగా కావాలంటే మీరు చెయ్యగలరు) కానీ మీరు పెరిఫెరల్స్‌ను ఆన్ చేయాలి.

డాక్యుమెంటేషన్: బ్లూ పిల్ ప్రసిద్ధ STM32F103C8T6 చిప్‌తో అమర్చబడింది, దీనికి రెండు ఉపయోగకరమైన పత్రాలు ఉన్నాయి:

డేటాషీట్‌లో మనకు ఆసక్తి ఉండవచ్చు:

  • పిన్‌అవుట్‌లు - చిప్ పిన్‌అవుట్‌లు - మనం బోర్డులను తయారు చేయాలని నిర్ణయించుకున్నట్లయితే;
  • మెమరీ మ్యాప్ - నిర్దిష్ట చిప్ కోసం మెమరీ మ్యాప్. రిఫరెన్స్ మాన్యువల్ మొత్తం లైన్ కోసం మ్యాప్‌ను కలిగి ఉంది మరియు అది మాది లేని రిజిస్టర్‌లను పేర్కొంది.
  • పిన్ నిర్వచనాల పట్టిక - పిన్స్ యొక్క ప్రధాన మరియు ప్రత్యామ్నాయ విధులను జాబితా చేయడం; "బ్లూ పిల్" కోసం మీరు పిన్స్ మరియు వాటి ఫంక్షన్ల జాబితాతో ఇంటర్నెట్‌లో మరింత అనుకూలమైన చిత్రాలను కనుగొనవచ్చు. అందువల్ల, మేము వెంటనే బ్లూ పిల్ పిన్‌అవుట్‌ని గూగుల్ చేసి, ఈ చిత్రాన్ని చేతిలో ఉంచుతాము:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
NB: ఇంటర్నెట్ నుండి చిత్రంలో ఒక లోపం ఉంది, ఇది వ్యాఖ్యలలో గుర్తించబడింది, అందుకు ధన్యవాదాలు. చిత్రం భర్తీ చేయబడింది, కానీ ఇది ఒక పాఠం - డేటాషీట్‌ల నుండి కాకుండా సమాచారాన్ని తనిఖీ చేయడం మంచిది.

మేము డేటాషీట్‌ను తీసివేసి, రిఫరెన్స్ మాన్యువల్‌ని తెరవండి మరియు ఇప్పటి నుండి మేము దానిని మాత్రమే ఉపయోగిస్తాము.
విధానం: మేము ప్రామాణిక ఇన్‌పుట్/అవుట్‌పుట్‌తో వ్యవహరిస్తాము, SPIని కాన్ఫిగర్ చేస్తాము, అవసరమైన పెరిఫెరల్స్‌ను ఆన్ చేస్తాము.

ఇన్‌పుట్ అవుట్‌పుట్

Atmega328లో, I/O చాలా సరళంగా అమలు చేయబడుతుంది, అందుకే STM32 ఎంపికల సమృద్ధి గందరగోళంగా ఉంటుంది. ఇప్పుడు మనకు ముగింపులు మాత్రమే అవసరం, కానీ వీటికి కూడా నాలుగు ఎంపికలు ఉన్నాయి:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
ఓపెన్ డ్రెయిన్, పుష్-పుల్, ప్రత్యామ్నాయ పుష్-పుల్, ప్రత్యామ్నాయ ఓపెన్ డ్రెయిన్

"లాగు నెట్టు" (పుష్-పుల్) అనేది Arduino నుండి సాధారణ అవుట్‌పుట్, పిన్ అధిక లేదా తక్కువ విలువను తీసుకోవచ్చు. కానీ "ఓపెన్ డ్రెయిన్" తో ఉన్నాయి ఇబ్బందులు, నిజానికి ఇక్కడ ప్రతిదీ చాలా సులభం అయినప్పటికీ:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
అవుట్‌పుట్ కాన్ఫిగరేషన్ / అవుట్‌పుట్‌కు పోర్ట్ కేటాయించబడినప్పుడు: / అవుట్‌పుట్ బఫర్ ఎనేబుల్ చేయబడింది: / – ఓపెన్ డ్రెయిన్ మోడ్: అవుట్‌పుట్ రిజిస్టర్‌లోని “0” N-MOSని ప్రారంభిస్తుంది, అవుట్‌పుట్ రిజిస్టర్‌లోని “1” పోర్ట్‌ను Hi-Z మోడ్‌లో వదిలివేస్తుంది ( P-MOS సక్రియం చేయబడలేదు ) / – పుష్-పుల్ మోడ్: అవుట్‌పుట్ రిజిస్టర్‌లోని “0” N-MOSని సక్రియం చేస్తుంది, అవుట్‌పుట్ రిజిస్టర్‌లోని “1” P-MOSని సక్రియం చేస్తుంది.

ఓపెన్ డ్రెయిన్ మధ్య అన్ని తేడా (ఓపెన్ డ్రెయిన్) “పుష్-పుల్” నుండి (పుష్-పుల్) అంటే మొదటి పిన్‌లో అధిక స్థితిని ఆమోదించలేము: అవుట్‌పుట్ రిజిస్టర్‌కి ఒకదాన్ని వ్రాసేటప్పుడు, అది అధిక నిరోధక మోడ్‌లోకి వెళుతుంది (అధిక నిరోధం, హాయ్- Z) సున్నా వ్రాసేటప్పుడు, పిన్ లాజికల్‌గా మరియు ఎలక్ట్రికల్‌గా రెండు మోడ్‌లలో ఒకే విధంగా ప్రవర్తిస్తుంది.

సాధారణ అవుట్‌పుట్ మోడ్‌లో, పిన్ కేవలం అవుట్‌పుట్ రిజిస్టర్‌లోని విషయాలను ప్రసారం చేస్తుంది. "ప్రత్యామ్నాయం"లో ఇది సంబంధిత పెరిఫెరల్స్ ద్వారా నియంత్రించబడుతుంది (9.1.4 చూడండి):

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
పోర్ట్ బిట్ ప్రత్యామ్నాయ ఫంక్షన్ పిన్‌గా కాన్ఫిగర్ చేయబడితే, పిన్ రిజిస్టర్ నిలిపివేయబడుతుంది మరియు పిన్ పెరిఫెరల్ పిన్‌కి కనెక్ట్ చేయబడుతుంది.

ప్రతి పిన్ యొక్క ప్రత్యామ్నాయ కార్యాచరణ వివరించబడింది పిన్ నిర్వచనాలు డౌన్‌లోడ్ చేసిన చిత్రంపై డేటాషీట్ ఉంది. పిన్ అనేక ప్రత్యామ్నాయ విధులను కలిగి ఉంటే ఏమి చేయాలనే ప్రశ్నకు, డేటాషీట్‌లోని ఫుట్‌నోట్ ద్వారా సమాధానం ఇవ్వబడుతుంది:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
బహుళ పెరిఫెరల్స్ ఒకే పిన్‌ని ఉపయోగిస్తే, ప్రత్యామ్నాయ ఫంక్షన్‌ల మధ్య వైరుధ్యాన్ని నివారించడానికి, ఒక సమయంలో ఒక పరిధీయ మాత్రమే ఉపయోగించాలి, పెరిఫెరల్ క్లాక్ ఎనేబుల్ బిట్ (సముచితమైన RCC రిజిస్టర్‌లో) ఉపయోగించి టోగుల్ చేయాలి.

చివరగా, అవుట్‌పుట్ మోడ్‌లోని పిన్‌లు క్లాక్ స్పీడ్‌ను కూడా కలిగి ఉంటాయి. ఇది మరొక శక్తి పొదుపు లక్షణం; మా విషయంలో, మేము దానిని గరిష్టంగా సెట్ చేసి మరచిపోతాము.

కాబట్టి: మేము SPIని ఉపయోగిస్తున్నాము, అంటే రెండు పిన్‌లు (డేటాతో మరియు క్లాక్ సిగ్నల్‌తో) "ప్రత్యామ్నాయ పుష్-పుల్ ఫంక్షన్" అయి ఉండాలి మరియు మరొకటి (LAT) "రెగ్యులర్ పుష్-పుల్" అయి ఉండాలి. కానీ వాటిని కేటాయించే ముందు, SPIతో వ్యవహరించండి.

SPI

మరో చిన్న విద్యా కార్యక్రమం

SPI లేదా సీరియల్ పెరిఫెరల్ ఇంటర్‌ఫేస్ (సీరియల్ పెరిఫెరల్ ఇంటర్‌ఫేస్) అనేది MKని ఇతర MKలతో మరియు సాధారణంగా బయటి ప్రపంచంతో కనెక్ట్ చేయడానికి సులభమైన మరియు చాలా ప్రభావవంతమైన ఇంటర్‌ఫేస్. దాని ఆపరేషన్ సూత్రం ఇప్పటికే పైన వివరించబడింది, ఇక్కడ చైనీస్ LED డ్రైవర్ గురించి (రిఫరెన్స్ మాన్యువల్లో, విభాగం 25 చూడండి). SPI మాస్టర్ ("మాస్టర్") మరియు స్లేవ్ ("స్లేవ్") మోడ్‌లో పనిచేయగలదు. SPI నాలుగు ప్రాథమిక ఛానెల్‌లను కలిగి ఉంది, వీటిలో అన్నీ ఉపయోగించబడవు:

  • MOSI, మాస్టర్ అవుట్‌పుట్ / స్లేవ్ ఇన్‌పుట్: ఈ పిన్ మాస్టర్ మోడ్‌లో డేటాను ప్రసారం చేస్తుంది మరియు స్లేవ్ మోడ్‌లో డేటాను అందుకుంటుంది;
  • MISO, మాస్టర్ ఇన్‌పుట్ / స్లేవ్ అవుట్‌పుట్: దీనికి విరుద్ధంగా, ఇది మాస్టర్‌లో అందుకుంటుంది మరియు స్లేవ్‌లో ప్రసారం చేస్తుంది;
  • SCK, సీరియల్ క్లాక్: మాస్టర్‌లో డేటా ట్రాన్స్‌మిషన్ ఫ్రీక్వెన్సీని సెట్ చేస్తుంది లేదా స్లేవ్‌లో క్లాక్ సిగ్నల్‌ను అందుకుంటుంది. ముఖ్యంగా కొట్టే బీట్స్;
  • SS, స్లేవ్ సెలెక్ట్: ఈ ఛానెల్ సహాయంతో, బానిస తన నుండి ఏదో కోరుకుంటున్నట్లు తెలుసుకుంటాడు. STM32లో దీనిని NSS అంటారు, ఇక్కడ N = నెగిటివ్, అనగా. ఈ ఛానెల్‌లో గ్రౌండ్ ఉంటే కంట్రోలర్ బానిస అవుతాడు. ఇది ఓపెన్ డ్రెయిన్ అవుట్‌పుట్ మోడ్‌తో బాగా కలుపుతుంది, కానీ అది మరొక కథ.

అన్నిటిలాగే, STM32లో SPI కార్యాచరణలో సమృద్ధిగా ఉంటుంది, ఇది అర్థం చేసుకోవడం కొంత కష్టతరం చేస్తుంది. ఉదాహరణకు, ఇది SPI తో మాత్రమే కాకుండా, I2S ఇంటర్‌ఫేస్‌తో కూడా పని చేస్తుంది మరియు డాక్యుమెంటేషన్‌లో వారి వివరణలు మిశ్రమంగా ఉంటాయి, సకాలంలో అదనపు కత్తిరించడం అవసరం. మా పని చాలా సులభం: మేము కేవలం MOSI మరియు SCKని ఉపయోగించి డేటాను పంపాలి. మేము సెక్షన్ 25.3.4 (సగం డ్యూప్లెక్స్ కమ్యూనికేషన్, సగం డ్యూప్లెక్స్ కమ్యూనికేషన్)కి వెళ్తాము, అక్కడ మేము కనుగొంటాము. 1 గడియారం మరియు 1 ఏకదిశాత్మక డేటా వైర్ (1 క్లాక్ సిగ్నల్ మరియు 1 ఏకదిశాత్మక డేటా స్ట్రీమ్):

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
ఈ మోడ్‌లో, అప్లికేషన్ SPIని ట్రాన్స్‌మిట్-ఓన్లీ లేదా రిసీవ్-ఓన్లీ మోడ్‌లో ఉపయోగిస్తుంది. / ట్రాన్స్‌మిట్-ఓన్లీ మోడ్ డ్యూప్లెక్స్ మోడ్‌ను పోలి ఉంటుంది: ట్రాన్స్‌మిట్ పిన్‌పై డేటా ట్రాన్స్‌మిట్ చేయబడుతుంది (మాస్టర్ మోడ్‌లో MOSI లేదా స్లేవ్ మోడ్‌లో MISO), మరియు రిసీవ్ పిన్ (వరుసగా MISO లేదా MOSI) సాధారణ I/O పిన్‌గా ఉపయోగించవచ్చు . ఈ సందర్భంలో, అప్లికేషన్ Rx బఫర్‌ను మాత్రమే విస్మరించాల్సిన అవసరం ఉంది (అది చదివితే, అక్కడ బదిలీ చేయబడిన డేటా ఉండదు).

చాలా బాగుంది, MISO పిన్ ఉచితం, LAT సిగ్నల్‌ని దానికి కనెక్ట్ చేద్దాం. STM32లో ప్రోగ్రామాటిక్‌గా నియంత్రించబడే స్లేవ్ సెలెక్ట్‌ని చూద్దాం, ఇది చాలా సౌకర్యవంతంగా ఉంటుంది. మేము సెక్షన్ 25.3.1 SPI సాధారణ వివరణలో అదే పేరు యొక్క పేరాను చదువుతాము:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
సాఫ్ట్‌వేర్ నియంత్రణ NSS (SSM = 1) / స్లేవ్ ఎంపిక సమాచారం SPI_CR1 రిజిస్టర్ యొక్క SSI బిట్‌లో ఉంటుంది. ఇతర అప్లికేషన్ అవసరాలకు బాహ్య NSS పిన్ ఉచితం.

ఇది రిజిస్టర్లకు వ్రాయడానికి సమయం. నేను SPI2ని ఉపయోగించాలని నిర్ణయించుకున్నాను, డేటాషీట్‌లో దాని మూల చిరునామా కోసం చూడండి - విభాగం 3.3 మెమరీ మ్యాప్‌లో:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు

సరే, ప్రారంభిద్దాం:

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

"మాస్టర్ మోడ్‌లో SPIని కాన్ఫిగర్ చేయడం" స్వీయ వివరణాత్మక శీర్షికతో విభాగాన్ని 25.3.3 తెరవండి:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు

1. SPI_CR2 రిజిస్టర్‌లో బిట్స్ BR[0:1]తో సీరియల్ క్లాక్ ఫ్రీక్వెన్సీని సెట్ చేయండి.

రిజిస్టర్‌లు అదే పేరుతో ఉన్న సూచన మాన్యువల్ విభాగంలో సేకరించబడతాయి. చిరునామా షిఫ్ట్ (చిరునామా ఆఫ్‌సెట్) CR1 – 0x00 కోసం, డిఫాల్ట్‌గా అన్ని బిట్‌లు క్లియర్ చేయబడతాయి (విలువను రీసెట్ చేయండి 0x0000):

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు

BR బిట్‌లు కంట్రోలర్ క్లాక్ డివైడర్‌ను సెట్ చేస్తాయి, తద్వారా SPI పనిచేసే ఫ్రీక్వెన్సీని నిర్ణయిస్తుంది. మా STM32 ఫ్రీక్వెన్సీ 72 MHz అవుతుంది, LED డ్రైవర్, దాని డేటాషీట్ ప్రకారం, 25 MHz వరకు ఫ్రీక్వెన్సీతో పనిచేస్తుంది, కాబట్టి మనం నాలుగు (BR[2:0] = 001) ద్వారా విభజించాలి.

#define _SPI_CR1 0x00

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

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

2. డేటా బదిలీ మరియు సీరియల్ క్లాక్ టైమింగ్ మధ్య సంబంధాన్ని నిర్వచించడానికి CPOL మరియు CPHA బిట్‌లను సెట్ చేయండి (పేజీ 240లోని రేఖాచిత్రం చూడండి)

మేము ఇక్కడ డేటాషీట్‌ను చదువుతున్నాము మరియు స్కీమాటిక్‌లను చూడటం లేదు కాబట్టి, పేజీ 704 (SPI సాధారణ వివరణ)లోని CPOL మరియు CPHA బిట్‌ల వచన వివరణను నిశితంగా పరిశీలిద్దాం:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
గడియార దశ మరియు ధ్రువణత
SPI_CR1 రిజిస్టర్ యొక్క CPOL మరియు CPHA బిట్‌లను ఉపయోగించి, మీరు ప్రోగ్రామాటిక్‌గా నాలుగు సమయ సంబంధాలను ఎంచుకోవచ్చు. CPOL (క్లాక్ పోలారిటీ) బిట్ డేటా ప్రసారం చేయబడనప్పుడు క్లాక్ సిగ్నల్ యొక్క స్థితిని నియంత్రిస్తుంది. ఈ బిట్ మాస్టర్ మరియు స్లేవ్ మోడ్‌లను నియంత్రిస్తుంది. CPOL రీసెట్ చేయబడితే, విశ్రాంతి మోడ్‌లో SCK పిన్ తక్కువగా ఉంటుంది. CPOL బిట్ సెట్ చేయబడితే, విశ్రాంతి మోడ్‌లో SCK పిన్ ఎక్కువగా ఉంటుంది.
CPHA (క్లాక్ ఫేజ్) బిట్ సెట్ చేయబడినప్పుడు, అధిక బిట్ ట్రాప్ స్ట్రోబ్ అనేది SCK సిగ్నల్ యొక్క రెండవ అంచు (CPOL స్పష్టంగా ఉంటే పడిపోతుంది, CPOL సెట్ చేయబడితే పెరుగుతుంది). గడియారం సిగ్నల్‌లో రెండవ మార్పు ద్వారా డేటా సంగ్రహించబడుతుంది. CPHA బిట్ స్పష్టంగా ఉంటే, అధిక బిట్ ట్రాప్ స్ట్రోబ్ అనేది SCK సిగ్నల్ యొక్క రైజింగ్ ఎడ్జ్ (CPOL సెట్ చేయబడితే పడే అంచు, CPOL క్లియర్ చేయబడితే రైజింగ్ ఎడ్జ్). క్లాక్ సిగ్నల్‌లో మొదటి మార్పు వద్ద డేటా క్యాప్చర్ చేయబడుతుంది.

ఈ జ్ఞానాన్ని గ్రహించిన తరువాత, రెండు బిట్‌లు తప్పనిసరిగా సున్నాలుగా ఉండాలనే నిర్ణయానికి వచ్చాము, ఎందుకంటే ఉపయోగంలో లేనప్పుడు SCK సిగ్నల్ తక్కువగా ఉండాలని మరియు పల్స్ యొక్క పెరుగుతున్న అంచుపై డేటా ప్రసారం చేయబడాలని మేము కోరుకుంటున్నాము (Fig. రైజింగ్ ఎడ్జ్ DM634 డేటాషీట్‌లో).

మార్గం ద్వారా, ఇక్కడ మేము మొదట ST డేటాషీట్‌లలోని పదజాలం యొక్క లక్షణాన్ని ఎదుర్కొన్నాము: వాటిలో "బిట్‌ను సున్నాకి రీసెట్ చేయి" అనే పదబంధం వ్రాయబడింది. కొంచెం రీసెట్ చేయడానికికానీ కాదు కొంచెం క్లియర్ చేయడానికి, ఉదాహరణకు, ఆత్మగా.

3. డేటా బ్లాక్ 8-బిట్ లేదా 16-బిట్ ఫార్మాట్ కాదా అని నిర్ణయించడానికి DFF బిట్‌ను సెట్ చేయండి

DM16 వంటి 634-బిట్ PWM డేటాను ప్రసారం చేయడంలో ఇబ్బంది పడకుండా నేను ప్రత్యేకంగా 12-బిట్ DM633ని తీసుకున్నాను. DFFని ఒకదానికి సెట్ చేయడం అర్ధమే:

#define DFF         0x0800

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

4. బ్లాక్ ఆకృతిని గుర్తించడానికి SPI_CR1 రిజిస్టర్‌లో LSBFIRST బిట్‌ను కాన్ఫిగర్ చేయండి

LSBFIRST, దాని పేరు సూచించినట్లుగా, ముందుగా తక్కువ ముఖ్యమైన బిట్‌తో ప్రసారాన్ని కాన్ఫిగర్ చేస్తుంది. కానీ DM634 అత్యంత ముఖ్యమైన బిట్ నుండి డేటాను స్వీకరించాలనుకుంటోంది. కాబట్టి, మేము దానిని రీసెట్‌ని వదిలివేస్తాము.

5. హార్డ్‌వేర్ మోడ్‌లో, NSS పిన్ నుండి ఇన్‌పుట్ అవసరమైతే, మొత్తం బైట్ బదిలీ సీక్వెన్స్ సమయంలో NSS పిన్‌కి అధిక సిగ్నల్‌ని వర్తింపజేయండి. NSS సాఫ్ట్‌వేర్ మోడ్‌లో, SPI_CR1 రిజిస్టర్‌లో SSM మరియు SSI బిట్‌లను సెట్ చేయండి. NSS పిన్‌ను అవుట్‌పుట్‌గా ఉపయోగించాలంటే, SSOE బిట్‌ను మాత్రమే సెట్ చేయాలి.

NSS హార్డ్‌వేర్ మోడ్ గురించి మరచిపోవడానికి SSM మరియు SSIలను ఇన్‌స్టాల్ చేయండి:

#define SSI         0x0100
#define SSM         0x0200

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

6. MSTR మరియు SPE బిట్‌లు తప్పనిసరిగా సెట్ చేయబడాలి (NSS సిగ్నల్ ఎక్కువగా ఉంటే మాత్రమే అవి సెట్ చేయబడతాయి)

వాస్తవానికి, ఈ బిట్‌లతో మేము మా SPIని మాస్టర్‌గా నియమిస్తాము మరియు దానిని ఆన్ చేస్తాము:

#define MSTR        0x0004
#define SPE         0x0040

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

SPI కాన్ఫిగర్ చేయబడింది, డ్రైవర్‌కు బైట్‌లను పంపే ఫంక్షన్‌లను వెంటనే వ్రాద్దాం. 25.3.3 “మాస్టర్ మోడ్‌లో SPIని కాన్ఫిగర్ చేయడం” చదవడం కొనసాగించండి:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
డేటా బదిలీ ఆర్డర్
Tx బఫర్‌కు బైట్ వ్రాయబడినప్పుడు ప్రసారం ప్రారంభమవుతుంది.
డేటా బైట్ షిఫ్ట్ రిజిస్టర్‌లో లోడ్ చేయబడింది సమాంతరంగా మోడ్ (అంతర్గత బస్సు నుండి) మొదటి బిట్ యొక్క ప్రసార సమయంలో, దాని తర్వాత ఇది ప్రసారం చేయబడుతుంది సీక్వెన్షియల్ MOSI పిన్ మోడ్, CPI_CR1 రిజిస్టర్‌లో LSBFIRST బిట్ సెట్టింగ్‌పై ఆధారపడి మొదటి లేదా చివరి బిట్ ఫార్వార్డ్. డేటా ట్రాన్స్‌మిషన్ తర్వాత TXE ఫ్లాగ్ సెట్ చేయబడింది Tx బఫర్ నుండి షిఫ్ట్ రిజిస్టర్ వరకు, మరియు CPI_CR1 రిజిస్టర్‌లో TXEIE బిట్ సెట్ చేయబడితే అంతరాయాన్ని కూడా సృష్టిస్తుంది.

STM కంట్రోలర్‌లలో SPI అమలు యొక్క ఒక ఫీచర్‌పై దృష్టిని ఆకర్షించడానికి నేను అనువాదంలో కొన్ని పదాలను హైలైట్ చేసాను. Atmegaలో TXE ఫ్లాగ్ (Tx ఖాళీ, Tx ఖాళీగా ఉంది మరియు డేటాను స్వీకరించడానికి సిద్ధంగా ఉంది) మొత్తం బైట్ పంపిన తర్వాత మాత్రమే సెట్ చేయబడుతుంది బయటకు. మరియు ఇక్కడ ఈ ఫ్లాగ్ అంతర్గత షిఫ్ట్ రిజిస్టర్‌లో బైట్ చొప్పించిన తర్వాత సెట్ చేయబడింది. ఇది ఒకే సమయంలో (సమాంతరంగా) అన్ని బిట్‌లతో అక్కడకు నెట్టబడినందున, ఆపై డేటా వరుసగా బదిలీ చేయబడుతుంది, బైట్ పూర్తిగా పంపబడే ముందు TXE సెట్ చేయబడుతుంది. ఇది ముఖ్యం ఎందుకంటే మా LED డ్రైవర్ విషయంలో, మేము పంపిన తర్వాత LAT పిన్‌ను లాగాలి всех డేటా, అనగా. TXE జెండా మాత్రమే మాకు సరిపోదు.

అంటే మనకు మరో జెండా కావాలి. 25.3.7 - “స్టేటస్ ఫ్లాగ్‌లు” చూద్దాం:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
<…>
డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
బిజీ ఫ్లాగ్
BSY ఫ్లాగ్ హార్డ్‌వేర్ ద్వారా సెట్ చేయబడింది మరియు క్లియర్ చేయబడింది (దీనికి రాయడం వల్ల ఎటువంటి ప్రభావం ఉండదు). BSY జెండా SPI కమ్యూనికేషన్ లేయర్ యొక్క స్థితిని సూచిస్తుంది.
ఇది రీసెట్ చేస్తుంది:
బదిలీ పూర్తయినప్పుడు (బదిలీ నిరంతరంగా ఉంటే మాస్టర్ మోడ్‌లో తప్ప)
SPI నిలిపివేయబడినప్పుడు
మాస్టర్ మోడ్ లోపం సంభవించినప్పుడు (MODF=1)
బదిలీ నిరంతరంగా లేకపోతే, ప్రతి డేటా బదిలీ మధ్య BSY ఫ్లాగ్ క్లియర్ చేయబడుతుంది

సరే, ఇది ఉపయోగపడుతుంది. Tx బఫర్ ఎక్కడ ఉందో తెలుసుకుందాం. దీన్ని చేయడానికి, “SPI డేటా రిజిస్టర్” చదవండి:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
బిట్స్ 15:0 DR[15:0] డేటా రిజిస్టర్
స్వీకరించిన డేటా లేదా ప్రసారం చేయవలసిన డేటా.
డేటా రిజిస్టర్ రెండు బఫర్‌లుగా విభజించబడింది - ఒకటి రాయడానికి (ట్రాన్స్‌మిట్ బఫర్) మరియు ఒకటి చదవడానికి (బఫర్‌ని స్వీకరించడానికి). డేటా రిజిస్టర్‌కి వ్రాయడం Tx బఫర్‌కు వ్రాస్తుంది మరియు డేటా రిజిస్టర్ నుండి చదవడం వలన Rx బఫర్‌లో ఉన్న విలువ తిరిగి వస్తుంది.

బాగా, మరియు స్థితి రిజిస్టర్, ఇక్కడ TXE మరియు BSY ఫ్లాగ్‌లు కనిపిస్తాయి:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు

మేము రాస్తాము:

#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
}

సరే, LED డ్రైవర్ అవుట్‌పుట్‌ల సంఖ్య ప్రకారం, మనం 16 సార్లు రెండు బైట్‌లను ప్రసారం చేయాలి కాబట్టి, ఇలాంటివి:

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();
}

కానీ మాకు ఇంకా LAT పిన్‌ను ఎలా లాగాలో తెలియదు, కాబట్టి మేము I/Oకి తిరిగి వెళ్తాము.

పిన్‌లను కేటాయించడం

STM32F1లో, పిన్‌ల స్థితికి బాధ్యత వహించే రిజిస్టర్‌లు చాలా అసాధారణమైనవి. వాటిలో Atmega కంటే ఎక్కువ ఉన్నాయని స్పష్టంగా తెలుస్తుంది, కానీ అవి ఇతర STM చిప్‌ల నుండి కూడా భిన్నంగా ఉంటాయి. విభాగం 9.1 GPIO యొక్క సాధారణ వివరణ:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
ప్రతి సాధారణ ప్రయోజన I/O పోర్ట్‌లు (GPIO) రెండు 32-బిట్ కాన్ఫిగరేషన్ రిజిస్టర్‌లు (GPIOx_CRL మరియు GPIOx_CRH), రెండు 32-బిట్ డేటా రిజిస్టర్‌లు (GPIOx_IDR మరియు GPIOx_ODR), 32-బిట్ సెట్/రీసెట్ రిజిస్టర్ (GPIOx_BSRR), 16-బిట్ రీసెట్ రిజిస్టర్ (GPIOx_BR32- మరియు ax_BRXNUMX) బిట్ బ్లాకింగ్ రిజిస్టర్ (GPIOx_LCKR).

మొదటి రెండు రిజిస్టర్‌లు అసాధారణమైనవి మరియు చాలా అసౌకర్యంగా ఉన్నాయి, ఎందుకంటే 16 పోర్ట్ పిన్‌లు వాటి అంతటా "ఒక్కో సోదరుడికి నాలుగు బిట్స్" ఆకృతిలో చెల్లాచెదురుగా ఉన్నాయి. ఆ. సున్నా నుండి ఏడు వరకు ఉన్న పిన్‌లు CRLలో ఉన్నాయి మరియు మిగిలినవి CRHలో ఉన్నాయి. అదే సమయంలో, మిగిలిన రిజిస్టర్‌లు పోర్ట్ యొక్క అన్ని పిన్‌ల బిట్‌లను విజయవంతంగా కలిగి ఉంటాయి - తరచుగా మిగిలిన సగం “రిజర్వ్”.

సరళత కోసం, జాబితా చివరి నుండి ప్రారంభిద్దాం.

మాకు బ్లాకింగ్ రిజిస్టర్ అవసరం లేదు.

సెట్ మరియు రీసెట్ రిజిస్టర్‌లు చాలా ఫన్నీగా ఉంటాయి, అవి పాక్షికంగా ఒకదానికొకటి డూప్లికేట్ అవుతాయి: మీరు BSRRలో మాత్రమే ప్రతిదీ వ్రాయగలరు, ఇక్కడ ఎక్కువ 16 బిట్‌లు పిన్‌ను సున్నాకి రీసెట్ చేస్తాయి మరియు దిగువ వాటిని 1కి సెట్ చేస్తారు లేదా మీరు కూడా చేయవచ్చు. BRRని ఉపయోగించండి, వీటిలో దిగువ 16 బిట్‌లు పిన్‌ను మాత్రమే రీసెట్ చేస్తాయి . నేను రెండవ ఎంపికను ఇష్టపడుతున్నాను. ఈ రిజిస్టర్‌లు ముఖ్యమైనవి ఎందుకంటే అవి పిన్‌లకు అటామిక్ యాక్సెస్‌ను అందిస్తాయి:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
అటామిక్ సెట్ లేదా రీసెట్
బిట్ స్థాయిలో GPIOx_ODR ప్రోగ్రామింగ్ చేస్తున్నప్పుడు అంతరాయాలను నిలిపివేయవలసిన అవసరం లేదు: ఒక అటామిక్ రైట్ ఆపరేషన్ APB2తో ఒకటి లేదా అంతకంటే ఎక్కువ బిట్‌లను మార్చవచ్చు. మార్చవలసిన బిట్ యొక్క సెట్/రీసెట్ రిజిస్టర్ (GPIOx_BSRR లేదా, రీసెట్ కోసం మాత్రమే, GPIOx_BRR)కి "1" వ్రాయడం ద్వారా ఇది సాధించబడుతుంది. ఇతర బిట్‌లు మారవు.

డేటా రిజిస్టర్‌లు చాలా స్వీయ-వివరణాత్మక పేర్లను కలిగి ఉన్నాయి - IDR = ఇన్పుట్ డైరెక్షన్ రిజిస్టర్, ఇన్‌పుట్ రిజిస్టర్; ODR = అవుట్పుట్ దిశ రిజిస్టర్, అవుట్‌పుట్ రిజిస్టర్. ప్రస్తుత ప్రాజెక్ట్‌లో మాకు అవి అవసరం లేదు.

చివరకు, నియంత్రణ రిజిస్టర్లు. PB13, PB14 మరియు PB15 అనే రెండవ SPI పిన్‌లపై మాకు ఆసక్తి ఉన్నందున, మేము వెంటనే CRH వైపు చూస్తాము:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు

మరియు మనం 20 నుండి 31 వరకు బిట్స్‌లో ఏదైనా వ్రాయవలసి ఉంటుందని మేము చూస్తాము.

పిన్‌ల నుండి మనకు ఏమి కావాలో మేము ఇప్పటికే గుర్తించాము, కాబట్టి ఇక్కడ నేను స్క్రీన్‌షాట్ లేకుండా చేస్తాను, MODE దిశను (రెండు బిట్‌లను 0కి సెట్ చేస్తే ఇన్‌పుట్) మరియు పిన్ వేగం (మనకు 50MHz అవసరం, అనగా. పిన్ రెండూ “1”), మరియు CNF మోడ్‌ను సెట్ చేస్తుంది: సాధారణ “పుష్-పుల్” – 00, “ప్రత్యామ్నాయం” – 10. డిఫాల్ట్‌గా, మనం పైన చూసినట్లుగా, అన్ని పిన్‌లు దిగువ నుండి మూడవ బిట్‌ను కలిగి ఉంటాయి (CNF0), అది వాటిని మోడ్‌కు సెట్ చేస్తుంది ఫ్లోటింగ్ ఇన్‌పుట్.

నేను ఈ చిప్‌తో ఇంకేదైనా చేయాలని ప్లాన్ చేస్తున్నందున, సరళత కోసం నేను దిగువ మరియు ఎగువ నియంత్రణ రిజిస్టర్‌ల కోసం సాధ్యమయ్యే అన్ని MODE మరియు CNF విలువలను నిర్వచించాను.

ఎలాగో ఇలా

#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

మా పిన్స్ పోర్ట్ B (బేస్ అడ్రస్ – 0x40010C00), కోడ్‌లో ఉన్నాయి:

#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;

మరియు, తదనుగుణంగా, మీరు LAT కోసం నిర్వచనాలను వ్రాయవచ్చు, ఇది BRR మరియు BSRR రిజిస్టర్‌ల ద్వారా ట్విచ్ చేయబడుతుంది:

/*** 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, ఇది ఎల్లప్పుడూ అలానే ఉంటుంది, అలాగే ఉండనివ్వండి)

ఇప్పుడు ప్రతిదీ చాలా బాగుంది, కానీ అది పని చేయదు. ఇది STM32 అయినందున, అవి విద్యుత్తును ఆదా చేస్తాయి, అంటే మీరు అవసరమైన పెరిఫెరల్స్ యొక్క క్లాకింగ్‌ను ప్రారంభించాలి.

గడియారాన్ని ఆన్ చేయండి

గడియారం అని కూడా పిలువబడే గడియారం, గడియారానికి బాధ్యత వహిస్తుంది. మరియు మేము ఇప్పటికే RCC సంక్షిప్తీకరణను గమనించవచ్చు. మేము దాని కోసం డాక్యుమెంటేషన్‌లో వెతుకుతున్నాము: ఇది రీసెట్ మరియు క్లాక్ కంట్రోల్.

పైన చెప్పినట్లుగా, అదృష్టవశాత్తూ, క్లాకింగ్ టాపిక్ యొక్క అత్యంత కష్టమైన భాగం STM నుండి వచ్చిన వ్యక్తులు మా కోసం చేసారు, దీని కోసం మేము వారికి చాలా ధన్యవాదాలు (మరోసారి నేను లింక్ ఇస్తాను డి హాల్ట్ వెబ్‌సైట్, ఇది ఎంత గందరగోళంగా ఉందో స్పష్టంగా చెప్పడానికి). పరిధీయ గడియారాన్ని ప్రారంభించే బాధ్యత కలిగిన రిజిస్టర్‌లు మాత్రమే మాకు అవసరం (పరిధీయ గడియారం ఎనేబుల్ రిజిస్టర్‌లు). మొదట, RCC యొక్క మూల చిరునామాను కనుగొనండి, ఇది "మెమరీ మ్యాప్" ప్రారంభంలో ఉంది:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు

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

ఆపై మీరు ప్లేట్‌లో ఏదైనా కనుగొనడానికి ప్రయత్నించే లింక్‌పై క్లిక్ చేయండి లేదా, మరింత ఉత్తమంగా, విభాగాల నుండి ఎనేబుల్ చేసే రిజిస్టర్‌ల వివరణల ద్వారా వెళ్లండి రిజిస్టర్లను ప్రారంభించండి. మేము RCC_APB1ENR మరియు RCC_APB2ENRలను ఎక్కడ కనుగొంటాము:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు

మరియు అవి, తదనుగుణంగా, SPI2, IOPB (I/O పోర్ట్ B) మరియు ప్రత్యామ్నాయ విధులు (AFIO) యొక్క క్లాకింగ్‌ను కలిగి ఉన్న బిట్‌లను కలిగి ఉంటాయి.

#define _APB2ENR 0x18
#define _APB1ENR 0x1C

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

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

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

చివరి కోడ్ కనుగొనవచ్చు ఇక్కడ.

మీకు పరీక్షించడానికి అవకాశం మరియు కోరిక ఉంటే, DAM634ని ఇలా కనెక్ట్ చేయండి: DAI నుండి PB15, DCK నుండి PB13, LAT నుండి PB14. మేము 5 వోల్ట్ల నుండి డ్రైవర్ను శక్తివంతం చేస్తాము, మైదానాలను కనెక్ట్ చేయడం మర్చిపోవద్దు.

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు

STM8 PWM

STM8పై PWM

నేను ఇప్పుడే ఈ కథనాన్ని ప్లాన్ చేస్తున్నప్పుడు, డేటాషీట్‌ను మాత్రమే ఉపయోగించి తెలియని చిప్ యొక్క కొంత కార్యాచరణను నేర్చుకోవాలని నేను ఒక ఉదాహరణగా నిర్ణయించుకున్నాను, తద్వారా నేను బూట్‌లు లేకుండా షూమేకర్‌తో ముగియను. STM8 ఈ పాత్రకు అనువైనది: మొదట, నేను STM8S103తో రెండు చైనీస్ బోర్డులను కలిగి ఉన్నాను మరియు రెండవది, ఇది చాలా ప్రజాదరణ పొందలేదు మరియు అందువల్ల ఇంటర్నెట్‌లో చదివి పరిష్కారాన్ని కనుగొనాలనే టెంప్టేషన్ ఈ పరిష్కారాల కొరతపై ఆధారపడి ఉంటుంది.

చిప్ కూడా ఉంది సమాచార పట్టిక и రిఫరెన్స్ మాన్యువల్ RM0016, మొదటిదానిలో పిన్అవుట్ మరియు రిజిస్టర్ చిరునామాలు ఉన్నాయి, రెండవది - మిగతావన్నీ. STM8 భయంకరమైన IDEలో Cలో ప్రోగ్రామ్ చేయబడింది ST విజువల్ డెవలప్.

క్లాకింగ్ మరియు I/O

డిఫాల్ట్‌గా, STM8 2 MHz ఫ్రీక్వెన్సీలో పనిచేస్తుంది, ఇది వెంటనే సరిదిద్దబడాలి.

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
HSI (హై స్పీడ్ ఇంటర్నల్) గడియారం
HSI క్లాక్ సిగ్నల్ ప్రోగ్రామబుల్ డివైడర్ (16 నుండి 1)తో అంతర్గత 8 MHz RC ఓసిలేటర్ నుండి తీసుకోబడింది. ఇది క్లాక్ డివైడర్ రిజిస్టర్ (CLK_CKDIVR)లో సెట్ చేయబడింది.
గమనిక: ప్రారంభంలో, 8 యొక్క డివైడర్‌తో HSI RC ఓసిలేటర్ క్లాక్ సిగ్నల్ యొక్క లీడింగ్ సోర్స్‌గా ఎంపిక చేయబడింది.

మేము డేటాషీట్‌లో రిజిస్టర్ చిరునామాను, refmanలో వివరణను కనుగొంటాము మరియు రిజిస్టర్‌ను క్లియర్ చేయాల్సిన అవసరం ఉందని చూస్తాము:

#define CLK_CKDIVR *(volatile uint8_t *)0x0050C6

CLK_CKDIVR &= ~(0x18);

మేము PWMని అమలు చేసి LED లను కనెక్ట్ చేయబోతున్నాము కాబట్టి, పిన్అవుట్‌ను చూద్దాం:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు

చిప్ చిన్నది, ఒకే పిన్స్‌లో అనేక విధులు నిలిపివేయబడతాయి. చదరపు బ్రాకెట్లలో ఉన్నది “ప్రత్యామ్నాయ కార్యాచరణ”, ఇది “ఆప్షన్ బైట్‌లు” ద్వారా మార్చబడుతుంది (ఎంపిక బైట్లు) – Atmega ఫ్యూజులు లాంటివి. మీరు వారి విలువలను ప్రోగ్రామాటిక్‌గా మార్చవచ్చు, కానీ ఇది అవసరం లేదు, ఎందుకంటే రీబూట్ చేసిన తర్వాత మాత్రమే కొత్త ఫంక్షనాలిటీ యాక్టివేట్ అవుతుంది. ఈ బైట్‌లను మార్చగల ST విజువల్ ప్రోగ్రామర్ (విజువల్ డెవలప్‌తో డౌన్‌లోడ్ చేయబడింది)ని ఉపయోగించడం సులభం. మొదటి టైమర్ యొక్క CH1 మరియు CH2 పిన్‌లు స్క్వేర్ బ్రాకెట్లలో దాగి ఉన్నాయని పిన్అవుట్ చూపిస్తుంది; STVPలో AFR1 మరియు AFR0 బిట్‌లను సెట్ చేయడం అవసరం, మరియు రెండవది రెండవ టైమర్ యొక్క CH1 అవుట్‌పుట్‌ను PD4 నుండి PC5కి బదిలీ చేస్తుంది.

అందువలన, 6 పిన్స్ LED లను నియంత్రిస్తాయి: మొదటి టైమర్ కోసం PC6, PC7 మరియు PC3, రెండవదానికి PC5, PD3 మరియు PA3.

I/O పిన్‌లను STM8లో సెటప్ చేయడం STM32లో కంటే సరళమైనది మరియు మరింత లాజికల్‌గా ఉంటుంది:

  • Atmega DDR డేటా దిశ రిజిస్టర్ నుండి సుపరిచితం (డేటా దిశ రిజిస్టర్): 1 = అవుట్పుట్;
  • మొదటి నియంత్రణ రిజిస్టర్ CR1, అవుట్‌పుట్ చేసినప్పుడు, పుష్-పుల్ మోడ్ (1) లేదా ఓపెన్ డ్రెయిన్ (0) సెట్ చేస్తుంది; నేను LED లను కాథోడ్‌లతో చిప్‌కి కనెక్ట్ చేసినందున, నేను సున్నాలను ఇక్కడ వదిలివేస్తాను;
  • రెండవ నియంత్రణ రిజిస్టర్ CR2, అవుట్‌పుట్ చేసినప్పుడు, గడియార వేగాన్ని సెట్ చేస్తుంది: 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

PWM సెట్టింగ్

ముందుగా, నిబంధనలను నిర్వచిద్దాం:

  • పిడబ్ల్యుఎం ఫ్రీక్వెన్సీ - టైమర్ టిక్ చేసే ఫ్రీక్వెన్సీ;
  • ఆటో-రీలోడ్, AR - టైమర్ లెక్కించబడే వరకు ఆటోలోడ్ చేయగల విలువ (పల్స్ వ్యవధి);
  • అప్‌డేట్ ఈవెంట్, UEV - టైమర్ ARకి లెక్కించబడినప్పుడు సంభవించే సంఘటన;
  • PWM డ్యూటీ సైకిల్ - PWM డ్యూటీ సైకిల్, తరచుగా "డ్యూటీ ఫ్యాక్టర్" అని పిలుస్తారు;
  • క్యాప్చర్/విలువ సరిపోల్చండి - క్యాప్చర్/పోలిక కోసం విలువ, టైమర్ లెక్కించబడినది ఏదో ఒకటి చేస్తాడు (PWM విషయంలో, ఇది అవుట్‌పుట్ సిగ్నల్‌ను విలోమం చేస్తుంది);
  • ప్రీలోడ్ విలువ - ప్రీలోడెడ్ విలువ. విలువను సరిపోల్చండి టైమర్ టిక్ చేస్తున్నప్పుడు మార్చలేరు, లేకపోతే PWM చక్రం విరిగిపోతుంది. అందువల్ల, కొత్త ప్రసారం చేయబడిన విలువలు బఫర్‌లో ఉంచబడతాయి మరియు టైమర్ దాని కౌంట్‌డౌన్ ముగింపుకు చేరుకున్నప్పుడు మరియు రీసెట్ చేయబడినప్పుడు తీసివేయబడతాయి;
  • అంచుతో సమలేఖనం చేయబడింది и మధ్యలో సమలేఖనం చేయబడిన మోడ్‌లు - సరిహద్దు వెంబడి మరియు మధ్యలో అమరిక, Atmel మాదిరిగానే ఫాస్ట్ పిడబ్ల్యుఎం и దశ-సరైన PWM.
  • OCiREF, అవుట్‌పుట్ కంపేర్ రిఫరెన్స్ సిగ్నల్ - రిఫరెన్స్ అవుట్‌పుట్ సిగ్నల్, వాస్తవానికి, PWM మోడ్‌లోని సంబంధిత పిన్‌లో ఏమి కనిపిస్తుంది.

పిన్అవుట్ నుండి ఇప్పటికే స్పష్టంగా ఉన్నట్లుగా, రెండు టైమర్లు PWM సామర్థ్యాలను కలిగి ఉంటాయి - మొదటి మరియు రెండవది. రెండూ 16-బిట్, మొదటిది చాలా అదనపు లక్షణాలను కలిగి ఉంది (ముఖ్యంగా, ఇది పైకి మరియు క్రిందికి లెక్కించవచ్చు). మేము ఇద్దరూ సమానంగా పని చేయాలి, కాబట్టి నేను స్పష్టంగా పేద రెండవదానితో ప్రారంభించాలని నిర్ణయించుకున్నాను, తద్వారా అక్కడ లేనిదాన్ని అనుకోకుండా ఉపయోగించకూడదు. కొన్ని సమస్య ఏమిటంటే, రిఫరెన్స్ మాన్యువల్‌లోని అన్ని టైమర్‌ల యొక్క PWM కార్యాచరణ యొక్క వివరణ మొదటి టైమర్ (17.5.7 PWM మోడ్) గురించిన అధ్యాయంలో ఉంది, కాబట్టి మీరు అన్ని సమయాలలో పత్రం అంతటా ముందుకు వెనుకకు వెళ్లాలి.

Atmegaపై PWM కంటే STM8పై PWMకి ముఖ్యమైన ప్రయోజనం ఉంది:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
సరిహద్దు సమలేఖనం PWM
ఖాతా కాన్ఫిగరేషన్ దిగువ నుండి పైకి
TIM_CR1 రిజిస్టర్‌లోని DIR బిట్ క్లియర్ చేయబడితే బాటమ్-అప్ కౌంటింగ్ సక్రియంగా ఉంటుంది
ఉదాహరణకు
ఉదాహరణ మొదటి PWM మోడ్‌ను ఉపయోగిస్తుంది. PWM రిఫరెన్స్ సిగ్నల్ OCiREF TIM1_CNT < TIM1_CCRi ఉన్నంత వరకు ఎక్కువగా ఉంచబడుతుంది. లేకపోతే అది తక్కువ స్థాయిని తీసుకుంటుంది. TIM1_CCRI రిజిస్టర్‌లోని పోలిక విలువ ఆటోలోడ్ విలువ (TIM1_ARR రిజిస్టర్) కంటే ఎక్కువగా ఉంటే, OCiREF సిగ్నల్ 1 వద్ద ఉంచబడుతుంది. పోలిక విలువ 0 అయితే, OCiREF సున్నా వద్ద ఉంచబడుతుంది....

సమయంలో STM8 టైమర్ నవీకరణ ఈవెంట్ మొదట తనిఖీ చేస్తుంది విలువను సరిపోల్చండి, మరియు అప్పుడు మాత్రమే సూచన సంకేతాన్ని ఉత్పత్తి చేస్తుంది. Atmega టైమర్ మొదట స్క్రూ అప్ చేసి, ఆపై పోల్చి చూస్తుంది compare value == 0 అవుట్‌పుట్ ఒక సూది, ఇది ఏదో ఒకవిధంగా పరిష్కరించబడాలి (ఉదాహరణకు, లాజిక్‌ను ప్రోగ్రామాటిక్‌గా విలోమం చేయడం ద్వారా).

కాబట్టి మనం ఏమి చేయాలనుకుంటున్నాము: 8-బిట్ PWM (AR == 255), దిగువ నుండి పైకి లెక్కింపు, సరిహద్దు వెంట అమరిక. లైట్ బల్బులు కాథోడ్‌ల ద్వారా చిప్‌కి కనెక్ట్ చేయబడినందున, PWM 0 (LED ఆన్) వరకు అవుట్‌పుట్ చేయాలి విలువను సరిపోల్చండి మరియు 1 తర్వాత.

మేము ఇప్పటికే కొన్నింటి గురించి చదివాము PWM మోడ్, కాబట్టి మేము ఈ పదబంధం (18.6.8 - TIMx_CCMR1) కోసం రిఫరెన్స్ మాన్యువల్‌లో శోధించడం ద్వారా రెండవ టైమర్ యొక్క అవసరమైన రిజిస్టర్‌ను కనుగొంటాము:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
110: మొదటి PWM మోడ్ – దిగువ నుండి పైకి లెక్కించేటప్పుడు, TIMx_CNT < TIMx_CCR1 అయితే మొదటి ఛానెల్ సక్రియంగా ఉంటుంది. లేకపోతే, మొదటి ఛానెల్ నిష్క్రియంగా ఉంటుంది. [ఇంకా పత్రంలో టైమర్ 1 నుండి తప్పు కాపీ-పేస్ట్ ఉంది] 111: రెండవ PWM మోడ్ – దిగువ నుండి పైకి లెక్కించేటప్పుడు, TIMx_CNT < TIMx_CCR1 అయితే మొదటి ఛానెల్ క్రియారహితంగా ఉంటుంది. లేకపోతే, మొదటి ఛానెల్ సక్రియంగా ఉంటుంది.

LED లు కాథోడ్‌ల ద్వారా MKకి కనెక్ట్ చేయబడినందున, రెండవ మోడ్ మాకు సరిపోతుంది (మొదటిది కూడా, కానీ మాకు ఇంకా తెలియదు).

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
బిట్ 3 OC1PE: పిన్ 1 ప్రీలోడ్‌ను ప్రారంభించండి
0: TIMx_CCR1లో ప్రీలోడ్ రిజిస్టర్ నిలిపివేయబడింది. మీరు ఎప్పుడైనా TIMx_CCR1కి వ్రాయవచ్చు. కొత్త విలువ వెంటనే పని చేస్తుంది.
1: TIMx_CCR1లో ప్రీలోడ్ రిజిస్టర్ ప్రారంభించబడింది. రీడ్/రైట్ ఆపరేషన్‌లు ప్రీలోడ్ రిజిస్టర్‌ను యాక్సెస్ చేస్తాయి. ప్రతి నవీకరణ ఈవెంట్ సమయంలో ముందుగా లోడ్ చేయబడిన విలువ TIMx_CCR1 షాడో రిజిస్టర్‌లో లోడ్ చేయబడుతుంది.
*గమనిక: PWM మోడ్ సరిగ్గా పనిచేయాలంటే, ప్రీలోడ్ రిజిస్టర్‌లు తప్పనిసరిగా ప్రారంభించబడాలి. సింగిల్ సిగ్నల్ మోడ్‌లో ఇది అవసరం లేదు (OPM బిట్ TIMx_CR1 రిజిస్టర్‌లో సెట్ చేయబడింది).

సరే, రెండవ టైమర్ యొక్క మూడు ఛానెల్‌ల కోసం మనకు అవసరమైన ప్రతిదాన్ని ఆన్ చేద్దాం:

#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 రెండు ఎనిమిది-బిట్ రిజిస్టర్లను కలిగి ఉంటుంది, ప్రతిదీ చాలా సులభం:

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

TIM2_ARRH = 0;
TIM2_ARRL = 255;

రెండవ టైమర్ దిగువ నుండి పైకి మాత్రమే లెక్కించబడుతుంది, సరిహద్దు వెంట అమరిక, ఏమీ మార్చవలసిన అవసరం లేదు. ఫ్రీక్వెన్సీ డివైడర్‌ను ఉదాహరణకు, 256కి సెట్ చేద్దాం. రెండవ టైమర్ కోసం, డివైడర్ TIM2_PSCR రిజిస్టర్‌లో సెట్ చేయబడింది మరియు ఇది రెండు పవర్‌లు:

#define TIM2_PSCR  *(volatile uint8_t *)0x00530E

TIM2_PSCR = 8;

ముగింపులు మరియు రెండవ టైమర్‌ను ఆన్ చేయడం మాత్రమే మిగిలి ఉంది. మొదటి సమస్య రిజిస్టర్ల ద్వారా పరిష్కరించబడుతుంది క్యాప్చర్ / సరిపోల్చండి ప్రారంభించు: వాటిలో రెండు, మూడు ఛానెల్‌లు అసమానంగా చెల్లాచెదురుగా ఉన్నాయి. ఇక్కడ మనం సిగ్నల్ యొక్క ధ్రువణతను మార్చడం సాధ్యమవుతుందని కూడా తెలుసుకోవచ్చు, అనగా. సూత్రప్రాయంగా, PWM మోడ్ 1ని ఉపయోగించడం సాధ్యమైంది. మేము వ్రాస్తాము:

#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;

చివరకు, మేము TIMx_CR1 రిజిస్టర్‌లో టైమర్‌ను ప్రారంభిస్తాము:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు

#define TIM2_CR1   *(volatile uint8_t *)0x005300

TIM2_CR1 |= 1;

అనలాగ్‌రైట్ () యొక్క సరళమైన అనలాగ్‌ని వ్రాద్దాం, ఇది పోలిక కోసం టైమర్‌కు వాస్తవ విలువలను బదిలీ చేస్తుంది. రిజిస్టర్లు ఊహాజనితంగా పేరు పెట్టబడ్డాయి రిజిస్టర్‌లను క్యాప్చర్/పోల్చండి, ప్రతి ఛానెల్‌కు వాటిలో రెండు ఉన్నాయి: TIM8_CCRxLలో తక్కువ-ఆర్డర్ 2 బిట్‌లు మరియు TIM2_CCRxHలో అధిక-ఆర్డర్. మేము 8-బిట్ PWMని సృష్టించాము కాబట్టి, తక్కువ ముఖ్యమైన బిట్‌లను మాత్రమే వ్రాస్తే సరిపోతుంది:

#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;
}

శ్రద్ధగల రీడర్ మేము కొద్దిగా లోపభూయిష్ట PWMని కలిగి ఉన్నామని, 100% పూరకాన్ని ఉత్పత్తి చేయలేకపోవడాన్ని గమనించవచ్చు (గరిష్ట విలువ 255 వద్ద, ఒక టైమర్ సైకిల్ కోసం సిగ్నల్ విలోమించబడుతుంది). LED ల కోసం ఇది పట్టింపు లేదు, మరియు శ్రద్ధగల రీడర్ దీన్ని ఎలా పరిష్కరించాలో ఇప్పటికే ఊహించవచ్చు.

రెండవ టైమర్‌లో PWM పని చేస్తుంది, మొదటిదానికి వెళ్దాం.

మొదటి టైమర్ అదే రిజిస్టర్‌లలో సరిగ్గా అదే బిట్‌లను కలిగి ఉంది (రెండవ టైమర్‌లో "రిజర్వ్ చేయబడిన" బిట్‌లు అన్ని రకాల అధునాతన విషయాల కోసం మొదటిదానిలో చురుకుగా ఉపయోగించబడతాయి). అందువల్ల, డేటాషీట్‌లో అదే రిజిస్టర్‌ల చిరునామాలను కనుగొని కోడ్‌ను కాపీ చేస్తే సరిపోతుంది. సరే, ఫ్రీక్వెన్సీ డివైడర్ విలువను మార్చండి, ఎందుకంటే... మొదటి టైమర్ రెండు రిజిస్టర్‌లలో ఖచ్చితమైన 16-బిట్ విలువను పొందాలనుకుంటున్నారు ప్రీస్కేలర్ హై и తక్కువ. మేము ప్రతిదీ చేస్తాము మరియు... మొదటి టైమర్ పని చేయదు. ఏంటి విషయం?

టైమర్ 1 యొక్క కంట్రోల్ రిజిస్టర్‌ల గురించి మొత్తం విభాగాన్ని చూడటం ద్వారా మాత్రమే సమస్య పరిష్కరించబడుతుంది, ఇక్కడ మేము రెండవ టైమర్ లేని దాని కోసం చూస్తాము. అక్కడ ఉంటుంది 17.7.30 బ్రేక్ రిజిస్టర్ (TIM1_BKR), ఈ బిట్ ఎక్కడ ఉంది:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
ప్రధాన అవుట్‌పుట్‌ని ప్రారంభించండి

#define TIM1_BKR   *(volatile uint8_t *)0x00526D

TIM1_BKR = (1<<7);

ఇప్పుడు ఖచ్చితంగా అంతే, కోడ్ అక్కడ.

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు

STM8 మల్టీప్లెక్స్

STM8లో మల్టీప్లెక్సింగ్

మూడవ చిన్న-ప్రాజెక్ట్ ఎనిమిది RGB LED లను PWM మోడ్‌లో రెండవ టైమర్‌కు కనెక్ట్ చేయడం మరియు వాటిని వేర్వేరు రంగులను చూపేలా చేయడం. ఇది LED మల్టీప్లెక్సింగ్ భావనపై ఆధారపడి ఉంటుంది, అంటే మీరు LED లను చాలా త్వరగా ఆన్ మరియు ఆఫ్ చేస్తే, అవి నిరంతరం ఆన్‌లో ఉన్నట్లు మనకు కనిపిస్తుంది (దృష్టి యొక్క నిలకడ, విజువల్ పర్సెప్షన్ యొక్క జడత్వం). నేను ఒకసారి చేసాను Arduinoలో ఇలాంటివి.

పని అల్గోరిథం ఇలా కనిపిస్తుంది:

  • మొదటి RGB LED యొక్క యానోడ్ కనెక్ట్ చేయబడింది;
  • దానిని వెలిగించి, కాథోడ్‌లకు అవసరమైన సంకేతాలను పంపడం;
  • PWM చక్రం ముగిసే వరకు వేచి ఉంది;
  • రెండవ RGB LED యొక్క యానోడ్ కనెక్ట్ చేయబడింది;
  • వెలిగించండి...

బాగా, మొదలైనవి. వాస్తవానికి, అందమైన ఆపరేషన్ కోసం యానోడ్ కనెక్ట్ చేయబడి, అదే సమయంలో LED "మండిపోతుంది". బాగా, లేదా దాదాపు. ఏదైనా సందర్భంలో, మేము రెండవ టైమర్ యొక్క మూడు ఛానెల్‌లలో విలువలను అవుట్‌పుట్ చేసే కోడ్‌ను వ్రాయాలి, UEV చేరుకున్నప్పుడు వాటిని మార్చండి మరియు అదే సమయంలో ప్రస్తుతం సక్రియంగా ఉన్న RGB LEDని మార్చండి.

LED స్విచింగ్ స్వయంచాలకంగా ఉన్నందున, మేము "వీడియో మెమరీ"ని సృష్టించాలి, దీని నుండి అంతరాయ హ్యాండ్లర్ డేటాను స్వీకరిస్తుంది. ఇది సాధారణ శ్రేణి:

uint8_t colors[8][3];

నిర్దిష్ట LED యొక్క రంగును మార్చడానికి, ఈ శ్రేణిలో అవసరమైన విలువలను వ్రాయడానికి సరిపోతుంది. మరియు వేరియబుల్ క్రియాశీల LED సంఖ్యకు బాధ్యత వహిస్తుంది

uint8_t cnt;

డెమక్స్

సరైన మల్టీప్లెక్సింగ్ కోసం, మనకు CD74HC238 డీమల్టిప్లెక్సర్ అవసరం. Demultiplexer - హార్డ్‌వేర్‌లో ఆపరేటర్‌ను అమలు చేసే చిప్ <<. మూడు ఇన్‌పుట్ పిన్‌ల ద్వారా (బిట్‌లు 0, 1 మరియు 2) మేము దానికి మూడు-బిట్ నంబర్ Xని ఫీడ్ చేస్తాము మరియు ప్రతిస్పందనగా ఇది అవుట్‌పుట్ నంబర్‌ని సక్రియం చేస్తుంది (1<<X) చిప్ యొక్క మిగిలిన ఇన్‌పుట్‌లు మొత్తం డిజైన్‌ను స్కేల్ చేయడానికి ఉపయోగించబడతాయి. మైక్రోకంట్రోలర్ యొక్క ఆక్రమిత పిన్‌ల సంఖ్యను తగ్గించడానికి మాత్రమే కాకుండా, భద్రత కోసం కూడా మాకు ఈ చిప్ అవసరం - కాబట్టి అనుకోకుండా సాధ్యమైనంత ఎక్కువ LED లను ఆన్ చేయకూడదు మరియు MK ని బర్న్ చేయకూడదు. చిప్ ఒక పెన్నీ ఖర్చవుతుంది మరియు ఎల్లప్పుడూ మీ హోమ్ మెడిసిన్ క్యాబినెట్‌లో ఉంచాలి.

కావలసిన LED యొక్క యానోడ్‌కు వోల్టేజ్ సరఫరా చేయడానికి మా CD74HC238 బాధ్యత వహిస్తుంది. పూర్తిస్థాయి మల్టీప్లెక్స్‌లో, ఇది P-MOSFET ద్వారా కాలమ్‌కు వోల్టేజ్‌ని సరఫరా చేస్తుంది, అయితే ఈ డెమోలో ఇది నేరుగా సాధ్యమవుతుంది, ఎందుకంటే దాని ప్రకారం, 20 mA గీస్తుంది నిరపేక్ష గరిష్ట రేటింగులు డేటాషీట్‌లో. నుండి డేటాషీట్ CD74HC238 మాకు పిన్‌అవుట్‌లు మరియు ఈ చీట్ షీట్ అవసరం:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
H = అధిక వోల్టేజ్ స్థాయి, L = తక్కువ వోల్టేజ్ స్థాయి, X – పట్టించుకోవద్దు

మేము E2 మరియు E1లను భూమికి, E3, A0, A1 మరియు A3లను STM5 యొక్క PD3, PC4, PC5 మరియు PC8 పిన్స్‌లకు కనెక్ట్ చేస్తాము. ఎగువ పట్టిక తక్కువ మరియు అధిక స్థాయిలను కలిగి ఉన్నందున, మేము ఈ పిన్‌లను పుష్-పుల్ పిన్‌లుగా కాన్ఫిగర్ చేస్తాము.

PWM

రెండవ టైమర్‌లోని PWM మునుపటి కథనంలో వలె రెండు తేడాలతో కాన్ఫిగర్ చేయబడింది:

ముందుగా, మనం అంతరాయాన్ని ఆన్ చేయాలి ఈవెంట్‌ని నవీకరించండి (UEV) ఇది సక్రియ LEDని టోగుల్ చేసే ఫంక్షన్‌ని పిలుస్తుంది. బిట్ మార్చడం ద్వారా ఇది జరుగుతుంది నవీకరణ అంతరాయాన్ని ప్రారంభించండి చెప్పే పేరుతో రిజిస్టర్‌లో

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
అంతరాయాన్ని ప్రారంభించు నమోదు

#define TIM2_IER   *(volatile uint8_t *)0x005303

//enable interrupt
TIM2_IER = 1;

రెండవ వ్యత్యాసం మల్టీప్లెక్సింగ్ యొక్క దృగ్విషయానికి సంబంధించినది అనుసరణ - డయోడ్ల పరాన్నజీవి గ్లో. మా విషయంలో, టైమర్, UEVలో అంతరాయాన్ని కలిగించి, టిక్ చేయడం కొనసాగుతుంది మరియు టైమర్ పిన్‌లకు ఏదైనా రాయడం ప్రారంభించే ముందు అంతరాయ హ్యాండ్లర్‌కు LED ని మార్చడానికి సమయం లేదు. దీన్ని ఎదుర్కోవడానికి, మీరు లాజిక్‌ను విలోమం చేయాలి (0 = గరిష్ట ప్రకాశం, 255 = ఏమీ వెలిగించబడదు) మరియు విపరీతమైన విధి చక్రం విలువలను నివారించండి. ఆ. UEV తర్వాత LED లు ఒక PWM సైకిల్ కోసం పూర్తిగా బయటకు వెళ్లేలా చూసుకోండి.

మారుతున్న ధ్రువణత:

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

r, g మరియు bలను 255కి సెట్ చేయడం మానుకోండి మరియు వాటిని ఉపయోగిస్తున్నప్పుడు వాటిని విలోమం చేయాలని గుర్తుంచుకోండి.

అంతరాయాలు

అంతరాయం యొక్క సారాంశం ఏమిటంటే, కొన్ని పరిస్థితులలో చిప్ ప్రధాన ప్రోగ్రామ్‌ను అమలు చేయడాన్ని ఆపివేస్తుంది మరియు కొంత బాహ్య ఫంక్షన్‌ను పిలుస్తుంది. టైమర్‌తో సహా బాహ్య లేదా అంతర్గత ప్రభావాల కారణంగా అంతరాయాలు సంభవిస్తాయి.

మేము మొదట ST విజువల్ డెవలప్‌లో ప్రాజెక్ట్‌ను సృష్టించినప్పుడు, అదనంగా main.c మేము రహస్యమైన ఫైల్‌తో విండోను అందుకున్నాము stm8_interrupt_vector.c, ప్రాజెక్ట్‌లో స్వయంచాలకంగా చేర్చబడుతుంది. ఈ ఫైల్‌లో, ప్రతి అంతరాయానికి ఒక ఫంక్షన్ కేటాయించబడుతుంది NonHandledInterrupt. మనం మన ఫంక్షన్‌ను కోరుకున్న అంతరాయానికి కట్టుబడి ఉండాలి.

డేటాషీట్‌లో అంతరాయ వెక్టర్‌ల పట్టిక ఉంది, ఇక్కడ మనకు అవసరమైన వాటిని కనుగొంటాము:

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు
13 TIM2 అప్‌డేట్/ఓవర్‌ఫ్లో
14 TIM2 క్యాప్చర్/పోల్ చేయండి

మేము UEV వద్ద LEDని మార్చాలి, కాబట్టి మనకు #13 అంతరాయం అవసరం.

దీని ప్రకారం, మొదట, ఫైల్‌లో stm8_interrupt_vector.c అంతరాయ నం. 13 (IRQ13)కి బాధ్యత వహించే ఫంక్షన్ యొక్క డిఫాల్ట్ పేరును మీ స్వంతంగా మార్చండి:

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

రెండవది, మేము ఫైల్‌ను సృష్టించాలి main.h కింది కంటెంట్‌తో:

#ifndef __MAIN_H
#define __MAIN_H

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

చివరకు, ఈ ఫంక్షన్‌ని మీలో రాయండి 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;
}

అంతరాయాలను ప్రారంభించడం మాత్రమే మిగిలి ఉంది. అసెంబ్లర్ కమాండ్ ఉపయోగించి ఇది జరుగుతుంది rim - మీరు దాని కోసం వెతకాలి ప్రోగ్రామింగ్ మాన్యువల్:

//enable interrupts
_asm("rim");

మరొక అసెంబ్లర్ కమాండ్ sim - అంతరాయాలను ఆఫ్ చేస్తుంది. "వీడియో మెమరీ"కి కొత్త విలువలు వ్రాయబడుతున్నప్పుడు అవి తప్పనిసరిగా ఆఫ్ చేయబడాలి, తద్వారా తప్పు సమయంలో ఏర్పడే అంతరాయం శ్రేణిని పాడుచేయదు.

అన్ని కోడ్ - GitHubలో.

డేటాషీట్‌లను చదవండి 2: STM32లో SPI; STM8లో PWM, టైమర్‌లు మరియు అంతరాయాలు

కనీసం ఎవరైనా ఈ వ్యాసం ఉపయోగకరంగా ఉంటే, నేను దానిని ఫలించలేదు. నేను వ్యాఖ్యలు మరియు వ్యాఖ్యలను స్వీకరించడానికి సంతోషిస్తాను, నేను ప్రతిదానికీ సమాధానం ఇవ్వడానికి ప్రయత్నిస్తాను.

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి