久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 10521|回復(fù): 2
收起左側(cè)

Arduino學(xué)習(xí)1-使用4017數(shù)字集成塊擴(kuò)展Arduino開關(guān)輸入端

[復(fù)制鏈接]
ID:114115 發(fā)表于 2016-4-14 02:42 | 顯示全部樓層 |閱讀模式

--用3個(gè)單片機(jī)引腳讀取10個(gè)開關(guān)狀態(tài)

作者注:此方法并非擴(kuò)展輸入腳最佳方法,如果需要大量擴(kuò)展輸入腳的話(幾十甚至上百路),可以使用74HC165或者CD4021做shiftin。而不是本文的4017。
http://playground.arduino.cc/Code/ShiftRegSN74HC165N
http://www.arduino.cc/en/Tutorial/ShiftIn


The SN74HC165N is an 8-bit parallel-load or serial-in shift registers with complementary serial outputs available from the last stage. When the parallel load (PL) input is LOW, parallel data from the D0 to D7 inputs are loaded into the register asynchronously.  When PL is HIGH, data enters the register serially at the Ds input and shifts one place to the right (Q0 → Q1 → Q2, etc.) with each positive-going clock transition. This feature allows parallel-to-serial converter expansion by tying the Q7 output to the DS input of the succeeding stage.
Breadboard SchematicThe following image shows 10 pushbuttons wired to two SN74HC165N input shift registers. Note that the 6 unused input pins are grounded.
5iErfC9.png
CodeThe following code demonstrates reading in 16 digital states from a pair of daisy-chained SN74HC165N shift registers while using only 4 digital pins on the Arduino.
  1. /*
  2. * SN74HC165N_shift_reg
  3. *
  4. * Program to shift in the bit values from a SN74HC165N 8-bit
  5. * parallel-in/serial-out shift register.
  6. *
  7. * This sketch demonstrates reading in 16 digital states from a
  8. * pair of daisy-chained SN74HC165N shift registers while using
  9. * only 4 digital pins on the Arduino.
  10. *
  11. * You can daisy-chain these chips by connecting the serial-out
  12. * (Q7 pin) on one shift register to the serial-in (Ds pin) of
  13. * the other.
  14. *
  15. * Of course you can daisy chain as many as you like while still
  16. * using only 4 Arduino pins (though you would have to process
  17. * them 4 at a time into separate unsigned long variables).
  18. *
  19. */

  20. /* How many shift register chips are daisy-chained.
  21. */
  22. #define NUMBER_OF_SHIFT_CHIPS   2

  23. /* Width of data (how many ext lines).
  24. */
  25. #define DATA_WIDTH   NUMBER_OF_SHIFT_CHIPS * 8

  26. /* Width of pulse to trigger the shift register to read and latch.
  27. */
  28. #define PULSE_WIDTH_USEC   5

  29. /* Optional delay between shift register reads.
  30. */
  31. #define POLL_DELAY_MSEC   1

  32. /* You will need to change the "int" to "long" If the
  33. * NUMBER_OF_SHIFT_CHIPS is higher than 2.
  34. */
  35. #define BYTES_VAL_T unsigned int

  36. int ploadPin        = 8;  // Connects to Parallel load pin the 165
  37. int clockEnablePin  = 9;  // Connects to Clock Enable pin the 165
  38. int dataPin         = 11; // Connects to the Q7 pin the 165
  39. int clockPin        = 12; // Connects to the Clock pin the 165

  40. BYTES_VAL_T pinValues;
  41. BYTES_VAL_T oldPinValues;

  42. /* This function is essentially a "shift-in" routine reading the
  43. * serial Data from the shift register chips and representing
  44. * the state of those pins in an unsigned integer (or long).
  45. */
  46. BYTES_VAL_T read_shift_regs()
  47. {
  48.     long bitVal;
  49.     BYTES_VAL_T bytesVal = 0;

  50.     /* Trigger a parallel Load to latch the state of the data lines,
  51.     */
  52.     digitalWrite(clockEnablePin, HIGH);
  53.     digitalWrite(ploadPin, LOW);
  54.     delayMicroseconds(PULSE_WIDTH_USEC);
  55.     digitalWrite(ploadPin, HIGH);
  56.     digitalWrite(clockEnablePin, LOW);

  57.     /* Loop to read each bit value from the serial out line
  58.      * of the SN74HC165N.
  59.     */
  60.     for(int i = 0; i < DATA_WIDTH; i++)
  61.     {
  62.         bitVal = digitalRead(dataPin);

  63.         /* Set the corresponding bit in bytesVal.
  64.         */
  65.         bytesVal |= (bitVal << ((DATA_WIDTH-1) - i));

  66.         /* Pulse the Clock (rising edge shifts the next bit).
  67.         */
  68.         digitalWrite(clockPin, HIGH);
  69.         delayMicroseconds(PULSE_WIDTH_USEC);
  70.         digitalWrite(clockPin, LOW);
  71.     }

  72.     return(bytesVal);
  73. }

  74. /* Dump the list of zones along with their current status.
  75. */
  76. void display_pin_values()
  77. {
  78.     Serial.print("Pin States:");

  79.     for(int i = 0; i < DATA_WIDTH; i++)
  80.     {
  81.         Serial.print("  Pin-");
  82.         Serial.print(i);
  83.         Serial.print(": ");

  84.         if((pinValues >> i) & 1)
  85.             Serial.print("HIGH");
  86.         else
  87.             Serial.print("LOW");

  88.         Serial.print("");
  89.     }

  90.     Serial.print("");
  91. }

  92. void setup()
  93. {
  94.     Serial.begin(9600);

  95.     /* Initialize our digital pins...
  96.     */
  97.     pinMode(ploadPin, OUTPUT);
  98.     pinMode(clockEnablePin, OUTPUT);
  99.     pinMode(clockPin, OUTPUT);
  100.     pinMode(dataPin, INPUT);

  101.     digitalWrite(clockPin, LOW);
  102.     digitalWrite(ploadPin, HIGH);

  103.     /* Read in and display the pin states at startup.
  104.     */
  105.     pinValues = read_shift_regs();
  106.     display_pin_values();
  107.     oldPinValues = pinValues;
  108. }

  109. void loop()
  110. {
  111.     /* Read the state of all zones.
  112.     */
  113.     pinValues = read_shift_regs();

  114.     /* If there was a chage in state, display which ones changed.
  115.     */
  116.     if(pinValues != oldPinValues)
  117.     {
  118.         Serial.print("*Pin value change detected*");
  119.         display_pin_values();
  120.         oldPinValues = pinValues;
  121.     }

  122.     delay(POLL_DELAY_MSEC);
  123. }
