【STM32】标准库 菜鸟入门 GPIO输入 |
您所在的位置:网站首页 › c语言gpio_pin的含义 › 【STM32】标准库 菜鸟入门 GPIO输入 |
按键分析
按键抖动:由于按键内部使用的是机械式弹簧片来进行通断的,所以在按下和松手的瞬间会伴随有一连串的抖动 消抖:运用延时函数耗过抖动时间,或者改善硬件电路 传感器分析 传感器元件主要是可变电阻,比如光敏传感器跟热敏传感器,光线越强或者温度越高,其内部电阻阻值越小,由于不方便直接被观察,所以常常此电阻与定值电阻串联,通过输出电压观察。 滤波电容,保持电压输出的平滑。一端电路中,一端接地。分析电容可以抹掉在分析。N1变小,输出逐渐减小,极限短路,输出VSS;N1变大,极限断路,输出VCC。 弱下拉:下拉电阻阻值小。 LM393:电压比较器芯片,里面两个运算放大器,也就是当正相输入大于反相输入时,输出VCC,反之输出VSS。模拟电压进行二极化可以变成数字电压。 AO:模拟电压输出 DO:数字思电压输出 硬件电路分析对图1,上拉输入,按下时低电平,松开时高电平,若不设置上拉输入,松开时电平不确定,不正确,所以一定上拉。stm32单片机中有上下拉电阻。对图3,则需需要下拉电阻,如果片外连接了上下拉电阻,则可以再设置浮空模式,因为外面配置了,不会发生不知道高低电平的事情,如图2与4,当然图2还可以设置为上拉输入,图4还可以设置为下拉输入,与外面的电阻强强联合,输入信号更稳定,但是当按键按下时,电平转换损耗也会更多。 C语言数字类型char short int longlong 8 16 32 64 stdint是新定义的名字,就是前面的的新名字,只是换了个名字而已 ST是老版的写法,但是依旧还能用,为了兼容老版本 关键字 位数 表示范围 stdint关键字 ST关键字 char 8 -128 ~ 127 int8_t s8 unsigned char 8 0 ~ 255 uint8_t u8 short 16 -32768 ~ 32767 int16_t s16 unsigned short 16 0 ~ 65535 uint16_t u16 int 32 -2147483648 ~ 2147483647 int32_t s32 unsigned int 32 0 ~ 4294967295 uint32_t u32 long 32 -2147483648 ~ 2147483647 unsigned long 32 0 ~ 4294967295 long long 64 -(2^64)/2 ~ (2^64)/2-1 int64_t unsigned long long 64 0 ~ (2^64)-1 uint64_t float 32 -3.4e38 ~ 3.4e38 double 64 -1.7e308 ~ 1.7e308 宏定义①#indefine ABC 12345 int a=ABC;相当于a=12345; 把ABC替换12345,其后不需要分号,宏定义把名字简化了,任何都能换 运用宏定义把一个数映射到字符串上,便于理解防止出错,便于快速修改,可以修改一切名字。 比如GPIO口的第十二个引脚,((uint16_t)0x1000)可以用GPIO_Pin_12代替。 ②typedef 只能给变量类型换名字 typedef usigned char uint8_t; uint8_t a;等效于usigned char a;命名之后两者都可以使用,只不过多了多了一个新名字罢了。 意思: uint8_t 替换usigned char,只能给变化类型改名。 结构体数组只能组合相同类型的数据,eg:char[20],int[50] 引用:char[0]...... 结构体,组合不同类型的数据。struct{char x;int y;float z}structName; 引用,函数名+子项的名字:structName.x=... structName.y=... structName.z=.... 结构体成员较多,一半写成: struct{ char x; int y; float z}structName; 运用typedef来替换struct{char x;int y;float z}更加简便 typedef struct{char x;int y;float z} SturctName_t; SturctName_t c; SturctName_t d; 以定义GPIO口初始化的函数为例: 大致意思:定义GPIO_InitTypeDef的名称,然后在定义其子项的参数,而后将结构体打包发送到指定位置。 对于上例,还可以写成:pGPIO_InitStructure->'A';pGPIO_InitStructure代表结构体的地址; 因为 GPIO_InitTypeDef GPIO_InitStructure; 已经把 GPIO_InitTypeDef 命名为GPIO_InitStructure; 枚举定义一个取之受限制的变量,用于限制取值范围,只能写花括号之中的值。 enum{MONDAY=1,TUSDAY,WENSDAY} week; 不赋值证明是按顺序,123456789这样子。 tepedef enum{MONDAY=1,TUSDAY,WENSDAY} Week_t; 这里的意思是,把枚举的这一块看做是Week_t代替。(typedef的作用) 引用枚举成员,名=里面的等号左边,也可以被其他引用,比如int a;a=MONDAY; Week_t week; week=MONDAY;//week=1; 只能赋值枚举中的值; eg: typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; FunctionalState a;//定义变量 a=(FunctionalState)1; a=(FunctionalState)0; a=ENABLE; a=DISABLE; 按键控制LED六脚自锁开关: 开关使用的时候记得先测试他是那种导通方式,避免踩雷。 正常情况下:若是单刀双掷开关,如下: 分为公共端,常用闭合端和常开端 模块化编程工程目录建立一个新的文件夹名为HardWare 三个箱子,工程管理新建文件也叫Hareware,可以移动位置 魔术棒。C/C++,添加到头文件列表中 右键Hardware,添加新文件,.c主题代码,.h可对外使用的声明,更改路径 .c初始化:插入头文件,注意,在书写代码之后,在其最后一行也要以空行结尾,不然报错。 #include "stm32f10x.h" .h初始化: #ifndef __LED_H #define __LED_H #endif注意最后同样以空行结尾 意思是,如果没有定义led_h,就定义led.h,结束if ctrl+atl+空格显示代码提示 打开.c文件,初始化LED端口(也就是打开时钟,配置端口模式,前面配置GPIO口的前两步) #include "stm32f10x.h" // Device header void LED_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); }然后把复制函数第一行放在.h文件中,对外部声明 在主函数中,头文件写上hardware文件中的.h文件夹名字。 在主函数中,若果需要引用的话,就把第一行函数写到哪里。可以写void也可以不写,只要是前后一致即可,如: void LED_OFF(void); LED_OFF;有警告编译一下更新函数; .c文件中,接着模块化,开启关闭led灯。 #include "stm32f10x.h" // Device header void LED_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); ); } void LED1_ON(void) { GPIO_ResetBits(GPIOA, GPIO_Pin_1); } void LED1_OFF(void) { GPIO_SetBits(GPIOA, GPIO_Pin_1); } 按键配置 uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //读取输入寄存器某一位的值 uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); //读取整个输入寄存器的值 uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //读取输出寄存器的值 uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); //读取整个输出寄存器的值 uint8_t Key_GetNum(void) //此函数与主函数中的KeyNum= Key_GetNum();配合,使主函数获得返回键码 { uint8_t KeyNum = 0; if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) //如果案件PB1按下变为低电平,进入后续 { Delay_ms(20); //消抖 while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0); //如果按键按下一直不动,不改变,死循环 Delay_ms(20); //消抖 KeyNum = 1; //赋值,与按键没按下的值不一样,方便调用 } return KeyNum; //返回键码 }主要流程与LED一样。 #include "Delay.h" #include "LED.h" #include "Key.h" uint8_t KeyNum; //在函数里面的是局部变量,只有函数内部自己可以使用,在main函数外面的是全局变量,都可以使用。函数内部优先局部变量。 int main(void) { LED_Init(); Key_Init(); while (1) { KeyNum = Key_GetNum(); //获取键码 if (KeyNum == 1) { LED1_Turn(); } if (KeyNum == 2) { LED2_Turn(); } } }KeyNum的值返回给Key_GetNum();可以直接在主函数中使用,如下例,也可以自主命名,然后赋值,如上例。 函数内主要用自己的局部变量,没有的话才向外求。 光敏传感器(LightSensor)。松手灯亮低电平,电位器调整阈值。蜂鸣器(buzzer) uint8_t LightSensor_Get(void) //自定义函数名 { return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1); //返回值返回到LightSensor_Get(); } |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |