#include "stm32c0xx.h"
int main(void)
{
// 1. Cấp điện (Clock) cho cổng A hoạt động
// Dòng C0 dùng thanh ghi IOPENR. Cả PA0 và PA5 đều thuộc Port A nên bật bit 0.
RCC->IOPENR |= (1 << 0);
// 2. Cấu hình PA5 làm đầu ra (Output) để điều khiển LED
// Mỗi chân chiếm 2 bit trong MODER, chân 5 ứng với bit 10 và 11.
GPIOA->MODER &= ~(3 << 10); // Xóa sạch dữ liệu cũ ở bit 10, 11
GPIOA->MODER |= (1 << 10); // Ghi 01 để cấu hình làm Output
// 3. Cấu hình PA0 làm đầu vào (Input) có điện trở kéo lên (Pull-up)
// Bước a: Chỉnh PA0 về chế độ Input (Ghi 00 vào bit 0, 1)
GPIOA->MODER &= ~(3 << 0);
// Bước b: Kích hoạt điện trở Pull-up để chân PA0 luôn ở mức 1 khi không bấm
GPIOA->PUPDR &= ~(3 << 0);
GPIOA->PUPDR |= (1 << 0); // Ghi 01 để chọn Pull-up
while (1)
{
// 4. Kiểm tra nút bấm PA0 với chống dội phím (Debouncing)
if ((GPIOA->IDR & (1 << 0)) == 0) // Phát hiện tín hiệu mức 0 (đang bấm nút)
{
// Chờ một khoảng thời gian ngắn để tín hiệu cơ học ổn định
for(int i = 0; i < 50000; i++);
// Kiểm tra lại lần nữa, nếu thực sự vẫn đang bấm thì mới bật đèn
if ((GPIOA->IDR & (1 << 0)) == 0)
{
// Bật đèn PA5 (Ghi 1 vào bit 5 của thanh ghi BSRR)
GPIOA->BSRR = (1 << 5);
}
}
else
{
// Chống dội khi nhả nút để đèn tắt dứt khoát
for(int i = 0; i < 50000; i++);
if ((GPIOA->IDR & (1 << 0)) != 0) // Nếu đã nhả nút thực sự (mức 1)
{
// Tắt đèn PA5 (Ghi 1 vào bit 21 của BSRR để Reset chân 5)
GPIOA->BSRR = (1 << 21);
}
}
}
}Loading
st-nucleo-c031c6
st-nucleo-c031c6