/**********************************************************
* 文件名 : 流水灯.c
* 作者 :
* 版本号 : V1.0
* 日期 :
* 功能 :用定时器中断实现开发板上的4个LED按顺序每隔1S打开一个,第5S全部熄灭,循环。
然后按下K1程序停止,蜂鸣器滴一声,再按下K1程序继续执行。
按下K2全灭,再按下K2全亮。
***********************************************************/
#include "stm32f10x.h"
/* LED1 -> PB8 , LED2 -> PB9 , LED3 -> PE0 , LED4 -> PE1*/
#define LED1_OFF GPIO_SetBits(GPIOB , GPIO_Pin_8);
#define LED1_ON GPIO_ResetBits(GPIOB , GPIO_Pin_8);
#define LED2_OFF GPIO_SetBits(GPIOB , GPIO_Pin_9);
#define LED2_ON GPIO_ResetBits(GPIOB , GPIO_Pin_9);
#define LED3_OFF GPIO_SetBits(GPIOE , GPIO_Pin_0);
#define LED3_ON GPIO_ResetBits(GPIOE , GPIO_Pin_0);
#define LED4_OFF GPIO_SetBits(GPIOE , GPIO_Pin_1);
#define LED4_ON GPIO_ResetBits(GPIOE , GPIO_Pin_1);
void GPIO_Config(void); //定义端口配置函数
void RCC_Configuration(void); //定义时钟配置函数
void Timer_Comfig(void); //定义定时器配置函数
void EXTI_Config(void);
void NVIC_Config(void); //嵌套中断配置函数
void TIM2_IRQHandler(void);//定义定时器中断服务函数
unsigned char i=0;
void delay_ms(u16 nms) //滴答定时器非中断方式延迟nms函数
{
u32 temp;
SysTick->LOAD = 9000*nms;
SysTick->VAL=0X00;//清空计数器
SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
do
{
temp=SysTick->CTRL;//读取当前倒计数值
}
while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
SysTick->CTRL=0x00; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
/*************************************************
函数: void RCC_Configuration(void)
功能: 复位和时钟控制配置
参数: 无
返回: 无
**************************************************/
void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus; //定义外部高速晶体启动状态枚举变量
/* RCC system reset(for debug purpose) */
RCC_DeInit(); //复位外设RCC寄存器重设为缺省值
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON); //打开外部高速晶振
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待HSE起振
if(HSEStartUpStatus == SUCCESS) //外部高速时钟已经准备好
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //使能预取指缓存
//开启FLASH预读缓冲功能,加速FLASH的读取。所有程序中必须的用法.位置:RCC初始化子函数里面,时钟起振之后
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2); //flash操作的延时,设置代码延时值为2个延时周期
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置AHB时钟(HCLK)等于系统时钟
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1); //设置高速AHB时钟(PCLK2)APB2时钟等于HCLK ,即72MHZ
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2); //设置低俗AHB时钟(PCLK1) APB1时钟等于HCLK/2,即36MHZ,因为有手册知APB1时钟最大不超过36MHZ
/* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //设置PLL输入时钟等于HSE时钟频率
//设置PLL的倍频系数为PLL输入时钟X9 ,即HSE*9=8MHZ*9=72MHZ
/* Enable PLL */
RCC_PLLCmd(ENABLE); //使能锁相环
/* Wait till PLL is ready */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) //检查指定的RCC标志位设置与否
{
}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //设置PLL作为系统时钟
/* Wait till PLL is used as system clock source */
while(RCC_GetSYSCLKSource() != 0x08) //返回用作系统时钟的时钟源 0X08代表PLL作为系统时钟
{
}
}
}
/*************************************************
函数: void Timer_Config(void)
功能: 定时器配置
参数: 无
返回: 无
**************************************************/
void Timer_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定义TIM_TimeBaseStructure结构体类型
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE); //使能定时器的时钟
TIM_DeInit(TIM2); //用于复位TIM2定时器,使之进入初始状态
TIM_TimeBaseStructure.TIM_Period=2000; //自动重装载寄存器周期的值(计数值)
//累计 TIM_Period个频率后产生一个更新或者中断
TIM_TimeBaseStructure.TIM_Prescaler= (36000 - 1); //时钟预分频数 例如:时钟频率=72MHZ/(时钟预分频+1)
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //采样分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // 把 TIM_TimeBaseInitStruct 中的每一个参数按缺省值填入
TIM_ClearFlag(TIM2, TIM_FLAG_Update); //清除溢出中断标志
//TIM_PrescalerConfig(TIM2,0x8C9F,TIM_PSCReloadMode_Immediate); //时钟分频系数36000,所以定时器时钟为2K
//TIM_ARRPreloadConfig(TIM2, DISABLE); //禁止ARR预装载缓冲器
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //使能TIM2中断
TIM_Cmd(TIM2, ENABLE); //开启时钟
}
/*************************************************
函数: voidEXTI_Config(void)
功能: 中断配置
参数: 无
返回: 无
**************************************************/
void EXTI_Config(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2); // 选择GPIO管脚PE2用作外部中断线路2
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);// 选择GPIO管脚PE3用作外部中断线路3
EXTI_ClearITPendingBit(EXTI_Line3); //清除中断线3的中断标志位
EXTI_ClearITPendingBit(EXTI_Line2); //清除中断线2的中断标志位
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;//设置EXTI线路为中断请求模式
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising; //设置输入线路上升沿为中断请求
EXTI_InitStructure.EXTI_Line=EXTI_Line2| EXTI_Line3; //选择待使能或者失能的外部线路为中断线2和3
EXTI_InitStructure.EXTI_LineCmd=ENABLE; //定义选中线路状态为使能状态
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct 中指定的参数初始化外设 EXTI寄存器
}
/*************************************************
函数: void NVIC_Config(void)
功能: 嵌套中断配置
参数: 无
返回: 无
**************************************************/
void NVIC_Config(void)//嵌套中断配置
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel=EXTI2_IRQn; //选择外部中断线2 中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//主优先级占0位
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; //次优先级占0位
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能选中的中断通道
NVIC_Init(&NVIC_InitStructure);//根据NVIC_InitStruct 中指定的参数初始化外设 NVIC寄存器
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel=EXTI3_IRQn; //选择外部中断线3 中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//主优先级占1位
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1; //次优先级占1位
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能选中的中断通道
NVIC_Init(&NVIC_InitStructure);//根据NVIC_InitStruct 中指定的参数初始化外设 NVIC寄存器
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //选择优先级组2,先占优先级2 位 ,从优先级2 位
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //选择TIM2全局中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//主优先级占2位
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //次优先级占2位
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能选中的中断通道
NVIC_Init(&NVIC_InitStructure);//根据NVIC_InitStruct 中指定的参数初始化外设 NVIC寄存器
}
/*************************************************
函数: void TIM2_IRQHandler(void)
功能: 定时器中断服务函数
参数: 无
返回: 无
**************************************************/
void TIM2_IRQHandler(void)
{
if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET ) //查询TIM2中断源的中断是否到来
{
TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update); //清除 TIM2 的中断待处理位
i++;
if(i>5) i=0;
}
}
/*******************************************************************************
* Function Name : EXTI2_IRQHandler
* Description : This function handles External interrupt Line 2 request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void EXTI2_IRQHandler(void)
{
unsigned char a=1; //定义按键次数并赋初值
if(EXTI_GetITStatus(EXTI_Line2)!=RESET)
{
EXTI_ClearITPendingBit(EXTI_Line2);
if(a==1)
{
a++;
GPIO_ResetBits(GPIOB , GPIO_Pin_0); //蜂鸣器动作
delay_ms(10);
GPIO_SetBits(GPIOB , GPIO_Pin_0);
while(1);
}
if(a==2)
{
delay_ms(10);
a=0;
}
}
}
/*******************************************************************************
* Function Name : EXTI3_IRQHandler
* Description : This function handles External interrupt Line 3 request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void EXTI3_IRQHandler(void)
{
unsigned char b=1;
if(EXTI_GetITStatus(EXTI_Line3)!=RESET)
{
EXTI_ClearITPendingBit(EXTI_Line3);
if(b==1)
{
delay_ms(10);
b++;
LED1_OFF;
LED2_OFF;
LED3_OFF;
LED4_OFF;
while(1);
}
if(b==2)
{
b=0;
LED1_ON;
LED2_ON;
LED3_ON;
LED4_ON;
while(1);
}
}
}
/*************************************************
函数: void GPIO_Configuration(void)
功能: GPIO配置
参数: 无
返回: 无
**************************************************/
void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //声明结构 初始化结构
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC |
RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE); //设置外设前调用该函数使能它的时钟
// RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* LED1 -> PB8 , LED2 -> PB9 , LED3 -> PE0 , LED4 -> PE1*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 |GPIO_Pin_9; //给引脚PIN赋值
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //最高输出速度为50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure); //调用该函数初始化外设GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
/*************************************************
函数: int main(void)
功能: main主函数
参数: 无
返回: 无
**************************************************/
int main(void)
{
SystemInit(); //初始化整个系统
Timer_Config();
EXTI_Config();
GPIO_Config();
NVIC_Config();
LED1_OFF;
LED2_OFF;
LED3_OFF;
LED4_OFF;
while (1)
{
switch(i)
{
case 1:
LED1_ON;
break;
case 2:
LED2_ON;
break;
case 3:
LED3_ON;
break;
case 4:
LED4_ON;
break;
case 5:
LED1_OFF;
LED2_OFF;
LED3_OFF;
LED4_OFF;
break;
default:
break;
}
}
}
|