全能编程开发工程师手把手教你玩转STM32F103C8T6单片机

一、STM32F103C8T6单片机介绍

STM32F103C8T6是STMicroelectronics公司推出的ARM Cortex-M3系列的32位微控制器,具有高性能、低功耗、低成本等特点。该单片机核心采用Cortex-M3内核,主频为72MHz,具有64KB的Flash存储器、20KB的SRAM存储器,并提供多种通信接口、多个定时器、多个中断、以及丰富的模拟/数字转换功能。

二、STM32F103C8T6硬件编程

1. GPIO

GPIO是通用输入输出端口,可以设置为输入或输出端口,用于控制外置设备的状态。例如,我们可以通过GPIO输出高电平,点亮LED灯。

/* GPIO配置 */
GPIO_InitTypeDef GPIO_InitStructure;          //GPIO结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);         //使能GPIOA的时钟

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;          //设置引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   //设置模式为推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  //设置输出速度
GPIO_Init(GPIOA, &GPIO_InitStructure);             //初始化GPIOA

2. 中断

中断是一种异步事件,可以在单片机执行其他任务时被触发,用于处理外部事件。例如,我们可以通过外部中断来处理某些按键的输入。

/* 外部中断配置 */
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

/* 使能AFIO以及GPIOB时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);

/* 配置GPIOB.11为输入模式 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOB, &GPIO_InitStructure);

/* 关闭JTAG调试端口,开启SWD调试接口 */
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);

/* 指定外部中断1对应的GPIOB.11引脚 */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource11);

/* 配置外部中断1,上升沿触发 */
EXTI_InitStructure.EXTI_Line = EXTI_Line11;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);

/* 配置中断优先级 */
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

三、STM32F103C8T6软件编程

1. ADC

ADC是模拟/数字转换器,可以将模拟信号转换成数字信号。例如,我们可以通过ADC读取电压传感器的输出,并将其转换为数字信号进行处理。

/* ADC配置 */
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

/* 使能ADC1时钟,以及所用引脚的GPIO时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);

/* 配置ADC输入引脚PA0 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* 配置ADC1 */
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                         //单独模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE;                               //非扫描模式,一次转换一个通道
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                         //非连续转换模式
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                       //数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1;                                     //采样通道数
ADC_Init(ADC1, &ADC_InitStructure);

/* 配置ADC1的采样通道0 */
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);

/* 开启ADC1 */
ADC_Cmd(ADC1, ENABLE);

/* 启动ADC1软件转换 */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);

2. PWM

PWM是脉宽调制信号,可以调节信号高电平与低电平的时间比例,用于控制电机等设备的转速。例如,我们可以通过PWM控制舵机的角度。

/* TIM3 PWM配置 */
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
uint16_t PrescalerValue = 0;

/* 使能TIM3和GPIOB时钟 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

/* TIM3的预分频值为71,定时器时钟为1MHz */
PrescalerValue = (uint16_t) (SystemCoreClock / 1000000) - 1;

/* TIM3基本配置 */
TIM_TimeBaseStructure.TIM_Period = 1999;                   //设置周期值,为2000时,频率为500Hz
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;       //设置预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0;                //设置时钟分割:不分割
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

/* PWM通道2的GPIOB.5引脚配置 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);

/* TIM3 PWM输出通道2的配置 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;              //输出使能
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;                          //PWM2模式
TIM_OCInitStructure.TIM_Pulse = 1000;                                      //设置占空比,范围为0-1999
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;                   //设置PWM输出极性为高
TIM_OC2Init(TIM3, &TIM_OCInitStructure);

/* 启动计时器 */
TIM_Cmd(TIM3, ENABLE);

四、STM32F103C8T6调试技巧

1. 使用USART输出调试信息

USART是USART串行通信接口,可以将单片机的调试信息输出到PC上,方便调试。

/* USART1配置 */
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

/* 使能USART1和GPIOA时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

/* 将GPIOA的第9位设置为USART1_TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* 将GPIOA的第10位设置为USART1_RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* USART1基本配置 */
USART_InitStructure.USART_BaudRate = 9600;                               //波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;               //数据长度为8位
USART_InitStructure.USART_StopBits = USART_StopBits_1;                    //停止位为1个
USART_InitStructure.USART_Parity = USART_Parity_No;                       //校验位无
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  //无硬件流控
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;            //发送和接收