復(fù)制代碼


使用Arduino做制作,需要有一組開關(guān)控制Arduino狀態(tài)。但是Arduino引腳不多,傳統(tǒng)接法開關(guān)多了要占用很多引腳。減少引腳的方法有很多,可以選矩陣方式,編碼器方式,還有本文要介紹的分時(shí)復(fù)用開關(guān)法等。

特點(diǎn):十個(gè)開關(guān)占用三個(gè)數(shù)據(jù)引腳,之后每增加十個(gè)開關(guān)就增加一個(gè)引腳。
4017是一塊十進(jìn)制計(jì)數(shù)器,每輸入一個(gè)CLK脈沖,Q0~Q9輪流產(chǎn)生高電平。每時(shí)刻有且只有一個(gè)引腳高電平。
二極管防止多個(gè)開關(guān)閉合時(shí),有的輸出端輸出高電平,有的輸出低電平,互相接上的話,會(huì)低電平引腳會(huì)干擾高電平腳的工作。
開關(guān)用10路撥動(dòng)式小型開關(guān),或者自己選擇其他開關(guān)形式。

電路工作原理:
  • 先在RST(4017的復(fù)位腳MR)發(fā)出一個(gè)脈沖,使4017復(fù)位。
  • 此時(shí)有且只有Q0輸出高電平(Q0對應(yīng)開關(guān)S1,Q9對應(yīng)開關(guān)S10),讀取一次輸出信號DATA。如果第一個(gè)開關(guān)S1閉合了,應(yīng)該DATA得到高電平;如果S1斷開了,就DATA得到低電平。此時(shí)記DATA結(jié)果對應(yīng)第一個(gè)開關(guān)S1的狀態(tài)。
  • 給CLK輸出一個(gè)脈沖,讓4017移位,有且只有Q1輸出高電平(Q0,Q2~Q9均為低電平)。讀取DATA。得到S2狀態(tài)。
  • 不斷給CLK脈沖。總共給10次脈沖,讓4017由Q0移動(dòng)到Q9,完成一次開關(guān)遍歷,每次移動(dòng)獲取一次DATA狀態(tài)。存為S1~S10狀態(tài)。

電路原理圖如圖:
00300057evq6q1y11llve1.gif

洞洞板圖(由于引腳多,不建議面包板制作。)
003000tah7jzwahibtvvhv.gif

