Tải bản đầy đủ (.pdf) (51 trang)

Thực hành lập trình vi điều khiển STM32L152 GPIO, SYSTICK TIMER, PWM, ADC

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.16 MB, 51 trang )

LẬP TRÌNH VI ĐIỀU KHIỂN STM32L152
(Sách Embedded Systems with ARM Cortex-M Microcontrollers
in Assembly Language and C (Third Edition) – Dr Yifeng Zhu )
Nội dung: Lý thuyết và mã nguồn các bài thực hành trên chip STM32L152RC
các bài GPIO, SysTick Timer, PWM và ADC

I. BÀI THỰC HÀNH CHƯƠNG 12 –GPIO (GENERAL PURPOSE
INPUT OUTPUT) - BẬT TẮT ĐÈN BẰNG NÚT NHẤN
Lab 1: Interfacing Push-button and LED Instructor: Prof. Yifeng Zhu Spring
2015
SƠ ĐỒ KHỐI:


MÃ NGUỒN BẬT TẮT LED BẲNG BUTTON
Yêu cầu : Thiết lập các chân PB.6, PB.7 là ngõ ra nối với các led xanh dương và
xanh lá, chân PA.0 là đầu vào kết nối với nút nhấn của vi điều khiển, khi nhấn nút
các đèn xanh dương và xanh lá thay đổi trạng thái.
CODE:
#include <stdint.h>
#include "stm32l1xx.h"
void GPIO_Clock_Enable(){

//enable the clock to port A,B

RCC->AHBENR |= 0x00000002;

//port B

RCC->AHBENR |=RCC_AHBENR_GPIOAEN;

// port A




}

void LED_BLUE(){

// set pin x I/O mode as GP Output.

GPIOB->MODER &=~(0x03<<(2*6));

// reset state

GPIOB->MODER |=(0x01<<(2*6));

// set pin x as a digital output. 01

GPIOB->OTYPER &=~(1<<6);

// output type push-pull .0

GPIOB->OSPEEDR &=~(0x03<<(2*6));

// set I/O speed

GPIOB->OSPEEDR |=(0x01<<(2*6));

// set mark

// set 01. 2MHz


GPIOB->PUPDR &= ~(0x03<<(2*6)); // set no pull up, no pull down.
}

void LED_GREEN() {
GPIOB->MODER &= ~(0x03<<(2*7));
GPIOB->MODER |= 0x01<<(2*7);
GPIOB->OTYPER &= ~(1<<7);
GPIOB->OSPEEDR &= ~(0x03<<(2*7));
GPIOB->OSPEEDR |= 0x01<<(2*7);
GPIOB->PUPDR &= ~(0X03<<(2*7));
}
void BUTTON_A(){
GPIOA->MODER &=~(0x03);

// set pin 0 I/O mode as GP input. 00

GPIOA->OTYPER &=~(0x1);

//output type pushpull. 0

GPIOA->OSPEEDR &=~(0x03);

//mark


GPIOA->OSPEEDR |= 0x01;
GPIOA->PUPDR &= ~(0x03);

//set 01. 2MHz
//00. no pull up, no pull down


}
int main(void){
int delay = 0;
GPIO_Clock_Enable();

//enable port A and B

LED_BLUE();

//config PA6

LED_GREEN();

//config PA7

BUTTON_A();

//config PA0

GPIOB->ODR |=1<<7;

//turn off a yellow led

GPIOB->ODR &=~(1<<6);

//turn on a blue led

while (1){
if ((GPIOA->IDR &1) ==1) {

// button is pressed
GPIOB->ODR ^=1<<6;
//change status of led 6
GPIOB->ODR ^=1<<7;
//change status of led 7
for (delay = 0; delay < 100000; delay++){} //delay for a
range time
}
};
}

II.THỰC HÀNH CHƯƠNG 14 – SYSTICK TIMER


ECE 271 Microcomputer Architecture and Applications - Lab 5: System Timer
(SysTick) Instructor: Prof. Yifeng Zhu Spring 2015

A : LÝ THUYẾT
- SysTick là một chức năng định thời được tích hợp vào phần cứng
- Là một bộ đếm xuống 24 bit - có giá trị nạp vào tối đa là 2^24 -1
- Cứ sau một khoảng thời gian khi bộ đếm đếm về 0 thì sinh ra ngắt, dựa vào đó gọi một
tác vụ xử lý ngắt
- Xung nhịp được lấy từ xung clock của lõi ARM
Công thức:
Interrupt period = (1 + SysTick_LOAD)/ Clock Frequence
Chu kỳ ngắt = (1 + Giá trị RELOAD)/ tần số xung nhịp
Trong đó giá trị lớn nhất của SysTick_LOAD = 2^24 -1 = 16777215
B : SƠ ĐÒ KHỐI VÀ MÃ NGUỒN BẬT TẮT LED BẲNG BUTTON

