找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1876|回复: 0
打印 上一主题 下一主题
收起左侧

基于STM32F103VE实现呼吸灯源程序

[复制链接]
跳转到指定楼层
楼主
ID:585660 发表于 2020-6-9 16:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
mian.c:
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include <stdio.h>

void delay(void)
{
                uint32_t volatile cnt = 0xFFFFF;
                while(cnt--);
}

void led_init(void)
{
                GPIO_InitTypeDef GPIO_InitStruct;                                                                         // 定义GPIO初始化结构体
        
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 开启GPIOB的时钟
        
                // PB5->LED
                GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;                                                         // 选择第5个引脚进行设置
                GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;                         // 设置该引脚为通用推挽输出模式
                GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;                        // 设置该引脚的输出频率为50MHz
                GPIO_Init(GPIOB, &GPIO_InitStruct);                                                                        // 对该引脚进行初始化
                GPIO_SetBits(GPIOB, GPIO_Pin_5);                                                                                 // LED OFF
}

void nvic_init(void)
{
                NVIC_InitTypeDef NVIC_InitStruct;                                                                                // 定义NVIC初始化结构体
        
                NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);                        // 中断优先级分组1
        
                // EXTI0中断配置
                NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;                                                // 设置EXTI0中断
                NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;        // 抢占优先级设置为0
                NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;                                        // 子优先级设置为2
                NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;                                                // 开启EXTI0中断
                NVIC_Init(&NVIC_InitStruct);                                                                                                                // 对EXTI0中断进行初始化
               
                // USART1中断配置
                NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;                                        // 设置USART1中断
                NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;        // 抢占优先级设置为0
                NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;                                        // 子优先级设置为1
                NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;                                                // 开启USART1中断
                NVIC_Init(&NVIC_InitStruct);                                                                                                                // 对USART1中断进行初始化
        
                // TIM6中断配置
                NVIC_InitStruct.NVIC_IRQChannel = TIM6_IRQn;                                                // 设置TIM6中断
                NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;        // 抢占优先级设置为0
                NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;                                        // 子优先级设置为1
                NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;                                                // 开启TIM6中断
                NVIC_Init(&NVIC_InitStruct);                                                                                                                // 对TIM6中断进行初始化
               
                // TIM3中断配置
                NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;
                NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
                NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3;
                NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
                NVIC_Init(&NVIC_InitStruct);
}

void exti_init(void)
{
                GPIO_InitTypeDef GPIO_InitStruct;                                                                         // 定义GPIO初始化结构体
                EXTI_InitTypeDef EXTI_InitStruct;                                                                                // 定义EXTI初始化结构体
        
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); // 开启GPIOA和AFIO的时钟
        
                // PA0->Key
                GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;                                                        // 选择第0个引脚进行设置
                GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;        // 设置该引脚为浮空输入模式
                GPIO_Init(GPIOA, &GPIO_InitStruct);                                                                        // 对该引脚进行初始化
               
                GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); // PA0->EXTILine0
                EXTI_InitStruct.EXTI_Line = EXTI_Line0;                                                        // 选择外部中断线0
                EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;                // 设置EXTILine0为中断模式
                EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;        // 设置触发方式为上升沿触发
                EXTI_InitStruct.EXTI_LineCmd = ENABLE;                                                        // 开启EXTILine0
                EXTI_Init(&EXTI_InitStruct);                                                                                                // 对EXTILine0进行初始化
}

void usart_init(void)
{
                USART_InitTypeDef USART_InitStruct;                                                                                        // 定义USART初始化结构体
                GPIO_InitTypeDef  GPIO_InitStruct;                                                                                        // 定义GPIO初始化结构体
        
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);        // 开启USART1的时钟
        
                // PA9->Tx
                GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;                                                                        // 选择第9个引脚进行设置
                GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;                                                // 设置该引脚为复用推挽输出
                GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;                                        // 设置该引脚输出速率为50MHz
                GPIO_Init(GPIOA, &GPIO_InitStruct);                                                                                        // 对该引脚进行初始化
        
                // PA10->Rx
                GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;                                                                        // 选择第10个引脚进行配置
                GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;                        // 设置该引脚为浮空输入模式
                GPIO_Init(GPIOA, &GPIO_InitStruct);                                                                                        // 对该引脚进行初始化
        
                // USART1配置
                USART_InitStruct.USART_BaudRate = 115200;                                                                // 设置波特率为115200
                USART_InitStruct.USART_WordLength = USART_WordLength_8b;// 设置数据位为8位
                USART_InitStruct.USART_Parity = USART_Parity_No;                                // 不使用校验位
                USART_InitStruct.USART_StopBits = USART_StopBits_1;                        // 设置1位停止位
                USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;// 关闭硬件流控制
                USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // 开启发送和接收功能
                USART_Init(USART1, &USART_InitStruct);                                                                        // 对USART1进行初始化
               
                USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);                                        // 开启USART1的接收中断
               
                USART_Cmd(USART1, ENABLE);                                                                                                                        // 开启USART1

}

// USART1发送字节函数
void usart1_sendbyte(char sendbyte)
{
                USART_SendData(USART1, sendbyte);                                                                                                                // 发送一个字节
                while(!USART_GetFlagStatus(USART1, USART_FLAG_TXE));                                // 等待数据寄存器为空
}

// USART1发送字符串函数
void usart1_sendstring(char *sendstring)
{
                uint8_t cnt = 0;
                do
                {
                                usart1_sendbyte(*(sendstring + cnt));
                                cnt++;
                }
                while(*(sendstring + cnt) != '\0');                        // 发送字符串
               
                while(!USART_GetFlagStatus(USART1, USART_FLAG_TC)); // 判断字符串是否发送完成
}

