基于STM32F103C8T6的系统定时器SysTick配置LED灯闪烁

#一、系统定时器简介
#二、SysTick定时时间的计算
#三、SysTick中断优先级
#四、SysTick的应用及其代码

一、系统定时器简介

SysTick:24位系统定时器,只能递减,存在于内核嵌套在NVIC中,所有的Cortex_M中都有这个系统定时器。

重装载值reload递减,当递减到0会触发中断并且会有置位countflag标志,VAL表示当前值,然后reload继续从预设值开始递减,周而复始。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、SysTick定时时间的计算

1.T :一个计数循环的时间,跟reload和CLK有关
2.CLK:72M或9M,由CTRL寄存器配置
3.reload:24位,用户自己配置

T=reload(1/CLk)*

CLK=72M,1us=(72)(1/72000000)
CLK=72M,1ms=(72000)
(1/72000000)

时间单位换算:1us=1000ms=1000000us=1000000000ns

三、SysTick中断优先级
1.system tick属于内核的外设,它的中断优先级配置:scb->sharx寄存器;
外设中断优先级配置的是nvic->iprx寄存器
有优先级的分组

2.STM32 的外设(内核还是片上)都是使用4个二进制来表示中断优先级
3.中断优先级的分组对内核和外设同样适用,只需要将中断优先级的四个位按外设优先级来分组即可,人为的进行分出抢占优先级和子优先级。

举例:

1<<4-1=16-1=15(1 1 1 1)

四、SysTick的应用及其代码

1)编写一个us延迟函数

2)编写一个ms延迟函数

文件新建:

1.在USER中新建文件夹SYSTEM
在这里插入图片描述
2.打开工程,在工程中新建组别
在这里插入图片描述
3.为新建的组别命名
在这里插入图片描述
4.将在USER文件夹新建的SYSTEM文件夹添加进新建组别中
在这里插入图片描述
5.在内核中调用的系统定时器使能函数 :uint32_t SysTick_Config(uint32_t ticks)
在这里插入图片描述
6.控制/状态寄存器使能
在这里插入图片描述
代码部分:

SysTick.c

#include "stm32f10x.h"
#include "systick.h"

void ms_delay(uint32_t ms)//毫秒级延迟函数
{
	  uint32_t i=0;
		SysTick_Config(72000);//定义一个循环1毫秒
	  for(i=0;i<ms;i++)
	  {
		   
			  while(!((SysTick->CTRL)&(1<<16)));
		
		}
		SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;//将控制及状态寄存器失能

}



void us_delay(uint32_t ms)//微秒级延迟函数
{
	  uint32_t i=0;
		SysTick_Config(72);//定义一个循环1微秒
	  for(i=0;i<ms;i++)
	  {
		   
			  while(!((SysTick->CTRL)&(1<<16)));
		
		}
		SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;//将控制及状态寄存器失能

}


SysTick.h

#include "stm32f10x.h"
void ms_delay(uint32_t ms);
void us_delay(uint32_t ms);

main.c

#include "stm32f10x.h"
#include "main.h"
#include "LED.h"
#include "usart.h"
#include "relay.h"
#include "shake.h"
#include "exti.h"
#include "tim.h" 
#include "motor.h"
#include "systick.h"

void delay(uint16_t time)//延迟函数
{
		uint16_t i=0;
	  while(time--)
		{
				i=12000;
			  while(i--);
		}
}



int  main()
{
	 usart_init();//串口初始化
	 LED_Init();//LED初始化
	 GPIO_SetBits(GPIOA,GPIO_Pin_1);//关灯
	
	while(1)
	{
			GPIO_ResetBits(GPIOA,GPIO_Pin_1);//开灯
		  ms_delay(500);//延时500ms
		  GPIO_SetBits(GPIOA,GPIO_Pin_1);//关灯
		  ms_delay(500);//延时500ms
		
	
	}
	 
	
	 
	 
}




	




usart.c

#include "stm32f10x.h"
#include "usart.h"
#include <stdio.h>


