基于STM32F407VET6的学习记录(一)

寄存器篇


文章目录


前言

本文是我学习的一些基础内容的记录(b站:飞熊不熊)。


一、跑马灯

  1.  时钟配置:
    u8 Sys_Clock_Set(u32 plln,u32 pllm,u32 pllp,u32 pllq)
    { 
    	u16 retry=0;
    	u8 status=0;
    	RCC->CR|=1<<16;				//HSE 开启 
    	while(((RCC->CR&(1<<17))==0)&&(retry<0X1FFF))retry++;//等待HSE RDY
    	if(retry==0X1FFF)status=1;	//HSE无法就绪
    	else   
    	{
    		RCC->APB1ENR|=1<<28;	//电源接口时钟使能
    		PWR->CR|=3<<14; 		//高性能模式,时钟可到168Mhz
    		RCC->CFGR|=(0<<4)|(5<<10)|(4<<13);//HCLK 不分频;APB1 4分频;APB2 2分频. 
    		RCC->CR&=~(1<<24);	//关闭主PLL
    		RCC->PLLCFGR=pllm|(plln<<6)|(((pllp>>1)-1)<<16)|(pllq<<24)|(1<<22);//配置主PLL,PLL时钟源来自HSE
    		RCC->CR|=1<<24;			//打开主PLL
    		while((RCC->CR&(1<<25))==0);//等待PLL准备好 
    		FLASH->ACR|=1<<8;		//指令预取使能.
    		FLASH->ACR|=1<<9;		//指令cache使能.
    		FLASH->ACR|=1<<10;		//数据cache使能.
    		FLASH->ACR|=5<<0;		//5个CPU等待周期. 
    		RCC->CFGR&=~(3<<0);		//清零
    		RCC->CFGR|=2<<0;		//选择主PLL作为系统时钟	 
    		while((RCC->CFGR&(3<<2))!=(2<<2));//等待主PLL作为系统时钟成功. 
    	} 
    	return status;
    } 

  2. 时钟介绍:RCC->CFGR|=(0<<4)|(5<<10)|(4<<13);//HCLK 不分频;APB1 4分频;APB2 2分频.
  3. LED初始化:
    //LED IO初始化
    void LED_Init(void)
    {    	 
    	RCC->AHB1ENR|=1<<5;//使能PORTF时钟 
    	GPIO_Set(GPIOF,PIN9|PIN10,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PF9,PF10设置
    	LED0=1;//LED0关闭
    	LED1=1;//LED1关闭
    }

  4. 实现:
    int main(void)
    { 
    	Stm32_Clock_Init(336,8,2,7);//设置时钟,168Mhz
    	delay_init(168);		//初始化delay函数
    	LED_Init();				//初始化LED时钟  
    	while(1)
    	{
    		LED0=0;				//亮
    		LED1=1;				//灭
    		delay_ms(200);
    		LED0=1;				//灭
    		LED1=0;				//亮
    		delay_ms(200);
    	}
    }

    5.电路原理:所以当PA6/PA7为低电平时亮(LEDx为0时LED亮)

     

 

二、蜂鸣器

1.引脚配置

//BEEP IO初始化
void BEEP_Init(void)
{    	 
	RCC->AHB1ENR|=1<<5;    		//使能PORTF时钟 
	GPIO_Set(GPIOF,PIN8,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PD); //PF8设置,下拉
	BEEP=0;						//关闭蜂鸣器	
}

2.电路原理

蜂鸣器电路:

 

分析:R59为限流电阻,R61为下拉电阻。当BEEP=1时,三极管导通,蜂鸣器响,BEEP=0时,三极管不导通,蜂鸣器不响。

三、按键

1.引脚配置:

//按键初始化函数
void KEY_Init(void)
{
	RCC->AHB1ENR|=1<<0;     //使能PORTA时钟 
	RCC->AHB1ENR|=1<<4;     //使能PORTE时钟
	GPIO_Set(GPIOE,PIN2|PIN3|PIN4,GPIO_MODE_IN,0,0,GPIO_PUPD_PU);	//PE2~4设置上拉输入
	GPIO_Set(GPIOA,PIN0,GPIO_MODE_IN,0,0,GPIO_PUPD_PD); 			//PA0设置为下拉输入 
} 

2.实现:

        首先是去抖动(20ms以内),这里选择10ms,然后判断按键是否连按,以及根据按键引脚输入信号来判断按下的是哪个按键,最后输出按键所对应的数值。(优先级,KEY0>KEY1>KEY2>KEY_UP,原因:代码中书写的先后顺序决定)

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;// 无按键按下
}

