STM32入门/更新于2018/1/24

我学习的主要芯片为STM32F407ZGT6
首先看了一些概念的东西,初步了解了STM32
然后新建了工程,开始模仿着写一些简单的程序(库函数方法)

跑马灯实验

  1. 使能IO口时钟,这几乎是写所有程序的第一步,要注意不同的外设调用的时钟使能函数可能不一样。
  2. 初始化IO口
  3. 操作IO口,输出高低电平GPIO_SetBits();→相当于LED0=1→灭;GPIO_ResetBits();→相当于LED0=0→`亮
    操作IO口也可以用位带操作,需在led程序的头文件中写以下程序:
 #ifndef  __BEEP_H

 #define  __BEEP_H

#include "stm32f4xx.h" 

#define BEEP PFout(8)

 void BEEP_Init(void);

 #endif

蜂鸣器实验

和跑马灯类似,注意LED和蜂鸣器都是输出的工作方式,初始化IO口时,一般设置为推挽输出。使用位带操作时,PFout(9)=0;

按键输入

普通key:上拉输入,一端接IO口,一端接GND(按下时测到低电平,低电平有效)
WK_up:下拉输入,一端接IO口,一端接VCC(按下时测到高电平,高电平有效)
按键输入的步骤为:
使能按键对应IO口的时钟;
初始化IO口,注意按键属于输入的工作方式;
扫描IO口电平;
同时我们应考虑到,连续按还是不连续按,这里用到static和mode。

u8 KEY_Scan(u8 mode)
{ 
static u8 key_up=1;//按键按松开标志
if(mode)key_up=1; //支持连按
if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
{
delay_ms(10);//去抖动
key_up=0;
if(KEY0==0)return 1;
else if(KEY1==0)return 2;
else if(KEY2==0)return 3;
else if(WK_UP==1)return 4;
}else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1;
return 0;// 无按键按下
}

mode用于选择支持连续按还是不支持;
static说明该函数不是一个可重入函数,初始化只会被调用一次。
同时,还应知道,按键扫描是有优先级的,在后续学到中断,进一步总结。

呼吸灯

在学习了跑马灯,蜂鸣器,按键之后,写了呼吸灯程序练习。
最初我觉得对于IO口,我们不是给他高电平,就是低电平,所以如果点灯的话,灯也应只有两种状态。但其实我们可以用延时来达到呼吸灯的效果。
这里用到占空比,简单说就是我们控制灯的亮灭,让他亮的时间持续变长,人眼看到的就是他在渐渐变亮,而其实他是不停的亮灭。渐渐变灭也同理,让他变灭的时间持续变长。由于分为两种情况,我们可以用简单的menu菜单。下面程序

#include "stm32f4xx.h"
#include "led.h"
#include "delay.h"
#include "beep.h"
#include "usart.h"
#include "key.h"nt 
main(void)
    {
        int MENU;
        int t,i;
        LED_Init();
        delay_init(168);
        MENU=0;
        t=1;    
        while(1)
            {
              if (MENU==0)
                  {
                        for(i = 0; i < 10; i++)
                            {
                                GPIO_ResetBits(GPIOF,GPIO_Pin_10 );
                                delay_us(t);
                                GPIO_SetBits(GPIOF,GPIO_Pin_10 );
                                delay_us(501-t);
                                GPIO_ResetBits(GPIOF,GPIO_Pin_9 );
                                delay_us(t);
                                GPIO_SetBits(GPIOF,GPIO_Pin_9 );
                                delay_us(501-t);                                    
                            }
                        t++;
                        if(t==500)
                            {
                              MENU=1;
                            }
                    }                   
          if (MENU==1)
                    {
                        for(i = 0; i < 10; i++)
                            {
                                GPIO_ResetBits(GPIOF,GPIO_Pin_10 );
                                delay_us(t);
                                GPIO_SetBits(GPIOF,GPIO_Pin_10 );
                                delay_us(501-t);
                                GPIO_ResetBits(GPIOF,GPIO_Pin_9 );
                                delay_us(t);
                                GPIO_SetBits(GPIOF,GPIO_Pin_9 );
                                delay_us(501-t);    
                            }
                        t--;
                        if(t==0)
                            {
                                MENU=0;
                                t=1;
                            }
                    }
         }
}

时钟系统

SYSCLR系统时钟由:HSE OSC高速的外部时钟;HSI RC高速的内部时钟;主PLL时钟得来。
PLL=8MHzN/(M*P)=8MHz336/(8*2)=168MHz
任何一个外设在没有使用之前,都必须使能相应的时钟。

NVIC中断优先级分组

一般只设置一次中断优先级,不随意改变。
步骤:
系统运行后,先设置中断优先级分组
针对每个中断,设置对应的抢占优先级,响应优先级
如需要挂起/解挂,查看中断当前激活状态

 1. 高优先级的抢占优先级是可以打断正在进行的低抢占优先级的中断
 2. 抢占优先级相同的中断,高响应优先级不可以打断低响应优先级
 3. 抢占优先级相同的中断,当两个中断同事发生,响应优先级高的先发生
 4. 如果两个中断的抢占优先级,响应优先级都相同,那个中断先发生,就先执行

串口通信

① 串口时钟使能,GPIO 时钟使能
② 设置引脚复用器映射
③ GPIO 端口初始化设置
④ 串口参数初始化
⑤ 初始化 NVIC 并且开启中断
⑥ 使能串口

中断服务函数:

void USART1_IRQHandler(void)               
{
    u8 Res;
#if SYSTEM_SUPPORT_OS   
    OSIntEnter();    
#endif
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  
    {
        Res =USART_ReceiveData(USART1); 

        if((USART_RX_STA&0x8000)==0)
        {
            if(USART_RX_STA&0x4000)
            {
                if(Res!=0x0a)USART_RX_STA=0;
                else USART_RX_STA|=0x8000;
            }
            else 
            {   
                if(Res==0x0d)USART_RX_STA|=0x4000;
                else
                {
                    USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
                    USART_RX_STA++;
                    if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0; 
                }        
            }
        }            
  } 

ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
这个函数一般使用在中断服务函数的开头判断中断是否发生。另一个函数是清除某个中断线上
的中断标志位:
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
这个函数一般应用在中断服务函数结束之前,清除中断标志位。
常用的中断服务函数格式为:

void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判断某个线上的中断是否发生
    { …中断逻辑…
     EXTI_ClearITPendingBit(EXTI_Line3); //清除 LINE 上的中断标志位
    } 
}

外部中断

1) 使能 IO 口时钟,初始化 IO
2) 开启 SYSCFG 时钟,设置 IO 口与中断线的映射关系。
3) 初始化线上中断,设置触发条件等。
4) 配置中断分组(NVIC ),并使能中断。
5) 编写中断服务函数。

定时器中断

1 )TIM3 时钟使能。
2 )初始化定时器参数 数, 设置 自动重装值 , 分频系数 ,计数方式 等。
3 )设置 TIM3_DIER 允许更新中断
4 )TIM3 中断优先级设置。
5 )允许 TIM3 工作,也就是使能 TIM3 。
6 )编写中断服务函数。

/************更新于2018/1/24*************/
/**************欢迎指正***************/

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值