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

 临近毕业,楼主发现自己感兴趣的东西越来越多。最近突然萌生学习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);          }      } }


  
  
结果:

 

 

 

 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值