任务:开启时单片机回复已打开;关闭时在电脑显示已关闭;发 送 1 打开;发送 2 关闭。

本次学习是基于STM32的通用定时器结合串口,进行对LED灯闪烁的控制,使得延时函数时带来的误差性,以及消耗大量的CPU的资源,一直在循环里空跑等的浪费单片机资源的现象得到了极大的改善,最主要的是,得到了LED灯在定时器的控制下,可以暂停在当时运行状态下,再在暂停时状态开始跑动的现象。

代码的总体布局:

(这里虽然有两处警告,但是运行结果0错误,0警告,暂时还没找出是什么问题哈)

main.c

#include "stm32f10x.h"                  // Device header
#include "Serial.h"
#include "sys.h"
#include "led.h"
#include "time.h"
uint8_t RxData;
int main(void)
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//设定中断优先级分组0led_init();Serial_Init();while (1){while(Serial_GetRxFlag() == 1){  RxData = Serial_GetRxData();switch(RxData){case 1 : time3_init(7199,9999);//1s产生一次中断,用于控制LED进行闪烁NVIC_INIT();Serial_Printf("打开\r\n");break;case 2 : TIM_Cmd(TIM3,DISABLE);Serial_Printf("关闭\r\n");break;} }       }
}

在第八行对NVIC进行分组,放在主函数的目的是,让定时器和串口用到的NVIC在同一组,进而设置它们的抢占优先级,和响应优先级进行区分它们的优先级。

卡脖子的地方在于 对STM32的基本语句的基本功能,基本用法不是很熟悉:例如:想要定时器不工作时,直接关了定时器的时钟:case 2 :TIM_Cmd(TIM3,DISABLE);)

串口模块代码Seriai.h

#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>uint8_t Serial_RxData;
uint8_t Serial_RxFlag;void Serial_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//使能APB2外设时钟 打开USART1RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;发送引脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);接收引脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;// 上拉输入模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//根据 USART_InitStruct 中指定的参数初始化外设 USARTx 寄存器USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = 9600;//该成员设置了 USART 传输的波特率USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控制失能USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;//发送使能|接收使能USART_InitStructure.USART_Parity = USART_Parity_No;//奇偶失能USART_InitStructure.USART_StopBits = USART_StopBits_1;//在帧结尾传输 1 个停止位USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8 位数据USART_Init(USART1, &USART_InitStructure);/****开启RXNE标志位到NVIC的输出****/USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);/***配置 嵌套向量中断控制器(NVIC)***/NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn ;//USART1 全局中断NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x1;//响应优先级NVIC_Init(&NVIC_InitStructure);USART_Cmd(USART1, ENABLE);//使能USART串口外设
}void Serial_SendByte(uint8_t Byte)//发送一位函数
{USART_SendData(USART1, Byte);//发送数据while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//接收标志位状态
}void Serial_SendString(char *String)//发送字符串函数
{uint8_t i;for (i = 0; String[i] != '\0'; i ++){Serial_SendByte(String[i]);}
}//重定向printf函数到串口:对printf进行重定向的方式来把打印信息printf到串口助手
//fputc是printf的底层头文件
//需要加#include <stdarg.h>int fputc(int ch, FILE *f)
{Serial_SendByte(ch);return ch;
}void Serial_Printf(char *format, ...)
{char String[100];va_list arg;va_start(arg, format);vsprintf(String, format, arg);va_end(arg);Serial_SendString(String);
}uint8_t Serial_GetRxFlag(void)//接收标志位函数
{if(Serial_RxFlag == 1){Serial_RxFlag = 0;return 1;}return 0;
}uint8_t Serial_GetRxData(void)//接收到的数据
{return Serial_RxData;
}   void USART1_IRQHandler(void)//串口 1 中断服务程序
{if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET)// 接收中断状态标志位{Serial_RxData = USART_ReceiveData(USART1);//串口接收数据Serial_RxFlag = 1;USART_ClearITPendingBit(USART1, USART_IT_RXNE);//清除中断标志位}
}

在串口模块中第一个串口初始化函数中分别对单片机的发送引脚和接收引脚进行配置,及串口的基本配置,和对串口NVIC进行配置进而能实现串口的中断。

Serial.h