/* 初始化USART1 */
USART_Init(USART1, &USART_InitStructure);

/* 启动USART1 */
USART_Cmd(USART1, ENABLE);

2. 使用ST-Link进行在线调试

ST-Link是一种在线调试工具,可以实现单步调试、内存查看、断点设置等功能。

/* ST-Link配置 */
/* 使用Keil uVision5自带的ST-Link调试器进行在线调试 */

五、总结

本文从STM32F103C8T6单片机的介绍、硬件编程、软件编程、调试技巧等多个方面进行了详细的阐述。通过阅读本文,读者可以了解到STM32F103C8T6单片机的基本特点、使用方法,以及如何使用不同的编程方法对单片机进行控制和调试。希望本文对读者有所帮助。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/199052.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-04 19:13
下一篇 2024-12-04 19:13

相关推荐

  • Python中的while true:全能编程开发必知

    对于全能编程开发工程师而言,掌握Python语言是必不可少的技能之一。而在Python中,while true是一种十分重要的语句结构,本文将从多个方面对Python中的while…

    编程 2025-04-29
  • 单片机打印函数

    单片机打印是指通过串口或并口将一些数据打印到终端设备上。在单片机应用中,打印非常重要。正确的打印数据可以让我们知道单片机运行的状态,方便我们进行调试;错误的打印数据可以帮助我们快速…

    编程 2025-04-29
  • lsw2u1:全能编程开发工程师的利器

    lsw2u1是一款多功能工具,可以为全能编程开发工程师提供便利的支持。本文将从多个方面对lsw2u1做详细阐述,并给出对应代码示例。 一、快速存取代码段 在日常开发中,我们总会使用…

    编程 2025-04-29
  • 全能编程开发工程师必备技能——如何优化大整数的计算

    本文将会为你分享如何解决大整数计算问题,以9999999967为例,我们将从多个方面对其做详细阐述,并给出完整的代码示例。 一、大整数的表示方法 在计算机中,我们通常采用二进制数来…

    编程 2025-04-29
  • xkujs全能编程开发工程师

    本文将从以下几个方面详细阐述xkujs作为一名全能编程开发工程师的技术能力和实战经验,为初学者提供学习参考。 一、JavaScript基础 作为一名全能编程开发工程师,JavaSc…

    编程 2025-04-29
  • Spring Cloud Greenwich.Release:全能编程开发工程师的首选

    本文将从以下几个方面对Spring Cloud Greenwich.Release进行详细阐述,包括项目概述、核心组件、应用案例、配置和部署等,旨在为全能编程开发工程师提供更好的解…

    编程 2025-04-29
  • 全能编程开发工程师必知——DTD、XML、XSD以及DTD参数实体

    本文将从大体介绍DTD、XML以及XSD三大知识点,同时深入探究DTD参数实体的作用及实际应用场景。 一、DTD介绍 DTD是文档类型定义(Document Type Defini…

    编程 2025-04-29
  • 全能编程开发工程师必备技能:Source Where 1=1

    如果你想成为一名全能的编程开发工程师,那么掌握SQL查询语言中的Source Where 1=1是非常必要的。 一、简介 Source Where 1=1是SQL语句的一种常见写法…

    编程 2025-04-29
  • 99mav全能编程开发工程师专题

    本文介绍99mav的全能编程开发工程师的各种技能点,以及如何成为一名全能的开发工程师。 一、全面掌握编程技能 一个全能的开发工程师需要全面掌握编程技能,包括但不限于: 熟练掌握多种…

    编程 2025-04-29
  • 全能编程开发工程师:罗列出来是什么意思

    全能编程开发工程师是指在软件开发过程中能够承担多种角色,掌握多种技能,全面推进项目的人才。罗列出来意味着需要将自己所掌握的知识和技能清晰地呈现出来。在本文中,我们将从几个方面讨论如…

    编程 2025-04-29

发表回复

登录后才能评论