STM32f103之USART+EXTI+TIMER+KEY+LED(简单综合应用)1

来源:互联网 发布:冠新软件 编辑:程序博客网 时间:2024/05/21 06:31
 临近毕业,楼主发现自己感兴趣的东西越来越多。最近突然萌生学习STM32的念头。自知还有很多不足,所以要把自己的学习经历写下来与网友共享,一方面督促自己更多的深入学习,另一方面希望得到“众神”的引领、、、闲话少说。
程序:

/*       标题:STM32f103之USART+EXTI+TIMER+KEY+LED(简单综合应用)1     软件:Keil uVision4      硬件:stm32f103VCT6     author:蜡烛     data:2014-05-14 

程序实现的功能描述:1.俩个LED灯以1S的频率交替闪烁          2.串口调试助手打开后显示结果信息          3.当有按键按下时,串口调试助手打印相关信息(俩个按键中实现打印方式不一样:  一个按键是普通的判断IO口高地位;另一个通过外部中断实现) 特别说明:本程序是将一些单一的程序整合起来的  程序中加了很多注释,程序是可执行的*/#include "stm32f10x.h"#include <stdio.h>/*      以下是用到USART函数进行串口监视时需添加的代码     */#ifdef __GNUC__  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf     set to 'Yes') calls __io_putchar() */  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)#else  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)#endif /* __GNUC__ */

/**  * @brief  Retargets the C library printf function to the USART.  * @param  None  * @retval None  */PUTCHAR_PROTOTYPE{  /* Place your implementation of fputc here */  /* e.g. write a character to the USART */  USART_SendData(USART1, (uint8_t) ch);

  /* Loop until the end of transmission */  while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)  {}

  return ch;}

/* Private function prototypes   在这里楼主为了程序看起来更直观点,就把所涉及的函数都放在了这,没有采用多C文件,但在实际应用编程中楼主建议采用多.C文件和对应的.h文件(或将所有接口函数都放在同一个.h文件)。或其他更好的编程思想

*/void  Delay (uint32_t nCount);void GPIO_Configuration(void);void USART_Configuration(void);void NVIC_Configuration(void);void EXTI_Configuration(void);void  TIMER_Configuration(void);/***********************************************************************/int main(void){ GPIO_Configuration();//这里端口的配置为按键和LED小灯涉及到的IO口 USART_Configuration();//串口配置 NVIC_Configuration();//中断管理配置 EXTI_Configuration();//外部中断配置 TIMER_Configuration();//定时器配置 

 printf("***************************************************************\r\n");  printf("*                                                             *\r\n"); printf("*  最热情的问候 With My Warmest Regards  ^_^  *\r\n"); printf("*                                                             *\r\n"); printf("***************************************************************\r\n");    /* Infinite loop */ while(1) {   if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_2)!= RESET)   {     Delay (0xfffff);     if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_2)!= RESET)     {       printf("KeyB is Press\r\n");       while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_2)!= RESET);     }   } }

}/***********************************************************************/

void  Delay (uint32_t nCount){  for(; nCount != 0; nCount--);}/***********************************************************************/

void GPIO_Configuration(void){  GPIO_InitTypeDef GPIO_InitStructure;    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC , ENABLE);   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);  //开启TIM2的时钟 /** * LED1 -> PB0   LED2 -> PB1 */        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(GPIOB, &GPIO_InitStructure);

  /*    KeyA -> PC13 , KeyB -> PB2  */      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   GPIO_Init(GPIOB, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   GPIO_Init(GPIOC, &GPIO_InitStructure);}/***********************************************************************/void USART_Configuration(void){   GPIO_InitTypeDef GPIO_InitStructure;  USART_InitTypeDef USART_InitStructure;

  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);  /*  *  USART1_TX -> PA9 , USART1_RX -> PA10  */      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  GPIO_Init(GPIOA, &GPIO_InitStructure);    

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    GPIO_Init(GPIOA, &GPIO_InitStructure);

  USART_InitStructure.USART_BaudRate = 115200;  USART_InitStructure.USART_WordLength = USART_WordLength_8b;  USART_InitStructure.USART_StopBits = USART_StopBits_1;  USART_InitStructure.USART_Parity = USART_Parity_No;  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  USART_Init(USART1, &USART_InitStructure);   USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  USART_ITConfig(USART1, USART_IT_TXE, ENABLE);  USART_Cmd(USART1, ENABLE); /* CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去   如下语句解决第1个字节无法正确发送出去的问题 */  USART_ClearFlag(USART1, USART_FLAG_TC);     /* 清发送外城标志,Transmission Complete flag */}