#ifndef __SERIAL_H
#define __SERIAL_H#include <stdio.h>void Serial_Init(void);
void Serial_SendByte(uint8_t Byte);
void Serial_SendString(char *String);
void Serial_Printf(char *format, ...);
uint8_t Serial_GetRxFlag(void);
uint8_t Serial_GetRxData(void);
#endif

led.c

#include "stm32f10x.h"                  // Device header
#include"led.h"void led_init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//通用推挽输出模式GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOC,&GPIO_InitStructure);
}

led.h

#ifndef __LED_H
#define __LED_H
#include "sys.h"#define LED0 PCout(13)void led_init(void);#endif

sys.h主要是在这里调用PC13口的LED,当然也可以是其他的接口,比如PA1可以是PAout(1)。

time.c

#include "stm32f10x.h"                  // Device header
#include "time.h"
#include "led.h"
void time3_init(u16 per,u16 pre)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3的时钟TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//TIM_CKD_DIV1是.h文件中已经定义好的,TIM_CKD_DIV1=0,也就是时钟分频因子为0TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//计数方式为向上计数TIM_TimeBaseStructure.TIM_Period=per;//周期TIM_TimeBaseStructure.TIM_Prescaler=pre;//分频系数TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能TIM3的更新中断TIM_Cmd(TIM3,ENABLE);//使能TIM3
}
void NVIC_INIT(void)
{NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;//设定中断向量   本程序为TIM3的中断NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能响应中断向量的中断响应NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x1;//配置中断向量的抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x1;//配置中断向量的响应优先级NVIC_Init(&NVIC_InitStructure);//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
}void TIM3_IRQHandler(void) //TIME3中断服务函数  需要设定中断优先级  即NVIC配置
{if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)//判断是否发生了更新(溢出)中断{TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除溢出中断标志位}LED0=!LED0;
}

time.h

#ifndef __TIME_H
#define __TIME_H
#include "sys.h"void time3_init(u16 per,u16 pre);
void NVIC_INIT(void);#endif

sys.h在这里的作用主要是为了能够方便的调用IO口,比如LED的接口为PC13

sys.h

//sys.h
#ifndef __SYS_H
#define __SYS_H
#include "stm32f10x.h"
//以下为位带操作代码,若不使用可忽略
#define BITBAND(addr, bitnum) ((addr & 0xF0000000) + 0x2000000 + ((addr & 0xFFFFF) << 5) + (bitnum << 2))
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))#define GPIOA_ODR_Addr    (GPIOA_BASE + 12) //0x4001080C
#define GPIOB_ODR_Addr    (GPIOB_BASE + 12) //0x40010C0C
#define GPIOC_ODR_Addr    (GPIOC_BASE + 12) //0x4001100C#define GPIOA_IDR_Addr    (GPIOA_BASE + 8)  //0x40010808
#define GPIOB_IDR_Addr    (GPIOB_BASE + 8)  //0x40010C08
#define GPIOC_IDR_Addr    (GPIOC_BASE + 8)  //0x40011008#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr, n)  //输出
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr, n)  //输入#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr, n)  //输出
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr, n)  //输入#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr, n)  //输出
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr, n)  //输入#endif  //__SYS_H

为减少传输过程和显示过程因的进制问题而导致的错误,Keil和串口助手进行如下配置:

补充相关NVIC知识点:

以及在参考手册中学习到的输入输出引脚的配置:

效果展示:

串口控制LED闪烁

(歉言:咳咳,拍视频手抖)

(感悟:忙活半天,发觉STM32的使用和51单片机的使用在思维上紧密联合)

(不会接线的的私聊我哦~)

