stm32学习笔记(二)

发布于:2022-11-13 ⋅ 阅读:(1362) ⋅ 点赞:(1)

keil实战——新建工程模板 

新建项目的时候发现没有32的库,还需要自己添加一下,去官网下载,网址:MDK5 Software Packs

野火视频用的是F1

在网址里找到keil这个标题,往下翻

下载即可

 

 下载完以后双击安装

 装了MDK会自动识别,直接点击NEXT,装完以后点击finish

我是装完才截的图,会有警告,没装过的不会有,忽略警告就好

 新建步骤如图,视频里讲的很清楚,就不细说了

 

 

 

下图直接关闭即可

 添加启动文件,地址如下

A盘(资料盘)\3-STM32官方资料\STM32F103官方固件库与手册(标准库)\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm

把startup_stm32f10x_hd.s复制到工程目录下

复制以后在keil中双击Source Group1,添加此文件到工程里 

在目录里新建txt文件,把名字改为main.c ,以同样的步骤把main添加进工程里,别忘了添加.h文件

 我txt文件无论怎么改名都无法转换成.c文件

解决办法:

这是我在csdn找的http://t.csdn.cn/0DJQy

1、首先你要有C/C++软件,如DEV-C(下载地址如下Dev-C++ download | SourceForge.net)

2、如果你是WIN10系统。首先打开“此电脑”,依次点“查看”-“选项”-“查看”,将“隐藏已知文件类型的扩展名”前面的勾去掉,再确定,让系统显示完整的文件全名。然后.c后缀就能直接改成C文件。

 双击选项

去掉选项以后再进行重命名的操作就可以了

新建项目,编译

此时直接编译的话,会出现如下错误:
“ Error: L6218E: Undefined symbol SystemInit (referred from startup_stm32f429_439xx.o)”
错误提示 SystemInit引用但没有定义。

图 2  汇编文件

由图汇编文件可知,运行的时候会先运行SystemInit,初始化系统时钟以后在调用面函数

在main函数外面做一个空实现,即可解决报错

这块我从一开始就出现了意想不到的问题,

然后就是我明明输的和老师一样吧,SystemInit报错no previous prototype for function systeminit

解决办法:

鼠标右键点击Target 1,选择Options for Group‘Source Group 1...’

将 6选成5即可

 

然后还没完呢,现在编译器确实不报错了,但是呢编译不过,会出现以下问题,编译终止

神奇的事情来了,既然Version 5 is not available,我就又换回Version 6了,这次编译页面也没有报错,编译也是直接就过了。

1.include<>与include" "区别

 include<>表示文件不在当前目录下,在编译器目录下

 include" "表示在当前目录下找不到,再去软件目录下找

 .hex:通过串口下载的可执行文件

.axf:通过编译器下载的可执行文件

.sct:加载没听清,以后补文件

下载程序

debug里选择DAP

 确保Utilities里的use debug driver是勾选上的

 然后在返回debug,在选择DAP的位置点击setting,在debug界面确保SWJ是勾选上的,时钟选择5MHz

 切换到Flash Download界面,勾选reset and run

 下载即可。如果出现这个报错,重新编译下

 我实际下载的时候发现与视频中不一样,我的无法勾选SWJ,如图

 去问了淘宝客服,说是版本不一样,只需connect处选择under Reset,Reset处选择SYSRESETREQ,,然后再次下载,就能成功了。

2.屏蔽   #if 0

             #else

             # end if

点亮LED灯

点灯三部曲

//  1.打开时钟 在AHB上
//  2.设置输出模式   GPIOx_CRL
//  3.开灯 用CDR设置指定位置为0

步骤

 图 3 指南者原理图

(1)由图可知,PB0控制灯,PB0为0,灯亮

PB0通过GPIOB_ODR第0位控制 

复位值为0x0000 0000,所以低十六位全是0

  *(unsigned int*) (0x40010C0C) & =~(1<<0);利用上一篇最后的清零操作

这一部相当于

(2)显然光有这一步等还是不会亮,这是由于PB0目前是输入状态,不是输出状态,需改变输入状态

此寄存器四位控制一个IO口 ,CRL思维控制的一个io口,相当于ODR寄存器里的pb0

由下方每一位的解释来选择模式,LED一般用推挽输出,所以CNF选择00,MODE选择01(此位置选择没有固定原因,就是随机选择)

*(unsigned int*)0x40010C00 |=((1)<<(4*0));//最后一位置一

这行刚开始代码我一直理解的不太好,找淘宝客服battle半天,后面发现按我的理解完全可以实现视频里的结果,并且作业中的点亮其他灯也完美实现,所以我觉得我的理解没有问题

