Nghiên cứu Khoa học
Đọc giá trị cảm biến và hiển thị lên LED 7 đoạn bằng STM32F103T8C6
Điện áp analog được đưa vào chân ADC (ví dụ PA0, PA1, PA2…).
ADC 12-bit của STM32 sẽ chuyển đổi:
ADC_Value = V_in/V_ref *4095
Trong đó:
Ví dụ:
|
Vin |
Giá trị ADC |
|
0V |
0 |
|
1.65V |
≈2048 |
|
3.3V |
4095 |
Code tham khảo:
#include "stm32f10x.h" // Device header
//#include "math.h"
uint8_t Maled[10] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};
uint8_t Tim2_flag=0;
uint8_t HC,HDV,so;
int count=0;
void delay();
void Tim2_Config();
void TIM2_IRQHandler(void);
void ADC_Config(void);
uint16_t ADC_Read(void);
void Tim3_Config(void);
void TIM3_IRQHandler(void);
uint16_t preset_speed;
int main(void)
{
int count1;
RCC->APB2ENR |=(1<<2)|(1<<4)|(1<<3);
GPIOA->CRL &= ~(0xff<<0);
GPIOA->CRL |=(8<<0)|(8<<4);
GPIOB->CRL =0;
GPIOB->CRL |=0x33333333;
GPIOB->CRH =0;
GPIOB->CRH |=0x33333333;
GPIOA->CRL |=(8<<4);
GPIOC->CRH &=~(0xf<<20);
GPIOC->CRH |=(3<<20);
// cau hin timer2 dinh thoi 100ms, quan ly bang ngat
ADC_Config();
Tim2_Config();
Tim3_Config();
//HDV=3;
while(1)
{
if(GPIOA->IDR & (1<<0))
{
while(GPIOA->IDR & (1<<0));
so++;
// HC=5;
HC=so/10;
HDV=so%10;
}
if(GPIOA->IDR & (1<<1))
{
while(GPIOA->IDR & (1<<1));
so--;
// HC=5;
HC=so/10;
HDV=so%10;
}
}
}
void delay()
{
int i;
for(i=0;i<1000;i++)
{
}
}
void Tim2_Config()
{
//dinh thoi 100ms
RCC->APB1ENR |=(1<<0); //TIM1_ENABLE=1: Kích hoat Timer 2
TIM2->PSC =8000;//Chia tan so 8 MHz xuong còn 10 kHz
TIM2->ARR =20-1;// dinh thoi 100ms
TIM2->DIER |= (1<<0);
TIM2->CR1 |=(1<<0);
NVIC_EnableIRQ(TIM2_IRQn); // Bat ngat Timer 2
}
void TIM2_IRQHandler(void)
{
if (TIM2->SR & 1<<0)
{
TIM2->SR &= ~1<<0; // Xóa co ngat
count++;
if(count==1)
{
GPIOB->ODR &= ~(0x3ff);
GPIOB->ODR |= (1 << 8); // Bat hàng chuc
GPIOB->ODR &= ~(1 << 9);
//GPIOB->ODR |=(1<<8);
GPIOB->ODR |=Maled[HC];
}
else
{
GPIOB->ODR &= ~(0x3ff);
// GPIOB->ODR |=(1<<9);
GPIOB->ODR |= (1 << 9); // Bat hàng chuc
GPIOB->ODR &= ~(1 << 8);
GPIOB->ODR |=Maled[HDV];
count=0;
}
}
}
void ADC_Config(void)
{
// Kich hoat clock cho Port A va ADC1
RCC->APB2ENR |= (1 << 2); // IOPAEN: Bat clock cho GPIOA
RCC->APB2ENR |= (1 << 9); // ADC1EN: Bat clock cho ADC1
GPIOA->CRL &= ~(0xF << (4 * 4)); // Xoa cac bit tuong ung voi PA4
// Cau hinh ADC
ADC1->SQR1 &= ~(0xF << 20);
ADC1->SQR3 &= ~(0x1F);
ADC1->SQR3 |= (4 << 0);
ADC1->SMPR2 &= ~(0x7 << (3 * 4));
ADC1->SMPR2 |= (7 << (3 * 4));
ADC1->CR2 |= (1 << 0); // ADON: Bat ADC1
ADC1->CR2 |= (1 << 2); // CAL: Bat dau hieu chuan ADC
while (ADC1->CR2 & (1 << 2)); // Doi hieu chuan hoan tat
}
//Ham doc gia tri ADC
uint16_t ADC_Read(void) {
ADC1->CR2 |= (1 << 0); // Bat ADC1 (ADON)
ADC1->CR2 |= (1 << 22); // SWSTART: Bat dau chuyen doi phan mem
GPIOC->CRH |=(1<<13);
while (!(ADC1->SR & (1 << 1)));
return ADC1->DR;
}
void Tim3_Config(void) {
// Kich hoat clock cho Timer 3
RCC->APB1ENR |= (1 << 1); // Bit 1: Kich hoat clock cho TIM3
TIM3->PSC = 8000 ; // Prescaler = 8000: PSC = 8000 - 1
TIM3->ARR = 50-1;
// Cho phep ngat khi tran
TIM3->DIER |= (1 << 0); // Bit UIE: Cho phep ngat khi tran
// Bat Timer 3
TIM3->CR1 |= (1 << 0); // Bit CEN: Bat Timer 3
// Kich hoat ngat cho TIM3 trong NVIC
NVIC_EnableIRQ(TIM3_IRQn); // Kich hoat ngat TIM3 trong NVIC
}
void TIM3_IRQHandler(void)
{
uint16_t adc_value;
if (TIM3->SR & 1<<0)
{ // Bit UIF: Kiem tra co ngat tran
//Tinh toan gia tri ADC
dc_value = ADC_Read(); // Doc gia tri ADC
preset_speed = (adc_value * 100) / 4095;
HC=preset_speed/10;
HDV=preset_speed%10;
// HC=1;
// HDV=3;
TIM3->SR &= ~(1 << 0); // Xoa co ngat tran
}
}