本帖最后由 qjp1988113 于 2020-9-30 12:42 编辑
今天测试下HC32F460的位段功能。由于官方没提供例程,该程序由正点原子STM32对应的程序修改。
先来看下华大手册的官方描述:
写的比较简单,也未给出详细的具体操作说明。
下面给出STM32关于位段操作的说明,含地址对应公式:
我们参考M3编程手册--《Cortex M3权威指南》里面的位段说明,因为它是中文版本。
很明显位段的功能,就是把外设寄存器BIT位的操作控制等效为一个32为地址寄存器的操作。
我们往这个地址写读均能得到对应外设寄存器BIT位等效的回应。当然这个等效的寄存器地址
跟外设是有一定关联的。
再具体大家可以去看上面的那本书。
华大HC32F460的例程里面对于寄存器的定义划分和ST还是有差异的,我们查找手册(我们这里仅仅做IO输出输入的控制):
有这3个寄存器的明细,我们就可以开始了:
//periBitBand 0X42000000 ~0X43FFFFFF 32M
//GPIO 0X40053800 ~0X40053FFF 1K
#define GPIO_BASE (0x40053800ul)
//位带操作,实现51类似的GPIO控制功能
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
//IO口地址映射
#define GPIOA_ODR_Addr (GPIO_BASE+0X04+0X10*0) //0x40020014
#define GPIOB_ODR_Addr (GPIO_BASE+0X04+0X10*1) //0x40020414
#define GPIOC_ODR_Addr (GPIO_BASE+0X04+0X10*2) //0x40020814
#define GPIOD_ODR_Addr (GPIO_BASE+0X04+0X10*3) //0x40020C14
#define GPIOE_ODR_Addr (GPIO_BASE+0X04+0X10*4) //0x40021014
#define GPIOH_ODR_Addr (GPIO_BASE+0X04+0X10*5) //0x40021C14
#define GPIOA_IDR_Addr (GPIO_BASE+0x00+0X10*0) //0x40020010
#define GPIOB_IDR_Addr (GPIO_BASE+0x00+0X10*1) //0x40020410
#define GPIOC_IDR_Addr (GPIO_BASE+0x00+0X10*2) //0x40020810
#define GPIOD_IDR_Addr (GPIO_BASE+0x00+0X10*3) //0x40020C10
#define GPIOE_IDR_Addr (GPIO_BASE+0x00+0X10*4) //0x40021010
#define GPIOH_IDR_Addr (GPIO_BASE+0x00+0X10*5) //0x40021C10
//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入
#define PHout(n) BIT_ADDR(GPIOH_ODR_Addr,n) //输出
#define PHin(n) BIT_ADDR(GPIOH_IDR_Addr,n) //输入
在加入上诉定义之后后,我们就可以使用了。
我们定义:
//IO输出
#define LED0 PEout(6)
#define LED1 PAout(7)
#define LED2 PBout(5)
#define LED3 PBout(9)
//IO输入
#define KEY0 PDin(3) //PD3
#define KEY1 PDin(4) //PD4
#define KEY2 PDin(5) //PD5
#define KEY3 PDin(6) //PD6
当然IO口的初始化程序要另写。
//按键扫描程序:
uint8_t KEY_Scan(uint8_t mode) //按键扫描函数
{
static uint8_t key_up=1;//按键按松开标志
if(mode)key_up=1; //支持连按
if(key_up&&(KEY0==0||KEY1==0||KEY2==0||KEY3==0))
{
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(KEY3==0)return 4;
}else if(KEY0==1&&KEY1==1&&KEY2==1&&KEY3==1)key_up=1;
return 0;// 无按键按下
}
main函数里面的调用:
key=KEY_Scan(0); //得到键值
if(key)
{
switch(key)
{
case KEY0_PRES: //控制LED0翻转
LED0=!LED0;
break;
case KEY1_PRES: //控制LED1翻转
LED1=!LED1;
break;
case KEY2_PRES: //控制LED2翻转
LED2=!LED2;
break;
case KEY3_PRES: //控制LED3翻转
LED3=!LED3;
break;
}
}else delay_ms(10);
编译下载,具体现象:
好了,今天就到这!
|