3.电路原理:

        首先就是电平触发方式的不同,WK_UP高电平触发,其它低电平触发,接着就是引脚接收的代码,使用sys.h中定义的:PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入,来接收引脚输入信号

 四、串口

1.引脚设置:

        首先先配置引脚以及串口时钟,接着配置串口1RX、TX引脚的复用,引脚复用为串口1(USART1),设置串口参数,如波特率等,开启串口中断。

void uart_init(u32 pclk2,u32 bound)
{  	 
	float temp;
	u16 mantissa;
	u16 fraction;	   
	temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV@OVER8=0
	mantissa=temp;				 //得到整数部分
	fraction=(temp-mantissa)*16; //得到小数部分@OVER8=0 
    mantissa<<=4;
	mantissa+=fraction; 
	RCC->AHB1ENR|=1<<0;   	//使能PORTA口时钟  
	RCC->APB2ENR|=1<<4;  	//使能串口1时钟 
	GPIO_Set(GPIOA,PIN9|PIN10,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_50M,GPIO_PUPD_PU);//PA9,PA10,复用功能,上拉输出
 	GPIO_AF_Set(GPIOA,9,7);	//PA9,AF7
	GPIO_AF_Set(GPIOA,10,7);//PA10,AF7  	   
	//波特率设置
 	USART1->BRR=mantissa; 	//波特率设置	 
	USART1->CR1&=~(1<<15); 	//设置OVER8=0 
	USART1->CR1|=1<<3;  	//串口发送使能 
#if EN_USART1_RX		  	//如果使能了接收
	//使能接收中断 
	USART1->CR1|=1<<2;  	//串口接收使能
	USART1->CR1|=1<<5;    	//接收缓冲区非空中断使能	    	
	MY_NVIC_Init(3,3,USART1_IRQn,2);//组2,最低优先级 
#endif
	USART1->CR1|=1<<13;  	//串口使能
}

2.代码原理:设置PCLK2时钟频率为84,因为APB2是系统时钟频率的2分频,也就是168/2=84(MHz),设置波特率为115200  bits/s(位/秒,也就是波特)

uart_init(84,115200);	//串口初始化,波特率为115200

3.串口数据的接收和发送:

        串口是全双工的,所以可以同时收发(全双工的输入和输出可同时进行,半双工则不能同时进行),引脚分别为发送端TX和接收端RX。串口接收数据的代码和解释如下:

 

if(USART1->SR&(1<<5))  // 检查USART1->SR寄存器的第5位是否为1,即判断是否接收到数据
{
    res=USART1->DR;  // 将接收到的数据存储在res变量中
    if((USART_RX_STA&0x8000)==0)  // 判断接收状态是否未完成,即判断USART_RX_STA的最高位是否为0
    {
        if(USART_RX_STA&0x4000)  // 判断是否接收到了0x0d
        {
            if(res!=0x0a)  // 判断接收到的数据是否为0x0a
                USART_RX_STA=0;  // 如果不是,表示接收错误,将接收状态置为0,重新开始接收数据
            else
                USART_RX_STA|=0x8000;  // 如果是,表示接收完成,将接收状态最高位置为1,表示接收完成
        }
        else  // 如果还未收到0X0D
        {
            if(res==0x0d)
                USART_RX_STA|=0x4000;  // 如果接收到的数据为0x0d,将接收状态第14位置为1,表示接收到了0x0d
            else
            {
                USART_RX_BUF[USART_RX_STA&0X3FFF]=res;  // 将接收到的数据存储在接收缓冲区中
                USART_RX_STA++;  // 接收状态加1
                if(USART_RX_STA>(USART_REC_LEN-1))
                    USART_RX_STA=0;  // 如果接收状态超过了缓冲区长度,表示接收数据错误,将接收状态置为0,重新开始接收数据
            }
        }
    }
}

目录

寄存器篇

文章目录

前言

一、跑马灯

二、蜂鸣器

1.引脚配置

2.电路原理

三、按键

四、串口

总结


总结

        以上就是我在学习中所记录的内容,本文仅仅简单介绍了我学习中的程序原理以及代码,如果有错误的地方,希望能指出、交流一下正确答案,感谢你的浏览,希望这些对你有所帮助(b站:飞熊不熊)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值