STM32F103C8T6相关开发笔记
最近开始学习STM32 ,记录学习过程 ------------------- 路漫漫其修远兮(加油)
1.GPIO配置
2.定时器配置
3.串口配置
4.外部中断
5.定时器控制pwm sg90转动
6.系统定时器SysTick
1.GPIO 配置
GPIO_InitTypeDef GPIO_XXX ; // 根据自己所需配置的GPIO 命名
GPIO_XXX.GPIO_Mode = GPIO_Mode_Out_PP ; // 设置GPIO 的模式
GPIO_XXX.GPIO_Pin = GPIO_Pin_11 ; //所用Gpio 引脚
GPIO_XXX .GPIO_Speed = GPIO_Speed_50MHz ; // 频率 (根据自己需求配置)
GPIO_Init( GPIOB, &GPIO_XXX ); // 这句函数配置千万不要忘记了,初始化我们所配置的GPIO
2.定时器配置
通过定时器实现GPIOC 13引脚的Led 隔一秒闪烁
#include "stm32f10x.h"
// led函数GPIOC 13
void init_led(void)
{
//³õʼ»¯½á¹¹Ìå
GPIO_InitTypeDef GPIO_INIT;
//ʱÖÓº¯Êý
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE );
GPIO_INIT.GPIO_Mode = GPIO_Mode_Out_PP ;
GPIO_INIT.GPIO_Pin = GPIO_Pin_13 ;
GPIO_INIT.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOC, &GPIO_INIT);
}
//定时器初始化函数
void Time_Init(void)
{
TIM_TimeBaseInitTypeDef Time_Struct; //定时器结构体
NVIC_InitTypeDef NVIC_INIT; //中断结构体
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE) ; //使能定时器时钟
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_1 ); // 使能中断时钟
Time_Struct.TIM_ClockDivision = TIM_CKD_DIV1 ; // 一份频
Time_Struct.TIM_CounterMode = TIM_CounterMode_Up ; //向上计数
Time_Struct.TIM_Period = 10000 -1;
Time_Struct.TIM_Prescaler = 7200 -1;
TIM_TimeBaseInit( TIM2, &Time_Struct); //初始化结构体
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //中断
TIM_Cmd(TIM2 ,ENABLE);
//中断结构体配置
NVIC_INIT.NVIC_IRQChannel = TIM2_IRQn ;
NVIC_INIT.NVIC_IRQChannelCmd = ENABLE;
NVIC_INIT.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_INIT.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_INIT);
}
//主函数
int main(void)
{
Time_Init();
init_led();
GPIO_SetBits(GPIOC , GPIO_Pin_13); // 开始为高电平
while(1)
{
}
}
void TIM2_IRQHandler (void)
{
static uint16_t t = 0;
if(TIM_GetITStatus( TIM2, TIM_IT_Update) != RESET)
{
if(t % 2 == 1)
{
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
}
else
{
GPIO_SetBits(GPIOC , GPIO_Pin_13);
}
}
TIM_ClearITPendingBit( TIM2, TIM_IT_Update); //清除标志
}
3.串口配置
通过串口向PC机上面发送字符、字符串,并通过PC机上发送指令是单片机实现相应的功能。这里通过接受的字符来控制我们的led灯的开和关
#include "stm32f10x.h"
void init_led(void)
{
//³õʼ»¯½á¹¹Ìå
GPIO_InitTypeDef GPIO_INIT;
//ʱÖÓº¯Êý
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE );
GPIO_INIT.GPIO_Mode = GPIO_Mode_Out_PP ;
GPIO_INIT.GPIO_Pin = GPIO_Pin_13 ;
GPIO_INIT.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOC, &GPIO_INIT);
}
void Usart_Init(void)
{
GPIO_InitTypeDef Gpio_Init; //gpio结构体
USART_InitTypeDef Usart_Init ;//串口结构体
NVIC_InitTypeDef nvic_init; //´中断结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE); //gpio使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO ,ENABLE); //¸使能时钟复用
RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 ,ENABLE); //使能串口时钟
//gpio结构体配置
// tx a9
Gpio_Init.GPIO_Mode = GPIO_Mode_Out_PP;
Gpio_Init.GPIO_Pin = GPIO_Pin_9 ;
Gpio_Init.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA ,&Gpio_Init); //³õʼ»¯GPIO
//rx a10
Gpio_Init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
Gpio_Init.GPIO_Pin = GPIO_Pin_10 ;
GPIO_Init(GPIOA ,&Gpio_Init);
//串口结构体配置
Usart_Init.USART_BaudRate = 115200; //波特率
Usart_Init.USART_HardwareFlowControl = USART_HardwareFlowControl_None ;
Usart_Init.USART_Mode = USART_Mode_Rx | USART_Mode_Tx ; //收发均可
Usart_Init.USART_Parity = USART_Parity_No ; //ÓÅÏÈλ
Usart_Init.USART_StopBits = USART_StopBits_1; //停止为
Usart_Init.USART_WordLength = USART_WordLength_8b ; //字节
USART_Init (USART1 , &Usart_Init); //初始化函数
USART_ITConfig( USART1, USART_IT_RXNE , ENABLE); //串口中断配置
USART_Cmd (USART1 ,ENABLE ); //打开串口1
nvic_init.NVIC_IRQChannel = EXTI1_IRQn;
nvic_init.NVIC_IRQChannelCmd = ENABLE ;
nvic_init.NVIC_IRQChannelPreemptionPriority =1;
nvic_init.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&nvic_init);
}
//发送字符
void USARTSendChar(USART_TypeDef* USARTx, uint16_t Data)
{
USART_SendData(USARTx, Data);
while(USART_GetFlagStatus(USARTx ,USART_FLAG_TXE ) == RESET);
}
//发送字符串
void UsartSendStr(USART_TypeDef* USARTx, char *str)
{
uint16_t i=0;
do
{
USARTSendChar(USARTx ,*(str+i));
i++;
}while(*(str+i)!='\0');
while(USART_GetITStatus( USARTx,USART_FLAG_TC) == RESET) ; //判断是否接受完毕
}
//复用 printf
int fputc(int ch, FILE *f)
{
USART_SendData(USART1 ,(uint8_t )ch);
while(USART_GetFlagStatus(USART1 ,USART_FLAG_TXE ) == RESET);
return (ch);
}
//输入
int fgetc(FILE *f)
{
while(USART_GetFlagStatus(USART1 ,USART_FLAG_RXNE ) == RESET);
return (int)(USART_ReceiveData(USART1));
}
int main(void)
{
init_led(); //初始化led
Usart_Init();//初始化串口
// printf("stm32"); //fputc
// putchar('O');
while(1)
{
}
}
//串口中断1
void USART1_IRQHandler(void)
{
char temp;
if(USART_GetITStatus( USART1, USART_IT_RXNE) != RESET)
{
temp = USART_ReceiveData(USART1);
if( temp == 'O')
{
GPIO_ResetBits( GPIOC, GPIO_Pin_13);
USARTSENDSTR(USART1 ,"LED IS OPEN");
}
if( temp == 'C')
{
GPIO_SetBits( GPIOC,GPIO_Pin_13);
USARTSENDSTR(USART1 ,"LED IS CLOSE");
}
}
}
4.外部中断配置
通过外部中断来控制我们GPIOC 13引脚Led灯
#include "stm32f10x.h"
void init_led(void)
{
//³õʼ»¯½á¹¹Ìå
GPIO_InitTypeDef GPIO_INIT;
//ʱÖÓº¯Êý
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE );
GPIO_INIT.GPIO_Mode = GPIO_Mode_Out_PP ;
GPIO_INIT.GPIO_Pin = GPIO_Pin_13 ;
GPIO_INIT.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOC, &GPIO_INIT);
}
//外部中断
void Exti_Init(void)
{
//配置gpio
NVIC_InitTypeDef nvic_init;
EXTI_InitTypeDef exti_init ;
GPIO_InitTypeDef shake_init;
//打开gpio时钟
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA , ENABLE);
RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO , ENABLE); //复用GPIOA
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1); //外中断线配置
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//震动传感器引脚配置
shake_init.GPIO_Mode = GPIO_Mode_IPD ;//下拉电平震动
shake_init.GPIO_Pin = GPIO_Pin_1 ;
shake_init.GPIO_Speed = GPIO_Speed_10MHz ;
//2.配置EXTI外部中断
exti_init.EXTI_Line = EXTI_Line1;
exti_init.EXTI_LineCmd = ENABLE;
exti_init.EXTI_Mode = EXTI_Mode_Interrupt;
exti_init.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&exti_init);
//3.配置NVIC 中断控制器
nvic_init.NVIC_IRQChannel = EXTI1_IRQn ;
nvic_init.NVIC_IRQChannelCmd = ENABLE;
nvic_init.NVIC_IRQChannelPreemptionPriority = 1;
nvic_init.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&nvic_init);
}
int main()
{
init_led();
Exti_Init();
while(1)
{
}
}
void EXTI1_IRQHandler(void)
{
if(EXTI_GetITStatus( EXTI_Line1 ) != RESET) //判断是否发送中断
{
GPIO_ResetBits(GPIOA , GPIO_Pin_1);
Delay_1ms(1000);
GPIO_SetBits(GPIOA , GPIO_Pin_1);
}
EXTI_ClearFlag( EXTI_Line1); //清除中断
}
5.定时器控制pwm sg90转动
通过定时器调节占空比来控制sg90的转动(pwm波调节)
#include"stm32f10x.h"
void delay(uint16_t time)
{
uint16_t i = 0;
while(time --)
{
i = 12000 ;
while( i--);
}
}
void init_sg90(void)
{
GPIO_InitTypeDef GPIOINIT;
TIM_TimeBaseInitTypeDef TIMEINIT;
TIM_OCInitTypeDef OCINIT;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);//gpio时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//复用时钟
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE);//定时器时钟
GPIO_PinRemapConfig( GPIO_PartialRemap_TIM3, ENABLE); //部分映射配置
GPIOINIT.GPIO_Mode = GPIO_Mode_AF_PP;
GPIOINIT.GPIO_Pin = GPIO_Pin_5 ;
GPIOINIT.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOB, &GPIOINIT);
TIMEINIT.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割
TIMEINIT.TIM_CounterMode = TIM_CounterMode_Up ;//time向上计数模式
TIMEINIT.TIM_Period = 200 -1;//设置在下一个更新事件装入活动的自动重载数值
TIMEINIT.TIM_Prescaler = 7200 -1; //定时器时钟频率分频值
TIM_TimeBaseInit( TIM3, &TIMEINIT); //初始化定时器结构体
OCINIT.TIM_OCMode = TIM_OCMode_PWM1 ; //选择定时器模式一
OCINIT.TIM_OCPolarity = TIM_OCPolarity_Low ; //选择有效输出极性
OCINIT.TIM_OutputState = TIM_OutputState_Enable ;//比较输出使能
TIM_OC2Init( TIM3, &OCINIT); //初始化
TIM_OC2PreloadConfig( TIM3, TIM_OCPreload_Enable);
TIM_Cmd( TIM3, ENABLE); //使能
}
//主函数
int main()
{
uint16_t pwmval = 155; //设定初值
init_sg90();
while(1)
{
for( pwmval = 195 ; pwmval >= 175 ;pwmval -= 5)
{
TIM_SetCompare2( TIM3, pwmval);
delay(500);
}
}
}
6.系统定时器SysTick
通过使能系统定时器更加精确的进行定时功能,闪烁Led灯
void init_led(void)
{
//³õʼ»¯½á¹¹Ìå
GPIO_InitTypeDef GPIO_INIT;
//ʱÖÓº¯Êý
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE );
GPIO_INIT.GPIO_Mode = GPIO_Mode_Out_PP ;
GPIO_INIT.GPIO_Pin = GPIO_Pin_13 ;
GPIO_INIT.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOC, &GPIO_INIT);
}
//1us
void SysTick_1us(uint32_t us)
{
uint32_t i ;
SysTick_Config(72);
for( i = 0; i < us ; i++)
{
while(! (SysTick->CTRL) &( 1 <<16 ));
}
SysTick ->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
//1ms
void SysTick_1ms(uint32_t ms)
{
uint32_t i ;
SysTick_Config(72000);
for( i = 0; i < ms ; i++)
{
while(! (SysTick->CTRL) &( 1 <<16 ));
}
SysTick ->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
int main()
{
init_led();
GPIO_SetBits(GPIOC, GPIO_Pin_13);
while(1)
{
GPIO_ResetBits( GPIOC, GPIO_Pin_13);
SysTick_1ms(500);
GPIO_SetBits(GPIOC, GPIO_Pin_13);
SysTick_1ms(500);
}
}
冲 ---(江江stm32)