您的位置:

全能编程开发工程师手把手教你玩转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单片机的基本特点、使用方法,以及如何使用不同的编程方法对单片机进行控制和调试。希望本文对读者有所帮助。