void tim_init(void)
{
                TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;                        // 定义定时器时基初始化结构体
                TIM_OCInitTypeDef TIM_OCInitStruct;                                                                        // 定义输出比较初始化结构体
                GPIO_InitTypeDef        GPIO_InitStruct;                                                        // 定义GPIO初始化结构体
        
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6 | RCC_APB1Periph_TIM3, ENABLE); // 开启TIM6和TIM3的时钟
        
                // TIM6配置
                TIM_TimeBaseStruct.TIM_Prescaler = (7200 - 1);
                TIM_TimeBaseStruct.TIM_Period = (10000 - 1);
                TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;        // 设置定时器计数模式
                TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
                TIM_TimeBaseStruct.TIM_RepetitionCounter = 0;
                TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStruct);
        
                TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);
        
                TIM_Cmd(TIM6, ENABLE);
        
                // TIM3配置
                // PB0->TIM3_CH3 PWM
                GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
                GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
                GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
                GPIO_Init(GPIOB, &GPIO_InitStruct);
               
                // TIM3时基部分
                TIM_TimeBaseStruct.TIM_Prescaler = (72 - 1);
                TIM_TimeBaseStruct.TIM_Period = (100 - 1); // 10KHz
                TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
                TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
                TIM_TimeBaseStruct.TIM_RepetitionCounter = 0;
                TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStruct);
               
                // TIM3输出比较部分
                TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; // PWM模式
                TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
                TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
                TIM_OCInitStruct.TIM_Pulse = 0;
                TIM_OC3Init(TIM3, &TIM_OCInitStruct);                // 对TIM3的CH3进行初始化
                TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); // 开启TIM3的预加载寄存器
               
                TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); // 开启TIM3的中断
               
                TIM_Cmd(TIM3, ENABLE); // 开启TIM3
               
}

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
        led_init();         // LED初始化函数
        nvic_init();        // NVIC配置函数
        exti_init();        // EXTI配置函数
        usart_init();        // USART配置函数
        tim_init();                // TIM配置函数
        
        usart1_sendstring("This is a testing\n");
        usart1_sendstring("Hello STM32\n");

  /* Infinite loop */
  while (1)
  {
  }
}
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

it.c:
// EXTI0中断服务函数
void EXTI0_IRQHandler(void)
{
                if(EXTI_GetITStatus(EXTI_Line0) != RESET) // 确保相应中断发生了
                {
                                EXTI_ClearITPendingBit(EXTI_Line0);                // 清除EXTI0中断标志位
                                
                                if(GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_5) == 0) // 判断LED引脚电平是否为0
                                {
                                                GPIO_SetBits(GPIOB, GPIO_Pin_5);                // LED OFF
                                }
                                else // GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_5) == 1
                                {
                                                GPIO_ResetBits(GPIOB, GPIO_Pin_5);        // LED ON
                                }
                }
}

uint8_t rx_buffer_flag = 0;
uint8_t rx_buffer[5] = {0};
uint8_t rx_buffer_cnt = 0;
void USART1_IRQHandler(void)
{
                uint8_t rcv_data = 0;
                if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) // 确保相应的中断发生
                {
                                USART_ClearITPendingBit(USART1, USART_IT_RXNE);                // 清除USART1接收中断位
                        
                                rcv_data = USART_ReceiveData(USART1);                                                        // 接收数据
//                                usart1_sendbyte(rcv_data);                                                                                                // 发送数据
                                if(rcv_data == 0xAA)
                                {
                                                rx_buffer_flag = 1;
                                }
                                if(rx_buffer_flag == 1)
                                {
                                                rx_buffer[rx_buffer_cnt] = rcv_data;
                                                rx_buffer_cnt++;
                                }
                                if(rx_buffer_cnt >= 4)
                                {
                                                rx_buffer_flag = 0;
                                                rx_buffer[4] = '\0';
                                                usart1_sendstring((char *)(rx_buffer + 1));
                                                rx_buffer_cnt = 0;
                                }
                                
                }
}

// TIM6中断服务函数
void TIM6_IRQHandler(void)
{
                if(TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)
                {
                                TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
                        
//                                if(GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_5) == 0) // 判断LED引脚电平是否为0
//                                {
//                                                GPIO_SetBits(GPIOB, GPIO_Pin_5);                // LED OFF
//                                }
//                                else // GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_5) == 1
//                                {
//                                                GPIO_ResetBits(GPIOB, GPIO_Pin_5);        // LED ON
//                                }
                }
}

// TIM3中断服务函数
uint8_t cnt1 = 0;
uint8_t cnt2 = 0;
uint8_t cnt_flag = 0;
void TIM3_IRQHandler(void)
{
                if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
                {
                                TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
                        
                                cnt1++;
                                if(cnt1 >= 100)
                                {
                                                cnt1 = 0;
                                                TIM3->CCR3 = cnt2;
                                                if(cnt_flag == 0)
                                                {
                                                                cnt2++;
                                                }
                                                else
                                                {
                                                                cnt2--;
                                                }
                                                if(cnt2 >= 100)
                                                {
                                                                cnt_flag = 1;
                                                }
                                                else if(cnt2 == 0)
                                                {
                                                                cnt_flag = 0;
                                                }
                                }
               
                }

}


stm32_test_20200417_呼吸灯.7z

176.35 KB, 下载次数: 21, 下载积分: 黑币 -5

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表