STM学习笔记(一)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_20539533/article/details/83450056

作为一名物联网专业的,我能不学STM32么!选这个专业的时候我就知道可以又学编程又学电路,果然梦寐以求。学习使我快乐,就是头冷,(我学的东西好杂)外加上一些其他事情就更没时间做其他事情了,这个专业再加上种种原因使我成为了单身狗·精英。21年的单身狗精英。这门课已经快结束了,要交作业了,以前也没怎么听。所以开始做作业,边学边做。三道题目。

我自己的笔记,是有我自己 的风格的,也看过别人的笔记,确实挺好的,但我不打算学,好累的。侧重点不同,我这可能会简略一笔带过甚至不提。

1.如果使用GOIOC6接口为推拉方式输出,最高频率50MHz,分别使用寄存器模式和库函数模式,如何进行编程。

主要就是寄存器了。

GPIO寄存器包括2个32位的配置寄存器(GPIOx_CRL,GPIOx_CRH),2个32位的数据寄存器(GPIOx_IDR,GPIOx_ODR),1个32位的置位/复位寄存器(GPIOx_BSRR),1个16位的复位寄存器(GPIOx_BRR),1个32位的锁定寄存器(GPIOx_LCKR)。以上所有寄存器不允许按位或字节访问,必须按32位字访问。GPIO寄存器
配置寄存器
配置GPIO的IO口C,那么需要写CNF c[1:0],MODEc[1:0].
MODE[1:0]   
00为输入模式(复位后的状态)
01为输出模式,最大频率10MHz
10为输出模式,最大频率2MHz
11为输出模式,最大频率50MHz
所以MODE[1:0]为11
CNF[1:0]
输入模式:
00为模拟输入模式
01为浮空输入模式(复位后的状态)
10为上拉/下拉输入模式
11为保留
输出模式
00为通用推挽输出模式
01为通用开漏输出模式
10为复用功能推挽输出模式
11为复用功能开漏输出模式
所以为CNF[1:0]为00
IO口是6,在0~7号内,写CRL寄存器,如果是8~15号的话使用CRH寄存器。
GPIOC->CRL的CNF6[1:0]为00,GPIOC->CRL的MODE6[1:0]为11
代码:
GPIOC->CRL&=0XF0FFFFFF;//清掉对位6的配置
GPIOC->CRL|=0X03000000;//写位6的位置0011
端口输入数据储存器(GPIOx_IDR)和端口输出数据寄存器(GPIOx_ODR)
端口位设置/清除寄存器(GPIOx_BSRR)
端口位清除寄存器(GPIOx_BRR)
GPIO库函数(具体的自己去STM32固件库使用手册查)
要使用GPIO库函数,必须让使用这些库函数的c文件包含"stm32f10x_gpio.h","stm32f10x_rcc.h"。需要在stm32f10x_conf.h进行配置。
GPIO的初始化函数GPIO_Init()
 
代码:
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz
GPIO_Init(GPIOC,&GPIO_InitStructure)

2.编程实现4位流水灯。

分析:

系统复位后,流水灯流动起来。流水灯流动,需要驱动LED轮流显示,4根GPIO推挽输出。

代码:

#define led_gpio GPIOC//led在端口C
#define led1 GPIO_Pin_6
#define led2 GPIO_Pin_7
#define led3 GPIO_Pin_8
#define led4 GPIO_Pin_9
//led1,2,3,4分别对GPIOC的6,7,8,9
INT8U delaytime;//每个灯亮的持续时间,全局变量
int main(void){
INT16U led_flow;//流水位置
delaytime=128;//延时时间初始化为128ms
led_flow=0x1;//流水灯位置在最低
clock_config();//使能本程序需要使用的时钟
led_init();//配置led引脚,初始化led GPIO
while(1){
GPIO_ResetBits(led_gpio,0x03C0);//熄灭所有led
//0x03C0=0000 0011 1100 0000
//对GPIOC 6,7,8,9位清零
GPIO_SetBits(led_gpio,led_flow<<6);
/*设置led亮,当led_flow为1,那么对应led1亮;当led_flow为1<<n,对应ledn亮*/
if(led_flow == 0x10)led_flow=0x1;//当左移了第四次,应回到0x1
delay_ms(delaytime);
}
}
void led_init(){
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStructure.GPIO_Pin=led1|led2|led3|led4;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(led_gpio,&GPIO_InitStructure);
}
clock_config(){
RCC_APB2PeriphClockCmd(
RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC |RCC_APB2Periph_GPIOD |RCC_APB2Periph_GPIOE |RCC_APB2Periph_AFIO | RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE);}