關(guān)于在一塊Arduino上使用多塊模塊:每增加一塊模塊,可以增加十路開關(guān)(當(dāng)然你也可以使用兩塊4017做成行列矩陣控制100個(gè)開關(guān)。不過那個(gè)就屬于另外話題了)。增加的方式是將兩塊模塊的RST,CLK,VCC,GND接在一起,接到單片機(jī)的相應(yīng)引腳,然后兩個(gè)模塊的DATA腳分別接單片機(jī)兩個(gè)IO口。
003001z4jccaasf8bs8p3u.gif
Arduino程序例子:

const int rst = 2; //板子的RST腳接Arduino的D4口(自定義)
const int clk = 3; //板子的CLK腳接Arduino的D3口(自定義)
const int data1 = 4; //板子的DATA腳接Arduino的D2口(自定義)
//const int data2 = 5; //如果有第二塊板子的話,兩塊板子共用RST和CLK引腳。DATA接Arduino的D5口,第三塊板子可以類推接D6口(自定義)
void setup()
{
Serial.begin(9600);
pinMode(rst, OUTPUT);
pinMode(clk, OUTPUT);
pinMode(data1, INPUT);
//pinMode(data2,INPUT); //如果有第二塊板子的話要定義IO
}
void loop()
{
int KeyStatus[10] = {0}; //按照總開關(guān)數(shù)定義。可能要改為20,30等
digitalWrite(rst, HIGH);
delayMicroseconds(10); //所有delayMicroseconds(10);均是給4017一個(gè)反應(yīng)時(shí)間。
digitalWrite(rst, LOW);
delayMicroseconds(10);
for(int i = 0; i < 10; i++)
{
KeyStatus = digitalRead(data1);
//KeyStatus[i+10] = digitalRead(data2); //讀取第二個(gè)板子的狀態(tài),地址放在i+10
digitalWrite(clk, HIGH);
delayMicroseconds(10);
digitalWrite(clk, LOW);
delayMicroseconds(10);
}

for(int i = 0; i < 10; i++) //循環(huán)打印KeyStatus數(shù)組,i<10可能要改為i<20,30等
{
Serial.print(KeyStatus);
Serial.print("        ");
}
Serial.println();
delay(100);
}
洞洞板實(shí)物圖:

1024425oh7mddd5epahpa5.jpg
1024418fyffco8yz33zf7c.jpg
102439yj3artmurfhm2jmt.jpg

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

ID:200272 發(fā)表于 2017-5-13 13:46 | 顯示全部樓層
請問digitalWrite(rst, HIGH); 和digitalWrite(rst, LOW); 這兩句是什么意思前一個(gè)是給一個(gè)高電平,4017復(fù)位那么后面那個(gè)給一個(gè)低電平又是什么情況?還有后面設(shè)計(jì)的CLK時(shí)的那兩句,主要是不懂為什么還要再給一個(gè)低電平
回復(fù)

使用道具 舉報(bào)

ID:200272 發(fā)表于 2017-5-13 13:48 | 顯示全部樓層
你好,請問關(guān)于那個(gè)rst 和clk 的設(shè)置的問題,一開始給了一個(gè)高電平后為什么還要再給一個(gè)低電平?
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 激情一区二区三区 | 久久久精品网站 | 久久精品伊人 | 欧美日韩综合视频 | 国产精品1区2区3区 国产在线观看一区 | 黄色91在线 | 精品久久久久久久久久久久久久 | 国产精品亚洲综合 | 成人伊人| 精品三级在线观看 | 夜夜夜夜夜夜曰天天天 | www狠狠干| 国产成人精品综合 | 亚洲一区二区不卡在线观看 | 日韩av一区二区在线观看 | 日韩成人高清在线 | 午夜成人在线视频 | 色综合久久久久 | 九九热精品视频 | 欧美伦理一区 | 在线天堂免费中文字幕视频 | a免费视频 | 精品国产一区二区三区av片 | 欧美片网站免费 | 中文字幕亚洲精品在线观看 | 精品一区二区三区不卡 | 久久久久国产一区二区三区四区 | 综合国产| 精品乱码一区二区三四区 | 久久久精| 久久久久网站 | 精品亚洲一区二区三区 | 亚洲欧美一区二区在线观看 | 黄色毛片在线播放 | www.日本精品 | 国产精品日韩高清伦字幕搜索 | 精品久久久久久久久久 | 日韩综合在线 | 精品91久久 | 亚洲一区二区电影网 | 国产91在线观看 |