prettyprint

2020年7月17日 星期五

搶答遊戲按鈕設計--使用STM32F103C8T6微控制器

本篇以STM32F103C8T6微控制器來實現搶答遊戲時誰先取得答題權,因為STM32F103C8T6使用Cortex-M3處理器,因此所有的GPIO Port都可以用來作為外部中斷使用。Arduino UNO/NANO/Pro mini只有兩個數位外部中斷(D2、D3),即使Mega也只有5個(D2、D3、D19、D20與D21)。
但根據Cortex-M3硬體結構當使用PA0當外部中斷時,PB0、PC0等即無法設為外部中斷。本實驗使用PA0、PA1當搶答外部中斷,PA2為復位外部中斷。PB0與PB1連接LED顯示誰先搶到答題權。
連接按鈕部分使用硬體RC debounce線路,整個線路連接如下圖所示
完成展示影片如下,最右邊的按鈕為復位按鈕,關掉LED,回到可搶答狀態。


軟體主要使用API
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);
來設定外部中斷ISR(Interrupt Service Routine),因為按鈕設計平時為高電位,偵測按下時的Mode為FALLING。

完整程式如下:
uint16_t ip1 = PA0;
uint16_t led1 = PB0;
uint16_t ip2 = PA1;
uint16_t led2 = PB1;
uint16_t ip_init = PA2;
volatile bool i1_pressed, i2_pressed;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(ip1, INPUT);
  pinMode(ip2, INPUT);
  pinMode(ip_init, INPUT);
  led_init();
  attachInterrupt(digitalPinToInterrupt(ip1), ip1_isr, FALLING);
  attachInterrupt(digitalPinToInterrupt(ip2), ip2_isr, FALLING);
  attachInterrupt(digitalPinToInterrupt(ip_init), led_init, FALLING);
}
void led_init(void) {
  i1_pressed=false;
  i2_pressed=false;
  
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  Serial.println("ip_init");
}
void ip1_isr(void) {
  if (i2_pressed) return;
  i1_pressed=true;
  digitalWrite(led1, HIGH);
  Serial.println("ip1");
}
void ip2_isr(void) {
  if (i1_pressed) return;
  i2_pressed=true;
  digitalWrite(led2, HIGH);
  Serial.println("ip2");
}
void loop() {
  // put your main code here, to run repeatedly:
  

}

沒有留言:

張貼留言