SƠ ĐỒ KHỐI:



MÃ NGUỒN : Bật tắt led bằng delay

#include <stdint.h>
#include "stm32l1xx.h"
uint32_t TimingDelay;
void GPIOB_Clock_Enable()


{
RCC->AHBENR |= 0x0000002;
// enable the clock to port B
}

void GPIOB_Pin_Init()
{
// set pin 6 I/O mode as general-purpose output: 01-digital output
GPIOB->MODER &= ~(0x03<<(2*6));
GPIOB->MODER |= 0x01<<(2*6);
// set bit 12
// set pin 7 I/O mode as general-purpose output: 01-digital output
GPIOB->MODER &= ~(0x03<<(2*7));
GPIOB->MODER |= 0x01<<(2*7);
// set bit 14
// set output type of pin 6 as push pull: 0-push-pull
GPIOB->OTYPER &= ~(1<<6);

// set output type of pin 7 as push pull: 0-push-pull
GPIOB->OTYPER &= ~(1<<7);


// set I/O output speed
GPIOB->OSPEEDR &= ~(0x03<<(2*6));
GPIOB->OSPEEDR |= 0x01<<(2*6);
GPIOB->PUPDR &= ~(0x03<<(2*6));
// no pull up pull down


GPIOB->OSPEEDR &= ~(0x03<<(2*7));
GPIOB->OSPEEDR |= 0x01<<(2*7);
GPIOB->PUPDR &= ~(0x03<<(2*7));
}

void SysTick_Initialize(uint32_t ticks)
{
// set MSIRANGE= 110 --> 4.194MHz
RCC->ICSCR &= ~(7 << 13);
RCC->ICSCR |= (6 << 13);
// Disable Systick IRQ and Systick counter
SysTick->CTRL = 0;

// Set reload register
SysTick->LOAD = ticks - 1;

//Set priority
//NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS)-1);

// Reset the SysTick counter value
SysTick->VAL = 0;


//Select processor clock


//1 = processor clock; 0 = external clock
SysTick->CTRL |= SysTick_CTRL_CLKSOURCE;//0x04

//Enable SysTick IRQ and SysTick Timer
SysTick->CTRL |= SysTick_CTRL_ENABLE;// 0x01

// Enables SysTick exception request
// 1 = counting down zero asserts the SysTick exception request
// 2 = counting down zero do not asserts the SysTick exception request
SysTick->CTRL |= SysTick_CTRL_TICKINT;//0x02
}

void SysTick_Handler(void) // SysTick interrupt service routine
{
if(TimingDelay !=0) // prevent it from being negative
TimingDelay--;
}

void Delay(uint32_t nTime)
{
// nTime : specifies the delay time length
TimingDelay = nTime;
while(TimingDelay!=0);
}


void Toggle(void){

GPIOB->ODR ^= 1<<6;
GPIOB->ODR ^= 1<<7;
}

int main(void){
GPIOB_Clock_Enable();
GPIOB_Pin_Init();
SysTick_Initialize(4194);

// 4194 xung nhip

GPIOB->ODR &= ~(1<<6);

// set pb 6 low

GPIOB->ODR |= 1<<7;

// set pb 7 high

while(1){
Delay(1000);
Toggle();
}

}

III. THỰC HÀNH CHƯƠNG 14 – PWM (PULSE WIDTH
MODULATION)
ECE 271 Microcomputer Architecture and Applications Lab 6: Pulse Width Modulation
Instructor: Prof. Yifeng Zhu Spring 2015



PHẦN I : LÝ THUYẾT

- PWM (Pulse with modulation) - điều chế độ rộng xung :
- Là một kỹ thuật số đơn giản dùng để điều khiển giá trị của điện áp ra tải
- Sử dụng một xung chữ nhật ngắn để nhanh chóng bật tắt nguồn điện thế ON/ OFF, tạo
giá trị điện
thế trung bình
- Phần trăm thời gian ở trạng thái ON trong một chu kỳ tỉ lệ thuận với giá trị của điện áp
xuất ra
- Bằng cách thay đổi hoặc điều chế độ rộng của xung chữ nhật, công xuất xuất ra được
hiệu chỉnh giống như đang mô
phỏng một tín hiệu liên tục.
===================================================
Có ba thông số cơ bản :
1. Prescaler : hệ số chia : có giá trị trong khoản từ 0 -> 65535
2. Counter modes : chế độ đếm - đếm tiến, đếm lùi hoặc nửa tiến nửa lùi
3. Counter period : chu kỳ đếm
====================================================
Công thức :
Duty cycle = (Ton/ Tperiod)*100
= Ton/(Ton + Toff)*100
-----------------------Fcl_cnt = Fcl_psc/(Prescaler + 1)
----------------------Thời gian tạo xung mỗi chu kỳ


