STM32学习笔记---------------------------IO控制
看了优快云那么久,今天也来自己尝试着记录下自己学习的过程,希望有不足之处能有各位指点!
学STM32找了很多资料,也看了很多视频,也有大神指导,这个过程感觉挺不错的!
简要介绍板子
我用的是一小块demo板,这个某宝上10块左右就有,上面有一块48脚的芯片(STM32F103C8T6),晶振(8M和32.768k)、Jlink、上面还有个那种扁形的Micro USB接口等,原理图和一些材料如下
接下来就进入正题了,那么如何实现IO控制呢?
输入是指外部输入到板子里,输出是由板子输出到外部;
要学会通过控制寄存器(改变对应寄存器的地址)来获取寄存器的值。
一般你去问别人或者看视频都会教你使用对应芯片的固件库,这个对初学者来说是比较容易理解的,但是我建议一开始要理解好并不是跟着网上的视频来控制固件库就够了,更应该的是去看对应芯片的技术参考手册,要弄清楚到底是通过控制什么寄存器来实现对应寄存器的配置的,学久了你就会发现其中的套路,所以建议初学应先用固件库实现对应的功能,然后再看技术手册自己用控制寄存器的方式实现一遍。
明确需求
比如说点亮LED灯吧,这时控制输出的一种表现:
先考虑以下问题:
首先要调用一个怎样的函数
这个函数的输入、输出是什么?
这个函数的有没有参数,是什么?
……
1.固件库控制LED输出(点亮一个LED灯)
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;//这种形式的定义一定要放在开头
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;//选择引脚PC13
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//配置速率
GPIO_Init(GPIOB, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 |GPIO_Pin_8;//选择引脚PA6 、PA8
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置速率
GPIO_Init(GPIOB, &GPIO_InitStructure);
//这里可以设置引脚高低电平(一开始灯是亮还是灭)
GPIO_SetBits(GPIOC, GPIO_Pin_13);
GPIO_SetBits(GPIOA, GPIO_Pin_6 || GPIO_Pin_8 );
}
2.寄存器控制LED输出(点亮一个LED灯)
先看相应芯片的参考手册:
- 开时钟(RCC)
- 配置端口寄存器(GPIO)
- 写出相应的引脚电平控制函数
相关寄存器配置:
//初始化PC13、PA6、PA8为输出口.并使能这两个口的时钟
//LED IO初始化
void LED_Init(void)
{
//使能时钟APB2的GPIOC(LED0)
*(volatile unsigned int*)0x40021018 |= (1<<4);
//端口配置高寄存器(GPIOx_CRH) 配置PC13引脚为输出
*(volatile unsigned int*)0x40011004 |= (0x03<<20);//设置速率50MHZ 11
*(volatile unsigned int*)0x40011004 &= ~(0x03<<22);//设置第13位为推挽输出 00
//配置PA6输出为LED1
//使能时钟APB2的GPIOA
*(volatile unsigned int*)0x40021018 |= (1<<2);
//端口配置高寄存器
*(volatile unsigned int*)0x40010800 |= (0x03<<24);//设置速率50MHZ 11
*(volatile unsigned int*)0x40010800 &= ~(0x03<<26);//设置第13位为推挽输出 00
//配置PA8引脚为输出(LED2)
RCC->APB2ENR|=1<<2; //使能PORTA时钟
GPIOA->CRH&=0XFFFFFFF0; //先把需要的用引脚逻辑电平清零再配置
GPIOA->CRH|=0X00000003;//PA8 推挽输出
GPIOA->ODR|=1<<8; //PA8 输出高
//配置PA8引脚为输出(LED2)
RCC->APB2ENR|=1<<2; //使能PORTA时钟
GPIOA->CRH&=0XFFFFFFF0; //先把需要的用引脚逻辑电平清零再配置
GPIOA->CRH|=0X00000003;//PA8 推挽输出
GPIOA->ODR|=1<<8; //PA8 输出高
}
void LED_ON(void) //低电平亮灯
{
//设置PC13为输出低电平
*(volatile unsigned int*)0x4001100C &= ~(1<<13);
}
void LED_OFF(void) //高电平灭灯
{
//设置PC13输出高电平
*(volatile unsigned int*)0x4001100C |= (1<<13);
}
接下来就是主函数的调用了
int main (void)
{
delay_init();//这个函数是
LED_Init();
{
while(1)
{
LED_ON();//灯亮
LED_OFF();//灯灭
}
}
}
还有就是有条件的话可以做流水灯、排灯等按照各种形式排出各种各样的形状的灯;
学完按键和定时器之后可以更好的考虑如何把各种控灯功能效率更高的实现出来;
本文不足之处希望大家多多指出,非常感谢。