STM32
实验任务1:以 STM32最小系统核心板(STM32F103C8T6)+面板板+3只_(或更多)红绿蓝LED 搭建电路,使用GPIOA/GPIOB/GPIOC端口控制LED灯,轮流闪烁,间隔时长1秒。
1)写出程序设计思路,包括GPIOx端口的各寄存器地址和详细参数;
2)用C语言寄存器方式编程实现,代码须有详细注解。
3)STM32最小系统核心板子出厂时已经焊接好了1个led灯(标注了PC13处),一般可通过此灯的点亮让编程者验证自己烧录的代码是否正常运行了。请查阅最小版电路原理图和相关资料,将这个灯也用在流水灯中,重编新程序。
LED灯的点亮
主函数:
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
while (1)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_0);
Delay_ms(500);
GPIO_SetBits(GPIOA, GPIO_Pin_0);
Delay_ms(500);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);
Delay_ms(500);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);
Delay_ms(500);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0);
Delay_ms(500);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1);
Delay_ms(500);
}
}
延时函数:
#include "stm32f10x.h"
/**
* @brief 微秒级延时
* @param xus 延时时长,范围:0~233015
* @retval 无
*/
void Delay_us(uint32_t xus)
{
SysTick->LOAD = 72 * xus; //设置定时器重装值
SysTick->VAL = 0x00; //清空当前计数值
SysTick->CTRL = 0x00000005; //设置时钟源为HCLK,启动定时器
while(!(SysTick->CTRL & 0x00010000)); //等待计数到0
SysTick->CTRL = 0x00000004; //关闭定时器
}
/**
* @brief 毫秒级延时
* @param xms 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_ms(uint32_t xms)
{
while(xms–)
{
Delay_us(1000);
}
}
/**
* @brief 秒级延时
* @param xs 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_s(uint32_t xs)
{
while(xs–)
{
Delay_ms(1000);
}
}
#ifndef __DELAY_H
#define __DELAY_H
void Delay_us(uint32_t us);
void Delay_ms(uint32_t ms);
void Delay_s(uint32_t s);
#endif
程序设计思路
硬件连接
寄存器地址和参数
GPIO寄存器:
GPIOA_BASE
= 0x40010800GPIOA_CRL
= 0x40010800 + 0x00 = 0x40010800GPIOA_BSRR
= 0x40010800 + 0x10 = 0x40010810GPIOB_BASE
= 0x40010C00GPIOB_CRL
= 0x40010C00 + 0x00 = 0x40010C00GPIOB_BSRR
= 0x40010C00 + 0x10 = 0x40010C10GPIOC_BASE
= 0x40011000GPIOC_CRL
= 0x40011000 + 0x00 = 0x40011000GPIOC_BSRR
= 0x40011000 + 0x10 = 0x40011010延时函数:
实验任务2:在实验1的基础上,改用标准外设库方式使用某个端口GPIOx端口管脚控制几个LED灯,轮流闪烁,间隔时长1秒。
1)写出工程项目创建文件夹、添加STM32标准外设库文件(*.c,*.h)的详细过程;
2)LED灯的亮/灭周期是通过软件循环延时完成的,其准确周期大致是多少呢?
在没有示波器条件下,可以使用Keil的软件仿真逻辑分析仪功能观察管脚的时序波形,更方便动态跟踪调试和定位代码故障点。 请用此功能观察GPIO端口的输出波形,并分析时序状态正确与否、高低电平转换周期(LED闪烁周期)实际为多少。
初始化GPIO
#include "stm32f10x.h"
void GPIO_Configuration(void) {
GPIO_InitTypeDef GPIO_InitStructure;
// 使能GPIOA、GPIOB、GPIOC的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
// 配置PA0为输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置PB0为输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 配置PC0为输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOC, &GPIO_InitStructure);
// 配置PC13为输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
延时函数:
void Delay(uint32_t nCount) {
for(; nCount != 0; nCount--);
}
主函数:
int main(void) {
// 初始化GPIO
GPIO_Configuration();
while (1) {
// 点亮红色LED
GPIO_SetBits(GPIOA, GPIO_Pin_0);
// 延时1秒
Delay(72000000 / 72);
// 熄灭红色LED
GPIO_ResetBits(GPIOA, GPIO_Pin_0);
// 点亮绿色LED
GPIO_SetBits(GPIOB, GPIO_Pin_0);
// 延时1秒
Delay(72000000 / 72);
// 熄灭绿色LED
GPIO_ResetBits(GPIOB, GPIO_Pin_0);
// 点亮蓝色LED
GPIO_SetBits(GPIOC, GPIO_Pin_0);
// 延时1秒
Delay(72000000 / 72);
// 熄灭蓝色LED
GPIO_ResetBits(GPIOC, GPIO_Pin_0);
// 点亮出厂自带LED
GPIO_SetBits(GPIOC, GPIO_Pin_13);
// 延时1秒
Delay(72000000 / 72);
// 熄灭出厂自带LED
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
}
}
作者:₩﹎