STM32标准库:IO接口的操作

STM32标准库:IO接口的操作

GPIO

控制单个GPIO管脚

GPIO_WriteBit(GPIOx,GPIO_Pin,Bitval);
//GPIOx用于选择GPIO外设,可以是GPIOA,GPIOB...
//GPIO_Pin为对应的GPIO管脚,可以形如GPIO_Pin_x(x可以是0-15)
//Bitval为待写入的值,为BIT_SET(相当于1),BIT_RESET(相当于0),为了方便可以直接用(BitAction)(1)或者(BitAction)(0)

控制整个GPIO外设

GPIO_Write(GPIOx,PortVal);
//向整组GPIO外设写入数据,一次性对16个管脚进行写入   
//PortVal例:0x0003(16位!)即0000 0000 0000 0000 0000 0000 0011,代表GPIO_Pin_0和GPIO_Pin_1为1,其他为0

读取单个GPIO管脚输入值

GPIO_ReadInputDataBit(GPIOx,GPIO_Pin);//返回单个GPIO管脚的值

读取整个GPIO外设输入值

GPIO_ReadInputData(GPIOx); //返回整个GPIO外设16个管脚的值

注:把Input换成Output,能够读取GPIO的输出值

初始化GPIO端口

步骤:使能GPIO时钟,初始化IO,操控IO

GPIO_InitTypeDef GPIO_InitStructure;//创建结构体,包含了配置信息
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOx | RCC_APB2Periph_GPIOx,ENABLE);//使能APB2外设时钟,启动APB2总线上的GPIOx外设的时钟,如果不在总线上启动,之后的操作就不会生效
//对于GPIO外设,参数1:RCC_APB2Periph_GPIOx(x可以是A,B...多个可以用用|分隔),参数2:ENABLE/DISABLE
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_x | GPIO_Pin_x;//选择GPIO管脚(x可以是0-15)
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//设置IO接口速度(可选2/10/50MHz),只有在设置IO输出时起效
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//选择工作方式
/*工作模式 
GPIO_Mode_AIN 模拟输入	GPIO_Mode_IN_FLOATING 浮空输入	GPIO_Mode_IPD 下拉输入
GPIO_Mode_IPU 上拉输入	GPIO_Mode_Out_PP 推挽输出	GPIO_Mode_Out_OD 开漏输出
GPIO_Mode_AF_PP 复用推挽					GPIO_Mode_AF_OD复用开漏      */

GPIO_Init(GPIOx,&GPIO_InitStructure); //根据GPIO_InitStructure中的参数初始化GPIOx的寄存器,参数1可以是GPIOA...

按键的硬件消抖需要使用电容,硬件成本上升,按键软件消抖伪代码如下:

if(!GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)){
    delay_ms(20) //定时器延时20毫秒消抖
    if(!GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)){
    	//按下后的执行代码
	}
    while(!GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)); //等待按键松开
}

FLASH

Flash的写入

步骤:解锁,清除标志位,擦除,写入,清除标志位,锁

void FLASH_W(u32 add,u16 dat){ //Flash写入函数,add为32位Flash地址,dat为16位数据
    FLASH_Unlock(); //解锁Flash读写操作
    FLASH_ClearFlag(FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);//清除标志位
    //FLASH_FLAG_BSY:忙标志位			FLASH_FLAG_EOP:操作结束标志位
    //FLASH_FLAG_PGERR:编写错误标志位			FLASH_FLAG_WRPRTERR:页面写保护错误标志位
	FLASH_ErasePage(add); //擦除指定的地址页,1页有4个字节
    FLASH_ProgramHalfWord(add,dat); //从指定地址写入半个字   STM32中  1字 = 4字节 = 32位
    FLASH_ClearFlag(FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);//清除标志位
    FLASH_Lock();//锁定Flash读写操作
}

注:如果想要写入一个字,则dat需要定义为u32类型,写入函数改为FLASH_ProgramWord(add,dat);,其他大小参考固件库函数手册

Flash的读取:标准库中没有相关函数,所以自己写

u16 a; u32 add;	//16位数据(半字)  32位地址
a = *(u16*)(add) //将地址强制转换为u16指针,然后读取该指针指向地址的值,返回半字的数据
//如果把a设置为u8,然后(u16*)改为(u8*),即可读取一个字节

蜂鸣器:

蜂鸣器:蜂鸣器通过方波来控制蜂鸣器音调,通过方波个数控制蜂鸣器鸣笛时间长短,在使用蜂鸣器前记得先执行断开蜂鸣器的代码。

void BUZZER_BEEP1(u16 s){ //蜂鸣器响一声
	u16 i;
	for(i=0;i<200;i++){
		GPIO_WriteBit(GPIOx,GPIO_Pin_x,(BitAction)(0)); //蜂鸣器导通
		delay_us(500); //延时,两段延时之和控制频率周期长度,控制音调。而占空比控制响度。
		GPIO_WriteBit(GPIOx,GPIO_Pin_x,(BitAction)(1)); //蜂鸣器断开
		delay_us(500); //延时	
        //这里两个delay控制
	}
}

蜂鸣器播放MIDI音乐

MIDI乐谱数据定义(假设20个音符):

uc16 music1[40] = { //假定music1[偶数下标] 表示音符频率(单位Hz),music1[奇数下表] 表示持续时间(单位ms),这里定375ms为一拍
330,750, // 330作为频率,对应低音3    750 = 375*2,对应2拍
440,375,
494,375,
523,750,
//以下省略剩下的MIDI乐谱数据
}

演奏乐谱:

void MIDI_PLAY(void){ //演奏函数
	u16 i,e;
	for(i=0;i<20;i++){ //外循环遍历音符和节拍
		for(e=0;e<music1[i*2]*music1[i*2+1]/1000;e++){ //频率*时间=总周期数,除以1000是因为表示持续时间的单位是ms,而表示频率的单位是Hz。内循环对应控制持续时间
            //以下为一个周期对蜂鸣器的操作
			GPIO_WriteBit(GPIOx,GPIO_Pin_x,(BitAction)(0)); //蜂鸣器导通
			delay_us(500000/music1[i*2]); //因为后面还有另一半。所以t = 0.5s/f,得到一个音调对应的半个频率周期时长(即一个频率周期高电平时间),然后换算成us要乘1000000。
			GPIO_WriteBit(GPIOx,GPIO_Pin_x,(BitAction)(1)); //蜂鸣器断开
			delay_us(500000/music1[i*2]); //一个频率周期低电平时间,和前面另一半的0.5s组成一个1s
		}	
	}
}

附加

STM32数据类型

u32 //定义32位无符号变量   
u16 //定义16位无符号变量   
u8 //定义8位无符号变量    
vu32 //定义32位无符号易变变量   v相当于volatile 
vu16 //定义16位无符号易变变量   v相当于volatile  
vu8 //定义8位无符号易变变量     v相当于volatile 
uc32 //定义32位无符号常量    c相当于const
uc16 //定义16位无符号常量    c相当于const
uc8 //定义8位无符号常变量    c相当于const
//常量是存在Flash里面的!
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值