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比较简单。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