void usart_init(void)
{
	  
		GPIO_InitTypeDef gpioinstructure;//GPIO结构体初始化函数
	  USART_InitTypeDef usartinstructure;//USART结构体初始化函数
	  NVIC_InitTypeDef  nvicinstructure;//中断控制器结构体初始化函数
	  
	  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置中断控制器优先抢占级组
		
	//1.配置GPIO、USART、引脚复用时钟
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//配置GPIOA时钟
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//配置引脚复用时钟
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//配置USART时钟
		
	//2.配置GPIO结构体
	   
    //配置PA9 TX 输出引脚
		gpioinstructure.GPIO_Mode  =  GPIO_Mode_AF_PP;//复用推挽输出
	  gpioinstructure.GPIO_Pin   =  GPIO_Pin_9 ;//引脚9
	  gpioinstructure.GPIO_Speed =  GPIO_Speed_50MHz;//速度为50Mhz
	
	  GPIO_Init(GPIOA,&gpioinstructure);//GPIO初始化
	
	  //配置PA10 RX 接收引脚
	  gpioinstructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;//浮空输出
	  gpioinstructure.GPIO_Pin   = GPIO_Pin_10;//引脚10
		
		GPIO_Init(GPIOA,&gpioinstructure);//GPIO初始化
		
	//3.配置串口的结构体
	  usartinstructure.USART_BaudRate = 115200;//波特率为115200
		usartinstructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件流配置
		usartinstructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx ;//接收模式
		usartinstructure.USART_Parity = USART_Parity_No;//无校验位
		usartinstructure.USART_StopBits = USART_StopBits_1;//一个停止位
		usartinstructure.USART_WordLength = USART_WordLength_8b;//有效数据位为8位
    
    USART_Init(USART1,&usartinstructure);//初始化串口1
    
    USART_Cmd(USART1,ENABLE);	//使能串口1
		
		USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//串口中断配置
		
	//4.配置中断控制器的结构
	  nvicinstructure.NVIC_IRQChannel  =  USART1_IRQn;//中断通道
		nvicinstructure.NVIC_IRQChannelCmd = ENABLE; //通道使能
		nvicinstructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级配置为1
		nvicinstructure.NVIC_IRQChannelSubPriority = 1;//子优先级配置为1
		
	  NVIC_Init(&nvicinstructure);//中断控制器初始化
			  
}


//发送字符
void USARTSendByte(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
		{
			  USARTSendByte(USARTx,*(str+i));
			  i++;
		}while(*(str+i)!='\0');
		
		while(USART_GetFlagStatus(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);//返回接收到的字符
}


 




		



usart.h

#include "stm32f10x.h"
#include <stdio.h>

void usart_init(void);
void USARTSendStr(USART_TypeDef* USARTx, char *str);





  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个基于STM32F103C8T6的智能家居项目,实现了通过手机APP远程控制光和温度控制的功能。 硬件设计: 1. STM32F103C8T6开发板 2. 4路继电器模块 3. 温度传感器DS18B20 4. OLED显示屏 5. 蜂鸣器 6. 电阻、电容、LED等常规电子元件 软件设计: 1. 编写驱动程序,控制继电器模块,开关光。 2. 通过1-Wire总线读取温度传感器DS18B20的数据。 3. 编写蜂鸣器驱动程序,实现报警功能。 4. 编写OLED显示驱动程序,显示温度和光状态。 5. 利用ESP8266模块和MQTT协议实现远程控制功能,通过手机APP控制光和温度控制。 程序实现: ```c #include "stm32f10x.h" #include "delay.h" #include "led.h" #include "ds18b20.h" #include "relay.h" #include "oled.h" #include "usart.h" #include "mqtt.h" #define TOPIC_LIGHT "home/light" #define TOPIC_TEMPERATURE "home/temperature" static void mqtt_callback(mqtt_event_t event, void *user_data); int main(void) { // 初始化各个模块 SysTick_Init(); LED_Init(); DS18B20_Init(); Relay_Init(); OLED_Init(); USART1_Init(); // 连接MQTT服务器 mqtt_init("mqtt://192.168.1.100", "client_id", mqtt_callback, NULL); while(1) { // 读取温度传感器的温度 float temperature = DS18B20_ReadTemperature(); // 控制光 if(mqtt_get_state(TOPIC_LIGHT) == MQTT_STATE_ON) { Relay_On(1); LED_On(LED1); } else { Relay_Off(1); LED_Off(LED1); } // 显示温度和光状态 OLED_Clear(); OLED_SetCursor(0, 0); OLED_Printf("Temperature: %.2fC", temperature); OLED_SetCursor(0, 2); if(mqtt_get_state(TOPIC_LIGHT) == MQTT_STATE_ON) OLED_Printf("Light: On"); else OLED_Printf("Light: Off"); // 发送温度数据到MQTT服务器 char temperature_str[16]; snprintf(temperature_str, 16, "%.2f", temperature); mqtt_publish(TOPIC_TEMPERATURE, temperature_str); // 延时一段时间 DelayMs(1000); } } static void mqtt_callback(mqtt_event_t event, void *user_data) { switch(event) { case MQTT_EVENT_CONNECTED: mqtt_subscribe(TOPIC_LIGHT); break; case MQTT_EVENT_DISCONNECTED: break; case MQTT_EVENT_PUBLISHED: break; case MQTT_EVENT_SUBSCRIBED: break; case MQTT_EVENT_UNSUBSCRIBED: break; case MQTT_EVENT_STATE_CHANGED: break; case MQTT_EVENT_DATA: break; } } ``` 该程序使用了定时器和延时函数来实现各个模块的控制和显示,同时使用了MQTT协议来实现远程控制功能。在主循环中,程序不断读取温度传感器的温度,控制光,显示温度和光状态,并发送温度数据到MQTT服务器。同时,通过MQTT协议订阅光主题,实现远程控制光的功能。请在自己的开发环境中进行编译和下载,同时需要配合相应的手机APP使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值