Tpwm = (ARR + 1) / Fcl_cnt =
Duty cycle = CCR/(ARR + 1) *100 (mode 1)
(1 - CCR/(ARR + 1) ) *100


PHẦN II : SƠ ĐÒ KHỐI VÀ MÃ NGUỒN BẬT TẮT LED BẲNG BUTTON

SƠ ĐỒ KHỐI:



MÃ NGUỒN :
1 .Tăng giảm độ sáng đèn

#include <stdint.h>
#include "stm32l1xx.h"
uint32_t TimingDelay;

//Enable the clock port B
void GPIOB_Clock_Enable()
{
RCC->AHBENR |= 0x0000002;
}

//Enable the clock of timer 4
void GPIO_Timer4_Clock_Enable(){
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
}

//Configure GPIO pins
void GPIOB_Pin6_Init()
{
// set pin 6 I/O mode as general-purpose output: 10 -alternative function
GPIOB->MODER &= ~(0x03<<(2*6));



GPIOB->MODER |= 0x02<<(2*6);
// set bit 13
// Pin PB 6 as alternative function 2 (TIM4)
GPIOB->AFR[0] &=~(0xF<<(4*6));
GPIOB->AFR[0] |=0x02<<(4*6);

// Set I/O output speed value as 40MHz
// 400KHz(00), 2MHz(01), 10MHz(10), 40MHz(11)
GPIOB->OSPEEDR &= ~(0x03<<(2*6));
GPIOB->OSPEEDR |= 0x03<<(2*6);
// set I/O as no pull-up, no pull-down: 00
GPIOB->PUPDR &= ~(0x03<<(2*6));
// set output type of pin 6 as push pull: 0-push-pull
GPIOB->OTYPER &=~(1<<6);
}

void GPIOB_Pin7_Init(){
// set pin 7 I/O mode as general-purpose output: 01-digital output
GPIOB->MODER &= ~(0x03<<(2*7));
GPIOB->MODER |= 0x02<<(2*7);
// set bit 15
// set output type of pin 7 as push pull: 0-push-pull
GPIOB->OTYPER &= ~(1<<7);
// 400KHz(00), 2MHz(01), 10MHz(10), 40MHz(11)
GPIOB->OSPEEDR &= ~(0x03<<(2*7));


GPIOB->OSPEEDR |= 0x03<<(2*7);

// Set PB 7 as alternative function 2 (TIM4)
GPIOB->AFR[0] &=~(0xF<<(4*7));
GPIOB->AFR[0] |=0x02<<(4*7);
// set I/O as no pull-up, no pull-down: 00
GPIOB->PUPDR &= ~(0x03<<(2*7));
}

void TIM4_Init(){
//Set the prescaler value
TIM4->PSC = 63;
//Set the auto-reload value: upcounting (0->ARR), downcounting (ARR->0)
TIM4->ARR = 200-1;
//OC1M=110 for PMW Mode 1 output on channel 1
TIM4->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; //
OC1M = 110
TIM4->CCMR1 |= TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2; //
OC2M =
110

TIM4->CCMR1 |= TIM_CCMR1_OC1PE;
preload enable- 0x0008

//out put 1

TIM4->CCMR1 |= TIM_CCMR1_OC2PE;

TIM4->CR1 |= TIM_CR1_ARPE;
reload preload enable - 0x0080

// Auto-



TIM4->CCER
|= TIM_CCER_CC1E;
Enable output for channel 1- 0x001
TIM4->CCER

TIM4->EGR
// Force update

|= TIM_CCER_CC2E;

|= TIM_EGR_UG;
- 0x01

TIM4->SR
&= ~TIM_SR_UIF;
Clear the update flag - 0x0001

TIM4->DIER |= TIM_DIER_UIE;
interupt on update event -0x001

TIM4->CR1
// ENABLE counter

|= TIM_CR1_CEN;
- 0x001

}


void SysTick_Handler(void) // SysTick interrupt service routine
{
if(TimingDelay !=0) // prevent it from being negative
TimingDelay--;
}

void Delay(uint32_t nTime)
{

//

//

// Enable


// nTime : specifies the delay time length
TimingDelay = nTime;
while(TimingDelay!=0);
}