STM32F103C8T6串口控制LED闪烁相关推荐

  1. STM32通过串口控制LED闪烁或者呼吸效果

    STM32通过串口控制LED闪烁或者呼吸效果 目录 STM32通过串口控制LED闪烁或者呼吸效果 1.准备工作 2.思路分析 3.实际操作 4.小结 1.准备工作 1.首先我们需要准备32的最小系统板 ...

  2. 串口控制led闪烁课程设计_排除led显示屏故障的方法及步骤

    led显示屏是目前大屏领域炙手可热的产品,能应用在不同的领域和场所:但经了解调查,我们发现,led显示屏再使用过程中可能会面临系统发生故障,导致其无法正常工作,今天华邦瀛光电就带大家了解一些关于排除l ...

  3. CC2530串口控制LED灯奇怪玩法

    CC2530串口控制LED灯奇怪玩法 实验目的:CC2530用串口从上位机发送16进制命令代码来控制LED3.4.5.6并返回相应动作 文章目录 CC2530串口控制LED灯奇怪玩法 一.串口设置 二 ...

  4. 嵌入式STM32入门之定时器控制LED闪烁与产生PWM脉冲宽度调制信号

    定时器控制LED闪烁与产生PWM脉冲宽度调制信号 一.前言 二.定时器基本介绍 (一)STM32定时器 (二)通用定时器主要功能 (三)计数器模式 (四)定时器工作原理 三.实验(1)初识定时器 (一 ...

  5. STM32F103:二.(2)串口控制LED

    串口控制LED 大概通一下流程,具体USART和NVIT后续再写 不得抱怨一句,这芯片贵的让人发吐,让我们学生党还怎么活 最近学习越学越没有动力,一点学习的心情都没,脑壳疼,先把32入门看后续写会不会 ...

  6. NE555时基电路实验(二)NE555控制LED闪烁

    NE555时基电路实验(二)NE555控制LED闪烁 实验用到的元器件: 1.NE555芯片,1片: 2. 470uF.100uF电解电容,耐压值16v,1个: 3.发光 LED,2个: 4.10千欧 ...

  7. 定时器中断控制LED闪烁(每隔1s)---普中科技开发仪

    定时器中断o,利用中断控制LED闪烁每隔1s闪烁一次(精确的1s) notes: (1)工作方式寄存器TMOD ,低四位用于To,高四位用于T1,(GATE,C/T- ,M1,M0) 一般让GATE ...

  8. 用定时器T0查询方式P0口8位控制LED闪烁

    #include<reg52.h> #define uchar unsigned char #define uint unsigned int void main (void) { uch ...

  9. STM32实现定时器控制LED闪烁

    文章目录 一.定时器介绍 二.STM32C配置项目 1.新建工程 2.配置引脚 3.配置SYS 4.配置GPIO 5.配置定时器 6.配置中断 7.时钟配置 8.创建代码 三.修改keil代码 四.实 ...

最新文章

  1. 【原创】MySQL 5.5 PROXY USER 伪装用户
  2. python flask框架发布问答平台注册页面_Python|Flask框架实现QQ账号登录
  3. 剖析数据库中重要而又常被曲解的概念
  4. cmder上传文件到服务器,wget 结合everything上传文件到服务器端(以及更改ip地址)...
  5. MySQL保存或更新 saveOrUpdate
  6. OpenStack基础知识
  7. 基本功:超全面 IO 流教程,小白也能看懂
  8. 51nod 1478 括号序列最长合法子段
  9. 关于jabber协议
  10. CF373C-Counting Kangaroos is Fun
  11. dfs和bfs走迷宫
  12. iis php mysql wiki_如何创建自己的wiki-Dokuwiki
  13. 第十二周 静态 +友元 + 动态 + 继承 + 多文件
  14. ​网易游戏实时 HTAP 计费风控平台建设
  15. Java***冒泡排序***
  16. AI一键图文生成短视频工具,文章AI自动生成视频,傻瓜式操作。
  17. 电商扣减库存_电商仓库管理的难点与解决方案
  18. Qt编写的项目作品3-输入法V2018
  19. 美团在深圳成立机器人研究院;移动发布物联网操作系统;百度Apollo公布自动驾驶最新进展|每日大事件...
  20. Hadoop HA高可用集群搭建(Hadoop+Zookeeper+HBase)

热门文章

  1. VB 极速自动备份文件助手 涉及可识别 Unicode 编码文件名
  2. kd树是怎么画出来的_你绝对猜不出这些画是怎么画出来的……
  3. i.MX6模组MYC-6ULX使用
  4. C# 创建和删除虚拟目录
  5. html mata头部标签详解
  6. CentOS服务器安装宝塔(图文详解)
  7. byr-加不加都告诉你
  8. NOI-1.5(14) 人口增长问题
  9. fat32转ntfs解决大于4G文件不能保存问题
  10. JavaScript - Date对象使用