这里说一下我的理解,确实是像视频里说的一样四个一组,

*(unsigned int*)0x40010C00 |=((1)<<(4*0));这行代码在我这边是这样的

*(unsigned int*)0x40010C00 |=((0x01)<<(4*0));相当于是0001这个整体左移了4个0;

在CRL寄存器里,四位对因一个PBx,如图

所以在程序里我这行代码是这样写的(*(unsigned int*)(0x40010C00))|= ((0x01)<<(0*(4*1)));

(3)加上这一步以后,灯还是不能点亮,这是因为GPIO时钟被关闭

 所以还要将时钟使能

  

可知0时钟关闭,所以要置一,地址为0x40021018,IOPB在第三位,所以左移三位置一

*(unsigned int*)0x40021018 |=(1<<3);

整体代码如下

 作业

作业需要注意的是,灯对应的引脚不一样,其对应的CRL寄存器的位不一样,记得改CRL的值

点灯代码如下

//点亮蓝灯
	//记得改CRL输出端口,不然输出端口一直是PB0,亮什么蓝灯啊
	(*(unsigned int*)(0x40021018))|=(1<<3);
	(*(unsigned int*)(0x40010C00))|= ((0x01)<<(4*1));//配置低寄存器CRL 模式为 0001  PB0的端口
  //(*(unsigned int*)(0x40010C0C)) |=(1<<0); 可以不需要,因为CRL输出端口变了
	(*(unsigned int*)(0x40010C0C)) &=~(1<<1);
	
	
		//点亮红灯
	//打开时钟 APB2 外设时钟使能寄存器(RCC_APB2ENR)
	(*(unsigned int*)(0x40021018))|=(1<<3);
	(*(unsigned int*)(0x40010C00))|= ((0x01)<<(5*(4*1)));//配置低寄存器CRL 模式为 0001  PB1的端口
	(*(unsigned int*)(0x40010C0C)) &=~(1<<5);

延时函数

原因是函数写道main函数以后,并且没在main前声明

void mydelay(int dy)
{
  int i=0;
  int j=0;	
	for(i=0;i<dy;i++)
	{
		for(j=0;j<1000;j++)
		{
			
		}
	}
}

蓝灯闪烁

//蓝灯闪烁
		(*(unsigned int*)(0x40021018))|=(1<<3);
		(*(unsigned int*)(0x40010C00))|= ((0x01)<<(4*1));
		while(k<10){
		
		(*(unsigned int*)(0x40010C0C)) &=~(1<<1);//点蓝灯
		mydelay(500);
	  (*(unsigned int*)(0x40010C0C)) |=(1<<1);//关蓝灯
		mydelay(500);
		k++;
	}

绿蓝红依次闪烁

(*(unsigned int*)(0x40021018))|=(1<<3);
		while(k<10){
		(*(unsigned int*)(0x40010C00))|= ((1)<<(4*0));
		(*(unsigned int*)(0x40010C0C))&=~(1<<0);//点绿灯
		mydelay(500);
		(*(unsigned int*)(0x40010C0C)) |=(1<<0);  //关闭绿灯
		mydelay(500);
		
		(*(unsigned int*)(0x40010C00))|= ((0x01)<<(4*1));
		(*(unsigned int*)(0x40010C0C)) &=~(1<<1);//点蓝灯
		mydelay(500);
	  (*(unsigned int*)(0x40010C0C)) |=(1<<1);//关蓝灯
		mydelay(500);
		
		(*(unsigned int*)(0x40010C00))|= ((0x01)<<(5*(4*1)));
		(*(unsigned int*)(0x40010C0C)) &=~(1<<5);//点红灯
		mydelay(500);
		(*(unsigned int*)(0x40010C0C)) |=(1<<5);//关红灯
		mydelay(500);
		k++;
	}

优化版,在h文件中声明好地址

//基地址
#define PERIPH_BASE      ((unsigned int)0x40000000)

//总线基地址   AHB  APB1  APB2
#define   APB1PERIHP_BASE      PERIPH_BASE                 //((unsigned int)0x40000000)
#define   APB2PERIHP_BASE     (PERIPH_BASE + 0x10000)     //((unsigned int)0x40000000 + 00010000)   
#define   AHBPERIHP_BASE     (PERIPH_BASE + 0x20000)    //AHB前三位为保留,单独定义,从0x20000开始定义

 GPIO功能概述

全称:General purpose input output,软件可控制的引脚

 1.GPIO包含在引脚内部

2.查找stm32数据手册

 功能框图


网站公告

今日签到

点亮在社区的每一天
去签到