
第一章 keil uVision4软件的安装 1
第二章 工程文件夹的建立 1
第三章 串口 5
第四章 按键 7
第五章 SPI 9
第六章 LCD 12
第七章 DMA 14
第八章 GPIO口 19
第一章keil uVision4软件的安装
1.打开压缩包中的Keil →ARMKil4→ mdk460 。2
2. 安装完毕打开uVision4,点击复制右上角的CID
再打开压缩包中KEIL_Lic4
点击Generate生成许可号5
将许可号复制到License Management6,注册成功。
第二章 工程文件夹的建立
1、从固件库里面拷贝Libraries到我们的工程目录下.
2、再新建两个文件夹obj---存放工程生成的文件 user---存放我们以后自己新建的.c .h文件.
3、进入user目录新建两个文件夹 inc---存放我们的.h文件 src---存放我们的.c文件.
4、去到固件库里面的project里面STM32F10x_StdPeriph_Template.
5、新建工程文件 STM32project.
6、选择工程存放位置.
7、选择CPU型号 STM32F103ZE.
8、是否选择KEIL带的启动文件.
9、修改工程文件.
10、修改文件夹名和新建文件夹StdDriver、user.
11、添加文件.3个文件
12、修改编译环境.
13、建main.c文件.
#include "stm32f10x.h"
int main(void)
{
while(1)
{
}
}
编译文件
14、工程文件说明.
模块化编程--------每一个模块建立.h---函数声明 变量声明(声明的函数/变量可以被其它.c文件调用) .c文件---函数的实现 变量定义。
第三章 串口
1、 通用同步异步收发器 USART Universal Synchronous/Asynchronous Receiver/Transmitter
串口收发器可以配置为同步模式,也可以配置为异步模式
但是一般使用的是异步模式,同步模式很少使用,大家有兴趣的话可以自己研究下
也就是我们今天要讲的是通用异步收发器 UART
UART:通用异步收发器
1 、串口:一个字节,一根数据线,数据一位一位发送
并口:一个字节,8根数据线,字节的各个位同时发送
2、 同步:有时钟线,根据时钟线上的时钟脉冲,主从设备来决定自己是收数据还是发 数据
3、上面讲了怎么传输数据,还有一个主从机数据的传输方向问题了
全双工:收发同时进行 就是现在电话机 手机
线:3条:发TX 收RX 共地GND
半双工(分时复用):收发同一时间只能有一个在进行 对讲机
线:2条:收发公用一条线 共地
单工:只能发/只能收 打印机
二、串口驱动程序设计,实现电脑与开发板的通信
我们使用串口1---UART1
1、串口的初始化
初始化引脚---PA9,PA10
PA9----USART1_TX----推挽输出---2M 9600 115200
PA10----USART1_RX----浮空输入---电平更加稳定
初始化串口模块---设置数据帧和波特率,工作模式
使能串口模块,使能发送,使能接收
2、串口发送函数
While(USART->SR&(1<<7)==0);
USART->DR =data;
3、串口接收函数
signed char USART1_receive(void)
{
u8 data;
if((USART1->SR&(1<<5))!=0)//判断数据寄存器有没有进来数据,1代表收到数据,0代表没有收到数据
{
data=USART1->DR;
return data;
}
return -1;
}
4、电脑串口助手与开发板的通信
实现数据回显
三、用printf()从串口输出
microlib 提供了一个有限的 stdio 子系统,它仅支持未缓冲的 stdin、stdout 和 stderr。 这样,即可使用 printf() 来显示应用程序中的诊断消息。
要使用高级 I/O 函数,您必须提供自己实现的以下基本函数,以便与您自己的 I/O 设备配合使用。
fputc()为所有输出函数实现此基本函数。 例如,fprintf()、printf()、fwrite()、fputs()、puts()、putc() 和 putchar()。
int fputc(int ch, FILE *f)
{
UART2_SendByte(ch);
return (ch);
}
四、串口重映射
五、配置其它串口
第四章 按键
1、弄清按键所接引脚的配置属性
按键有两种状态:按下去和没按的状态。
比如说: CPU通过检测引脚是高电平还是低电平,来判断按键是否按下去
那么引脚应该配置为什么属性?
输入----
浮空输入--1,检测外部信号 2,引脚外面接有上拉电阻或下拉电阻按键引脚外面接有上拉电阻,选择浮空输入
下拉输入--
上拉输入--
模拟输入--
2、程序如何判断外部IO口的高低电平
GPIOx->IDR &(1< 判断高电平:PB5 (GPIOx->IDR&(1<<5))!=0; (!!((GPIOx->IDR)&(1< 判断低电平: (GPIOx->IDR&(1< 3、设计程序实现按键,按一次灯亮,再按一次灯灭 1、先把延时函数添加进去:添加delay_us delay_ms函数到工程 一定要:初始化延时函数 delay_init(72); delay_ms();最大只能延时:18ms 2、消抖 4、状态机的运用 定义一个静态变量,专门用来标示按键的状态 为什么要定义一个静态变量来表示按键的状态? 5、位带操作 像单片机一样操作引脚 PAout(n); PAin(n); PBout(n); PBin(n); PXout(n); PXin(n); 原理:Cortex-M3 的内部存储空间有2 个“位带区”,分别称为“ SRAM 位带区” 和“外设存储位带区”,各自位于 SRAM 区和外设存储区各自最低的 1MBit 空间;并有对应的 2 个“位带别名区”,分别称为“ SRAM 位带别名区”和 “外设存储位带别名区”,每个别名区大小为 32MBit。“位带”技 术将两 个“位带区”的每一位分别映射带对应的“位带别名区”的一个“字” (即 32 位)的最低位上。 这部分存储空间(32M)是通过映射技术“虚拟”出来的,STM32 片内的这部分地址空间并没有物理存储介质存在。 第五章 SPI 一、时序 1)时钟频率(波特率)------发送或者接收一个位要多长时间 我们M3最快18M SPI的输出时钟必须在从机的范围内 看时序图里面的时钟高低电平的最小时间 也就是找最小周期 要去有时间特性的时序图找。 如果找时钟频率找不到确定-------给最小 tch---200ns tcl—200ns T=400ns f=1/T ------2.5M 2)时钟相位和时钟极性 时钟相位CPHA--------上升沿/下降沿 0: 数据采样从第一个时钟边沿开 始;1: 数据采样从第二个时钟边沿开始。 通俗:就是上升沿采样数据还是下降沿采样数据 串口靠时间来数据。同步通信--采样数据就是什么时候去拿数据 时钟极性CPOL--------高低电平 作用:决定第一个时钟边沿-----空闲的时候的电平 时钟相位CPHA 和 时钟极性CPOL组合成多少种情况? 答:4种时序模式 1、空闲的时候时钟极性CPOL=0 ,时钟相位CPHA=0 上升沿采样数据 CPOL = 0 CPHA = 0 –> 空闲的时候时钟线SCK为低电平上升沿采样数据 2、空闲的时候时钟极性CPOL=0 ,时钟相位CPHA=1 下降沿采样数据 CPOL = 0 CPHA = 1 –> 空闲的时候时钟线SCK为低电平下降沿采样数据 3、空闲的时候时钟极性CPOL=1 ,时钟相位CPHA=0 下降沿采样数据 CPOL = 1 CPHA = 0 –> 空闲的时候时钟线SCK为高电平下降沿采样数据 4、空闲的时候时钟极性CPOL=1 ,时钟相位CPHA=1 上升沿采样数据 CPOL = 1 CPHA = 0 –> 空闲的时候时钟线SCK为高电平上升沿采样数据 时序里面时钟极性和相位,必须和从机的一样 一般:CPOL = 0 CPHA = 0 CPOL = 1 CPHA = 1 只有空闲状态不同------ 时钟线要求空闲的时候是低电平那就选CPOL = 0 CPHA = 0时钟线接下拉电阻 时钟线要求空闲的时候是高电平那就选CPOL = 1 CPHA = 1时钟线接上拉电阻 二、配置SPI: 1、初始化引脚 2、选择好SPI的时序 选择:时钟相位和极性 0 0 SPI_CR1 时钟相位-----0位 写0 SPI2->CR1 &=~(1<<0); 时钟极性-----1位 写0 波特率(最小的频率) 位5—位3 写111 3、选择SPI的数据位宽 8位----CR1---位11 写0 MSB先发----CR1----位7 写0 4、设置好硬件SPI的工作模式 (如果是软件管理-----M3里面的NSS脚就空出来,可以配置成其它功能使用) M3----主机(软件管理)--- CR1—位9 写1 CR1—位8 写1 CR1—位2 写1 全双工----CR1---位15 写0 CR1---位10 写0 第六章 LCD 一、LCD的概述 1、显示分辨率 段码式显示和点阵式显示 显示分辨率就是屏幕上用于显示的像素个数,分辨率160×128的意思是水平方向含有像素数为160个,垂直方向像素数128个。屏幕尺寸一样的情况下,分辨率越高,显示效果就越精细和细腻。 分辨率:1024*768 我们LCD:240*320=76800 2、像素颜色的表示:色彩深度 像素的颜色由一个二进制数表示;二进制位数越多,表示的颜色的种类越多,颜色 表现越细腻逼真 LCD1602 1BPP bit per pixel LCD128 1BPP 8BPP-------一个点用8个位 黑、灰、白色之间,有256个层次。 16BPP-----假彩色 16个位 65536 种 RGB—565 555 RGB—565 18BPP---666 24BPP------888真彩色 RGB 2 32BPP 3、TFT-LCD TFT(ThinFilmTransistor)是指薄膜晶体管,意即每个液晶像素点都是由集成在像素点后面的薄膜晶体管来驱动,从而可以做到高速度、高亮度、高对比度显示屏幕信息,是目前最好的LCD彩色显示设备之一。 由于TFT-LCD是色彩表现力强,图像质量好,所以TFT-LCD已成为现在的主流LCD,是现在笔记本电脑和台式机上的主流显示设备。 今天要讲的LCD就是TFT-LCD 根据显示原理的不同,还有两种类型的LCD:STN-LCD TFD-LCD 比如手机使用的显示屏有STN方式、TFD方式和TFT方式3种类型。其中图像质量最好的是TFT方式,笔记本电脑中所使用的显示屏大部分都是这种类型。但TFT虽然画面精美,耗电量却较大,因而对于手机而言,具有电池不耐用的缺点。STN方式虽然在图像质量方面最差,但是具有耗电量小、成本低的优点。TFD恰恰定位在TFT与STN的中间位置。图像质量虽然略逊于TFT,但耗电量少于TFT。 4、LCD的背光 因为液晶材料本身并不发光,所以在显示屏两边设有作为光源的灯管,而在液晶显示器的背面设有一块背光板(或均匀光板)和反光膜,背光板是由荧光物质组成的可以发射光线,其主要作用是提供均匀的背景光源。背光板发出的光线在穿过第一层偏振过滤层之后进入包含成千上万的液晶颗粒的液晶层,射入液晶物质中,液晶物质受电场的控制。 二、LCD驱动芯片的结构及工作过程 开发板上的LCD驱动芯片为ILI9341 其基本结构如下: ILI9341---有Graphics RAM (GRAM) 大小为240*320*18 bit 每个像素都有18个位来表示它的颜色;RAM有xy坐标 就相当一个二维数组unsigned short table[320][240] 与LCD上的像素点一一对应 1、LCD的控制原理 1、接口 串口 SPI IIC 串口 8080接口:并行接口 RGB接口 数据线:8---LCD1602/LCD128 16----TFT2.8 24 32 我们的TFT:16根 DB0-DB15 写使能:WR 总使能:E 读使能:RD 读写选择:W/R 片选: CE/CS 命令/数据线:RS或DC 6800---摩托罗拉 SPI IIC RGB STM32上对应的控制引脚: 数据线:-----推挽输出 时钟50M DB0---PD14 DB1---PD15 DB2---PD0 DB3---PD1 DB4---PE7 DB5---PE8 DB6---PE9 DB7---PE10 DB8---PE11 DB9---PE12 DB10---PE13 DB11---PE14 DB12---PE15 DB13---PD8 DB14---PD9 DB15---PD10 控制线:-----推挽输出 时钟10M WR:PD5 RD:PD4 CE:PG12 RS或D/C:PG0 第七章 DMA 1、DMA概述 直接存储器访问(Direct Memory Access)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。这里的外设在STM32上是指它的片内外设、如串口,SPI,ADC等,存储器是指内存(SRAM),程序存储器(flash)。传输过程无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。CPU和输入输出都处于并行操作。因此,使整个计算机系统的效率大大提高 一般用于大量数据的传输,如图片数据 DMA控制器和Cortex™-M3核心共享系统数据总线,执行直接存储器数据传输。当CPU和DMA同时访问相同的目标(RAM或外设)时, DMA请求会暂停CPU访问系统总线达若干个周期,总线仲裁器执行循环调度,以保证CPU至少可以得到一半的系统总线(存储器或外设)带宽。 2、DMA结构及工作过程 工作过程:就是数据搬运过程 1、参与数据传输的对象:外设和存储器 存储器和存储器 由DMA通道x配置寄存器(DMA_CCRx)(x = 1…7)的14位决定 0:非存储器到存储器模式; 1:启动存储器到存储器模式。 DMA通道x存储器地址寄存器(DMA_CMARx)(x = 1…7) DMA通道x外设地址寄存器(DMA_CPARx)(x = 1…7) 2、数据传输的方向:外设--》存储器 存储器--》外设 存储器《--》存储器 由DMA通道x配置寄存器(DMA_CCRx)(x = 1…7)的4位决定 DIR:数据传输方向 (Data transfer direction) 该位由软件设置和清除。 0:从外设读 DMA通道x外设地址寄存器 1:从存储器读 DMA通道x存储器地址寄存器 3、每次传输数据的大小:存储器数据宽度/外设数据宽度 8/16/32位 位11:10 MSIZE[1:0]:存储器数据宽度 (Memory size) 这些位由软件设置和清除。 00: 8位 01: 16位 10: 32位 11:保留 位9:8 PSIZE[1:0]:外设数据宽度 (Peripheral size) 这些位由软件设置和清除。 00: 8位 01: 16位 10: 32位 11:保留 4、传输数据的次数:数据传输次数为0至65535。 DMA通道x传输数量寄存器(DMA_CNDTRx)(x = 1…7) 这个寄存器只能在通道不工作(DMA_CCRx的EN=0)时写入 5、数据地址是否增加:存储器地址增量模式 /外设地址增量模式 由DMA通道x配置寄存器(DMA_CCRx)(x = 1…7)的7位决定 位7 MINC:存储器地址增量模式 (Memory increment mode) 该位由软件设置和清除。 0:不执行存储器地址增量操作 1:执行存储器地址增量操作 位6 PINC:外设地址增量模式 (Peripheral increment mode) 该位由软件设置和清除。 0:不执行外设地址增量操作 1:执行外设地址增量操作 当设置为增量模式时,下一个要传输的地址将是前一个地址加上增量 值,增量值取决与所选的数据宽度为1、 2或4。 6、数据传输是否循环:当启动了循环模式,数据传输的数目变为0时,将会自动 地被恢复成配置通道时设置的初值,内部的当前外设/存储器地址寄存器也被重新 加载为DMA_CPARx/DMA_CMARx寄存器设定的初始基地址。DMA操作将会 继续进行。当通道配置为非循环模式时,传输结束后(即传输计数变为0)将不再产 生DMA操作。要开始新的DMA传输,需要在关闭DMA通道的情况下,在 DMA_CNDTRx寄存器中重新写入传输数目。 存储器到存储器模式不能与循环模式同时使用 位5 CIRC:循环模式 (Circular mode) 该位由软件设置和清除。 0:不执行循环操作 1:执行循环操作 7、上面描述了关于单次DMA通道数据传输的各种设置,若多个通道的DMA申请同时产生如何响应就涉及到通道优先级的问题: 仲裁器根据通道请求的优先级来启动外设/存储器的访问。 优先权管理分2个阶段: ● 软件:每个通道的优先权可以在DMA_CCRx寄存器中设置,有4个等级: ─ 最高优先级 ─ 高优先级 ─ 中等优先级 ─ 低优先级 DMA通道x配置寄存器(DMA_CCRx)(x = 1…7) 位13:12 PL[1:0]:通道优先级 (Channel priority level) 这些位由软件设置和清除。 00:低 01:中 10:高 11:最高 ● 硬件:如果2个请求有相同的软件优先级,则较低编号的通道比较高编号的通道有较高的优先权。举个例子,通道2优先于通道4。 外设的DMA请求,可以通过设置相应外设寄存器中的控制位,被地开启或关闭。 DMA1的各个通道能够响应哪些外设的DMA请求 DMA2的各个通道能够响应哪些外设的DMA请求 3、DMA寄存器 DMA中断状态寄存器(DMA_ISR) DMA中断标志清除寄存器(DMA_IFCR) DMA通道x配置寄存器(DMA_CCRx)(x = 1…7) DMA通道x传输数量寄存器(DMA_CNDTRx)(x = 1…7) DMA通道x外设地址寄存器(DMA_CPARx)(x = 1…7) DMA通道x存储器地址寄存器(DMA_CMARx)(x = 1…7) 4、DMA程序设计 void DMA1_Channel1_Init(void) { //开启DMA1的时钟 RCC->AHBENR |=(1<<0); //从存储器到存储器 DMA1_Channel1->CCR |=(1<<14); //存储器的地址 DMA1_Channel1->CMAR=(u32)code; //外设的地址,外设的地址可以存储器的地址 DMA1_Channel1->CPAR=(u32)buff; //外设的地址 //通道优先级:高 DMA1_Channel1->CCR &=~(3<<12); DMA1_Channel1->CCR|=(2<<12); //传输的数据量 DMA1_Channel1->CNDTR =sizeof(buff); //存储器数据宽度:8位 DMA1_Channel1->CCR &=~(3<<10); DMA1_Channel1->CCR |=(0<<10); //外设数据宽度:8位 DMA1_Channel1->CCR &=~(3<<10); DMA1_Channel1->CCR |=(0<<10); //存储器地址增加 DMA1_Channel1->CCR |=(1<<7); //外设地址增加 DMA1_Channel1->CCR |=(1<<6); //不选择循环模式 DMA1_Channel1->CCR &=~(1<<5); //数据传输方向:从存储器读 DMA1_Channel1->CCR &=~(1<<4); //先关闭DMA1通道 DMA1_Channel1->CCR &=~(1<<0); 1、STM32F103ZET6单片机的简单介绍: 上面的片内外设除了FLASH和SRAM的时钟,是开机自动开启的,对于其它片内外设,你要用哪一个,就要开启那个片内外设的时钟,比如说,要用到ADC1,GPIOC,就要开启的它们的时钟;好处:不用就不开时钟,它就不工作,就不耗能,这样就降低功耗 那么,片内外设的时钟如何开启? 我们要开启哪个片内外设的时钟,就把相应的寄存器位设为1,就可以了 2,STM单片机的输入输出,就是GPIO 我们的MCU有多少引脚? 打开硬件原理图 PA--PG 7个端口 一个端口有16个引脚 总共7*16=112引脚 每个引脚都可以配置输出或输入 输出: 开漏输出---特点:只能输出低电平,要输出高电平,必须在引脚外面接上拉电阻,实现 高电平输出 好处:芯片之间的电压匹配; 推挽输出---特点:能够输出高低电平,输出能力强 开漏复用输出---片内外设的输出接口---IIC硬件总线 推挽复用输出---片内外设的输出接口 输入: 浮空输入--IO口悬空,输入信号完全由外部信号决定,一般用来测量外部信号,当然受外部干扰也大,如果外面引脚接有上拉电阻或者下拉电阻,就选择浮空输入模式 上拉输入--内部接有上拉电阻,能得到稳定的高电平 下拉输入--内部接有下拉电阻,能得到稳定的低电平 模拟输入--模拟信号的输入 ADC 3、如何配置寄存器,实现上述输入输出功能? 每个引脚用四位来配置,假如不配置,默认为浮空输入 上拉输入或下拉输入,需要配置PxODR寄存器 设置引脚的输入输出模式,要在寄存器的对应位配置什么值,这个我们已经知道了 4、如何写代码来完成寄存器的配置 例如:PA端口的5引脚配置 PA5 为推挽输出 2M 0010 0X2 PA0--PA7 先清零 再设值 GPIOA->CRL = GPIOA->CRL & 0XFF0FFFFF GPIOA->CRL = GPIOA->CRL | 0X00200000; GPIOA->CRL &=0XFF0FFFFF; //清零 GPIOA->CRL | = 0X00200000; //设置 0XFF0FFFFF = ~(0XF<<5*4); PA6 0X00200000 = (0X2<<5*4) GPIOA->CRL &=~(0XF<<5*4); GPIOA->CRL | = (0X2<<5*4) GPIOA->CRL &=~(0XF< GPIOA->CRH &=0XFF0FFFFF; //清零 GPIOA->CRH | = 0X00200000; //设置 GPIOA->CRH &=~(OXF<<(10-8)*4); PA8 GPIOA->CRH |=(0X2<<(10-8)*4); 三:如何输出高低电平 GPIOx_ODR GPIOx_BSRR GPIOx_BRR 输出高电平 GPIOX->ODR |=(1< 低电平 GPIOB->ODR &=~(1<<5); GPIOx->BSRR =(1< GPIOX->ODR &=~(1< GPIOX->BRR =(1< GPIOx_IDR If(GPIOX->IDR&(1<
第八章 GPIO口}
