基于STM32F407VET6的学习记录(一)

编程入门 行业动态 更新时间:2024-10-13 04:23:00

基于STM32F407VET6的学习记录(一)

基于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 RDYif(retry==0X1FFF)status=1;	//HSE无法就绪else   {RCC->APB1ENR|=1<<28;	//电源接口时钟使能PWR->CR|=3<<14; 		//高性能模式,时钟可到168MhzRCC->CFGR|=(0<<4)|(5<<10)|(4<<13);//HCLK 不分频;APB1 4分频;APB2 2分频. RCC->CR&=~(1<<24);	//关闭主PLLRCC->PLLCFGR=pllm|(plln<<6)|(((pllp>>1)-1)<<16)|(pllq<<24)|(1<<22);//配置主PLL,PLL时钟源来自HSERCC->CR|=1<<24;			//打开主PLLwhile((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);//设置时钟,168Mhzdelay_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=0mantissa=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,AF7GPIO_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,最低优先级 
#endifUSART1->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)  // 判断接收到的数据是否为0x0aUSART_RX_STA=0;  // 如果不是,表示接收错误,将接收状态置为0,重新开始接收数据elseUSART_RX_STA|=0x8000;  // 如果是,表示接收完成,将接收状态最高位置为1,表示接收完成}else  // 如果还未收到0X0D{if(res==0x0d)USART_RX_STA|=0x4000;  // 如果接收到的数据为0x0d,将接收状态第14位置为1,表示接收到了0x0delse{USART_RX_BUF[USART_RX_STA&0X3FFF]=res;  // 将接收到的数据存储在接收缓冲区中USART_RX_STA++;  // 接收状态加1if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;  // 如果接收状态超过了缓冲区长度,表示接收数据错误,将接收状态置为0,重新开始接收数据}}}
}

目录

寄存器篇

文章目录

前言

一、跑马灯

二、蜂鸣器

1.引脚配置

2.电路原理

三、按键

四、串口

总结


总结

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

更多推荐

基于STM32F407VET6的学习记录(一)

本文发布于:2024-03-14 23:57:54,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1737649.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!