STM32寄存器及HAL库的LED程序
在搞清楚我们要用的几个寄存器的地址,以及寄存器中需要装填的数值以后,现在用一个简单粗暴的方法来操作这些寄存器——直接操作。(注意,这段代码不是实用的代码,只是为了写出一个最简单的LED,有些部分是不可取的。选这个_md.s的,这里我是已经移过来的,这个驱动文件需要移动到你所创建的项目目录里,没有的话去下一个就行。通过点上面的zoom栏中的in或者out将旁边的grid改为1s,并且勾选右边的sig
1,原理了解
寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和地址。访问寄存器的时候通过不同的地址来区分不同的寄存器。那么如果需要找某个寄存器的地址,我们就需要查看数据手册。
手册中没有直接给出所有的寄存器的地址,需要读者稍加计算。STM32给不同的寄存器分配了不同的地址,有点像划分了片区。在《STM32中文参考手册_V10》的第28页,有不同寄存器的地址范围。
第一步,找到GPIOB的基地址
所有GPIOB相关的寄存器,都住在0x4001 0C00到0x4001 0FFF范围内。
第二布,找到端口寄存器的数据偏移
找到存储数据的那个屋子,结论是0x4001 0C00+8 = 0x4001 0C08
第三步,找到知道数据的那个人
PB3的数据位于从右往左数第4个
而这个寄存器的位数是32位,这就是32位的单片机的意思。
经过这三步查找,我们可以做出以下结论:
PB3的输入数据位于0x4001 0C08这个地址上,这个地址上存放数据的右起第4个位就是PB3引脚对应的高低电平。
直接操作寄存器来点亮LED
时钟控制名字叫做RCC,属于AHB总线。GPIOB属于APB2
控制LED需要输出高电平或是低电平,所以需要配置为输出。
配置引脚PB8,使用的寄存器是GPIOB_CRH。下面我们来寻找这个寄存器的地址。
点亮LED需要输出低电平
在单片机的编程中,要想做某件事,必须寻找相应的寄存器。在8.2.4小节,可以找到端口输出数据寄存器,就是我们需要的。我们需要输出0。
使用直接赋值的方式写寄存器的地址
在搞清楚我们要用的几个寄存器的地址,以及寄存器中需要装填的数值以后,现在用一个简单粗暴的方法来操作这些寄存器——直接操作。(注意,这段代码不是实用的代码,只是为了写出一个最简单的LED,有些部分是不可取的。)将main函数修改为:
int main(void)
{
unsigned int *pRCC_APB2ENR = (unsigned int *)0x40021018;
unsigned int *pGPIOB_CRH = (unsigned int *)0x40010c04;
unsigned int *pGPIOB_ODR = (unsigned int *)0x40010c0c;
*pRCC_APB2ENR = 0x00000008;
*pGPIOB_CRH = 0x44444443;
*pGPIOB_ODR = 0x00000000;
return 0;
}
二,使用寄存器实现流水灯
了解完上面所述的GPIO的地址,下面先用寄存器实现流水灯的工作方式
开发工具:keil5,mcuisp
先用keil5新建一个工程
芯片选择我这里是STM32F103C8
然后再环境中只勾选cmsis的第二个
记得在output勾选打印hex文件后面要用
然后再sourcegroup文件下面新建一个.c文件取完名后粘贴下列代码
//--------------APB2???????------------------------
#define RCC_AP2ENR *((unsigned volatile int*)0x40021018)
//----------------GPIOA????? ------------------------
#define GPIOA_CRL *((unsigned volatile int*)0x40010800)
#define GPIOA_ORD *((unsigned volatile int*)0x4001080C)
//----------------GPIOB????? ------------------------
#define GPIOB_CRH *((unsigned volatile int*)0x40010C04)
#define GPIOB_ORD *((unsigned volatile int*)0x40010C0C)
//----------------GPIOC????? ------------------------
#define GPIOC_CRH *((unsigned volatile int*)0x40011004)
#define GPIOC_ORD *((unsigned volatile int*)0x4001100C)
//-------------------???????-----------------------
void Delay_wxc( volatile unsigned int t)
{
unsigned int i;
while(t--)
for (i=0;i<800;i++);
}
//------------------------???--------------------------
int main()
{
int j=100;
RCC_AP2ENR|=1<<2; //APB2-GPIOA??????
RCC_AP2ENR|=1<<3; //APB2-GPIOB??????
RCC_AP2ENR|=1<<4; //APB2-GPIOC??????
//????????? RCC_APB2ENR|=1<<3|1<<4;
GPIOA_CRL&=0x0FFFFFFF; //??? ??
GPIOA_CRL|=0x20000000; //PA7????
GPIOA_ORD|=1<<7; //???????
GPIOB_CRH&=0xFFFFFF0F; //??? ??
GPIOB_CRH|=0x00000020; //PB9????
GPIOB_ORD|=1<<9; //???????
GPIOC_CRH&=0x0FFFFFFF; //??? ??
GPIOC_CRH|=0x30000000; //PC15????
GPIOC_ORD|=0x1<<15; //???????
while(j)
{
GPIOA_ORD=0x0<<0; //PB0???
Delay_wxc(1000000);
GPIOA_ORD=0x1<<0; //PB0???
Delay_wxc(1000000);
GPIOB_ORD=0x0<<9; //PB9???
Delay_wxc(1000000);
GPIOB_ORD=0x1<<9; //PB9???
Delay_wxc(1000000);
GPIOC_ORD=0x0<<15; //PC15???
Delay_wxc(1000000);
GPIOC_ORD=0x1<<15; //PC15???
Delay_wxc(1000000);
}
}
然后还是点击sourcegroup添加一个驱动文件,文件类型选all files
选这个_md.s的,这里我是已经移过来的,这个驱动文件需要移动到你所创建的项目目录里,没有的话去下一个就行。然后添加完build。然后会生成hex文件,一般都是在objects文件夹中。然后用mcuisp烧录。
先搜索串口,然后读器件信息。再点开始编程,右边就是成功的结果
流水灯
然后信号灯会如上闪烁
三,使用32cudemx做
所需软件:STM32CubeMX,keil5,jre
先下载STM32CubeMX(注意该软件只能在java环境下打开)
一路默认安装就行,进入主界面
点击help里的manage…选择最新版本的插件下载
然后点击FIle。新建project
1处选择需要的芯片型号,2处会弹出芯片。然后点3处开始
先在SystemCore中SYS将debug改为serial wire
然后再rcc中
将HSE改为Crystal,然后点击上面的clock configuration
将那里的引脚改为第三个。然后返回rcc,将芯片的引脚A4,B9,C15设为output
然后点击上面的Project Manager
设置工程名,存储路径,一定要将IDE那栏改为MDK ARM,然后点击左边的code manager
勾选generated files第一项然后点右上角的generat code。可以直接选open project。
然后就会进到keil5里面
点击main.c将里面的while循环替换为如下的代码
SystemClock_Config();//系统时钟初始化
MX_GPIO_Init();//gpio初始化
while (1)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);//PA4亮灯
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);//PB9熄灯
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_SET);//PC15熄灯
HAL_Delay(1000);//延时1s
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);//PA4熄灯
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);//PB9亮灯
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_SET);//PC15熄灯
HAL_Delay(1000);//延时1s
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);//PA4熄灯
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);//PB9熄灯
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_RESET);//PC15亮灯
HAL_Delay(1000);//延时1s
}
替换完后点击build,同样会生成hex文件,进行跟前面一样的烧录,然后得到跟前面一样的效果这里主要是观察波形。
点击porject进入options for target“工程名
然后再的不过一页那里改为下面的配置
然后开始调试debug,选择逻辑分析仪
点那个setup,然后
添加前面选的引脚地址,type选bit
通过点上面的zoom栏中的in或者out将旁边的grid改为1s,并且勾选右边的signal info和cursor两项就会出现如上的波形图。至此,全部结束。总结使用STM32CUBEMX比较简单。
更多推荐
所有评论(0)