/***********************************************************************/void NVIC_Configuration(void){  NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);               

  NVIC_InitStructure.NVIC_IRQChannel =  EXTI15_10_IRQn;   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  NVIC_Init(&NVIC_InitStructure);   NVIC_InitStructure.NVIC_IRQChannel =  TIM2_IRQn;   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  NVIC_Init(&NVIC_InitStructure); }/***********************************************************************/void EXTI_Configuration(void){  EXTI_InitTypeDef EXTI_InitStructure;  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);   GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource13);  EXTI_ClearITPendingBit(EXTI_Line13);

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  EXTI_InitStructure.EXTI_Line = EXTI_Line13;  EXTI_InitStructure.EXTI_LineCmd = ENABLE;  EXTI_Init(&EXTI_InitStructure);}

/******************************************************************************** Function Name  : NVIC_Configuration* Description    : Configures the nested vectored interrupt controller.* Input          : None* Output         : None* Return         : None* Attention   : None*******************************************************************************/

void TIMER_Configuration()  //定时器初始化程序{     TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;         TIM_DeInit(TIM2);                 //重新将Timer设置为缺省值     TIM_InternalClockConfig(TIM2);     //采用内部时钟给TIM2提供时钟源         TIM_TimeBaseStructure.TIM_Prescaler = 36000 - 1;  //预分频系数为36000-1,这样计数器时钟为72MHz/36000 = 2kHz     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;   //设置时钟分割   0     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //设置计数器模式为向上计数模式     TIM_TimeBaseStructure.TIM_Period = 2000 - 1;               //设置计数溢出大小,每计2000个数就产生一个更新事件;这里定时1s        TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure); //将配置应用到TIM2中     TIM_ClearFlag(TIM2, TIM_FLAG_Update);          //清除溢出中断标志     TIM_ARRPreloadConfig(TIM2, DISABLE);          //禁止ARR预装载缓冲器     TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);      //开启TIM2的中断   TIM_Cmd(TIM2,ENABLE);             //开启定时器2    }

/******************************************************************************** Function Name  : EXTI15_10_IRQHandler* Description    : This function handles External lines 10-15 interrupt request.* Input          : None* Output         : None* Return         : None* Attention   : None*******************************************************************************/void EXTI15_10_IRQHandler(void)//中断处理函数的函数名都是默认好的,如果您修改了此处的函数名,会使得此函数无效{ if ( EXTI_GetITStatus(EXTI_Line13) != RESET ) {   EXTI_ClearITPendingBit(EXTI_Line13);//发生中断后,需清楚中断标志位,此处如果不清除,会使得串口一直在打印"KeyA is Press\r\n"     printf("KeyA is Press\r\n"); } }

void TIM2_IRQHandler(void){  static u8 ReadValue;      if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //判断是否发生中断溢出更新事件     {       TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);    //清除TIM2的中断标志位  如果没清除将导致俩个灯看起来都亮,按下KEYA键打印消息,按下KEYB键则不打印消息,这    //是因为KEYA键采用的外部中断的优先级别高于TIM2的优先级,所以不按按键时,程序一直在TIM2的中断处理函数里面循环    //这才导致按下KEYB键后没有响应和俩个LED灯一直亮着       ReadValue = GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_0);               if(ReadValue == 1)                                       {            GPIO_ResetBits(GPIOB, GPIO_Pin_0);      GPIO_SetBits(GPIOB, GPIO_Pin_1);              }           else                     {      GPIO_ResetBits(GPIOB, GPIO_Pin_1);      GPIO_SetBits(GPIOB, GPIO_Pin_0);         }     }}

结果:

 

 

 

 
 

0 0