3.编程实现2个按键检测,当按键1按下时,LED1翻转(由亮到灭或由灭到亮);当按键2按下时,LED2翻转。
分析:哇!这不就是把书上那一个例子拆成两个么!
代码:哇!这个有些问题。需要点时间。

贴上代码(可能有bug,睡觉了。我的头发呢)

#define led_gpio GPIOC//led在端口C
#define led1 GPIO_Pin_6
#define led2 GPIO_Pin_7
#define button_gpio GPIOB
#define button_port_source GPIO_PortSourceGPIOB
#define button_irqn EXTI9_5_IRQn
#define button1 GPIO_Pin_8
#define button1_source GPIO_PinSource8
#define button1_exit_line EXTI_Line8
#define button2 GPIO_Pin_9
#define button2_source GPIO_PinSource9
#define button2_exit_line EXTI_Line9
//led1,2,3,4分别对GPIOC的6,7,8,9
int led1s=0;
int led2s=0;

int main(void){
clock_config();//使能本程序需要使用的时钟
led_init();//配置led引脚,初始化led GPIO
key_init();//初始化按键GPIO
exti_config();//设置中断
while(1){
GPIO_ResetBits(led_gpio,0x00C0);//熄灭所有led
//0x00C0=0000 0000 1100 0000
//对GPIOC 6,7位清零
GPIO_SetBits(led_gpio,led_flow<<6);
/*设置led亮,当led_flow为1,那么对应led1亮;当led_flow为1<<n,对应ledn亮*/
if(led_flow == 0x10)led_flow=0x1;//当左移了第四次,应回到0x1
delay_ms(delaytime);
}
}
void led_init(){
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStructure.GPIO_Pin=led1|led2|led3|led4;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(led_gpio,&GPIO_InitStructure);
}void key_init(){
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStructure.GPIO_Pin=button1|button2;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_IPD;
GPIO_Init(led_gpio,&GPIO_InitStructure);
}
void exti_config(void){
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTyeDef NVIC_InitStructure;
GPIO_EXTILineConfig(button_port_source,button1_source);
GPIO_EXTILineConfig(button_port_source,button2_source);
EXTI_InitStructure.EXTI_Line = button1_exti_Line | button2_exti_Line; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; 
EXTI_Init(&EXTI_InitStructure); 
NVIC_InitStructure.NVIC_IRQChannel = button_irqn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure(&NVIC_InitStructure);
}
clock_config(){
RCC_APB2PeriphClockCmd(
RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC |RCC_APB2Periph_GPIOD |RCC_APB2Periph_GPIOE |RCC_APB2Periph_AFIO | RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE);}
void EXTI9_5_IRQHandler(void){
if(EXTI_GetITStatus(button1_exti_line)!=RESET)\|(GetITStatus(button2_exti_line)!=RESET){
delay_ms(20);
if(GPIO_ReadInputDataBit(button_gpio,button2)==0x00){
if(led1==0){GPIO_SetBits(led_gpio,GPIO_Pin_6);
led1s=1;}
else{GPIO_ResetBits(led_gpio,GPIO_Pin_6);
led1s=0;}
}
if(GPIO_ReadInputDataBit(button_gpio,button1)==0x00){
if(led2==0){GPIO_SetBits(led_gpio,GPIO_Pin_7);
led2s=1;}
else{GPIO_ResetBits(led_gpio,GPIO_Pin_7);
led2s=0;}
}
keep_run(100);
EXTI_ClearITPendingBit(button1_exti_line);
EXTI_ClearITPendingBit(button2_exti_line);
}
}

猜你喜欢

转载自blog.csdn.net/qq_20539533/article/details/83450056