int main(void){
int i;
int brightness = 1;
int brightness_1=199;
int stepSize = 1;
GPIOB_Clock_Enable();
GPIO_Timer4_Clock_Enable();
GPIOB_Pin6_Init();
GPIOB_Pin7_Init();

TIM4_Init();
while(1){
if((brightness >= 200) || (brightness <= 0))
stepSize = -stepSize;

// Reverse

direction
brightness += stepSize;

// Change

brightness
brightness_1-=stepSize;
TIM4->CCR1 = brightness;
brightness for chanel 1

// Set


TIM4->CCR2 = brightness_1;
brightness for chanel 2
for(i=0; i<1000; i++);
}
}
2. Capture (CCR cố định)

#include <stdint.h>
#include "stm32l1xx.h"
uint32_t TimingDelay;


void TIM4_IRQHandler(void){
}

//Enable the clock port B
void GPIOB_Clock_Enable()
{
RCC->AHBENR |= 0x0000002;
}

//Enable the clock of timer 4
void GPIO_Timer4_Clock_Enable(){
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
}

// Set

// A short delay


//Configure GPIO pins
void GPIOB_Pin6_Init()
{
// set pin 6 I/O mode as general-purpose output: 10 -alternative function
GPIOB->MODER &= ~(0x03<<(2*6));
GPIOB->MODER |= 0x02<<(2*6);
// set bit 13
// Pin PB 6 as alternative function 2 (TIM4)
GPIOB->AFR[0] &=~(0xF<<(4*6));
GPIOB->AFR[0] |=0x02<<(4*6);


// Set I/O output speed value as 40MHz
// 400KHz(00), 2MHz(01), 10MHz(10), 40MHz(11)
GPIOB->OSPEEDR &= ~(0x03<<(2*6));
GPIOB->OSPEEDR |= 0x03<<(2*6);
// set I/O as no pull-up, no pull-down: 00
GPIOB->PUPDR &= ~(0x03<<(2*6));
// set output type of pin 6 as push pull: 0-push-pull
GPIOB->OTYPER &=~(1<<6);
}

void TIM4_Init(){
//Set the prescaler value


TIM4->PSC = 2097000/1000-1;
//Set the auto-reload value: upcounting (0->ARR), downcounting (ARR->0)
TIM4->ARR = 1000;

TIM4->CCR1 = 500;

//Set PWM mode 1 or mode 2 on chanel 1, channel 2
TIM4->CCMR1 |= TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1;
1 0X020 | bit 2 0x040

TIM4->CCER
|= TIM_CCER_CC1E;
Enable output for channel 1- 0x001

TIM4->CR1

// ENABLE counter
}

int main(void){
int i;
int brightness = 1;
int brightness_1=199;
int stepSize = 1;
GPIOB_Clock_Enable();

|= TIM_CR1_CEN;
- 0x001

//bit

//


GPIO_Timer4_Clock_Enable();
GPIOB_Pin6_Init();
TIM4_Init();
while(1){
}
}

IV. THỰC HÀNH CHƯƠNG 18 – ADC (ANALOG TO DIGITAL
CONVETER)
ECE 271 Microcomputer Architecture and Applications, Lab 9: Analog to Digital Converter
(ADC) Instructor: Prof. Yifeng Zhu Spring 2015


- Công cụ : Keil C 5.0
A : LÝ THUYẾT
Chuyển đổi tương tự sang số
- 3 đặc trưng
+ Tốc độ lấy mẫu
+ Độ phân giải
+ Độ tiêu tốn năng lượng
Độ phân giải càng cao thì tốc độ thực của tín hiệu càng cao nhưng tốn nhiều bộ nhớ để
lưu dữ liệu
- 3 chức năng chính:
+ Lấy mẫu : rời rạc hóa về mặt thời gian
+ Lượng tử hóa : rời rạc hóa trục biên độ
+ Mã hóa: chuyển mẫu sang mã nhị phân


Có ba thông số cơ bản :
1. Prescaler : hệ số chia : có giá trị trong khoản từ 0 -> 65535
2. Counter modes : chế độ đếm - đếm tiến, đếm lùi hoặc nửa tiến nửa lùi
3. Counter period : chu kỳ đếm

B : SƠ ĐÒ KHỐI VÀ MÃ NGUỒN
SƠ ĐỒ KHỐI:


Lập vô tận


MÃ NGUỒN :
1 . Sử dụng ADC và triết áp để thay đổi giá trị điện thế và hiển thị kết quả lên màn
hình LCD


/*
************************************************************************
*********************************
* file:

main.c

* author: xxxx,
* date:

mmm-dd-2015

* version: 1.0
* compiler: MDK 5.12
* hardware: Discovery kit with STM32L152RCT6 MCU
* description: xxxx

// @note
//

This code is for the book "Embedded Systems with ARM Cortex-M3

//

Microcontrollers in Assembly Language and C, Yifeng Zhu,


×