导图社区 STM32-总结(9页)
基于野火视频与书籍教程入门、中级,包括GPIO、RCC、EXTI、定时器、USART、DMA、I2C读写eeprom、SPI读写FLASH的浅析与编程方法等。
编辑于2020-07-03 11:20:26连接
stm32F103ZET6
串口
ISP一键下载
BOOT配置ISP模式,BOOT1硬件地 RTS低,S8550导通,BOOT0拉高
复位,NRST低,重进ISP模式,DTR输出高 S8050导通,NRST=RST=低
系统进入ISP模式,BOOT0和NRST还原成原来状态 (上位机控制RTS、DTR
ISP下完,程序自动运行 (上位机控制RTS、DTR
单元
驱动单元(总线
Icode
取指
Dcode
const常量
FLASH
变量
内部SRAM
驱动单元
SYSTEM
寄存器
DMA
不占CPU传数据
被动单元
FLASH
程序
SRAM
变量、堆栈
FSMC
扩展静态内存
AHB
APB2
APB1
工程文件结构
Doc
说明文件
Libraries
CMSIS
startup、内核文件
STM32F10x_StdPeriph_Driver
外设库
Project
工程、hex
User
main、外设bsp、库头文件
删除编译
固件库文件结构
汇编启动文件
startup_stm32f10x_hd.s
堆栈指针
PC指针
初始化中断向量表
配置系统时钟
C库函数_main->C
时钟配置文件
system_stm32f10x.c
外部时钟HSE=8M,PLL倍频72兆
外设
stm32f10x.h
实现内核之外外设寄存器映射
stm32f10x_xx.c
外设驱动函数库文件
置位
复位
初始化
stm32f10x_xx.h
存放外设初始化结构体
外设初始化结构成员参数列表
外设固件库函数声明
xxx
GPIO
UART
I2C
SPI
FSMC
内核
CMSIS-Cortex微控制器软件接口
core_cm3.c
core_cm3.h
内核内外设寄存器映射
NVIC(嵌套向量中断控制器) SysTick(系统滴答定时器)
misc.h
misc.c
头文件配置文件
stm32f10x_conf.h
头文件的头文件//
stm32f10x_usart.h
stm32f10x_i2c.h
stm32f10x_spi.h
stm32f10x_sdc.h
stm32f10x_fsmc.h
中断服务存放函数文件
stm32f10x_it.c
stm32f10x_it.h
随便放
main.c
系统时钟已配置为72M
GPIO
按键检测
检测函数
uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin) { if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON ) { while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON); return KEY_ON; } else return KEY_OFF; }
检测按键是否按下 等待按键释放
位带
膨胀为32位字
外设位带
AliasAddr=0x42000000+(A-0x40000000)*8*4+n*4
SRAM位带
AliasAddr=0x22000000+(A-0x20000000)*8
((addr & 0xF0000000)+0x02000000+((addr & 0x00FFFFFF)<<5)+(bitnum<<2))
优化
#define ON 0 #define OFF 1
灯
#define LED1(a) if (a) \ GPIO_SetBits(LED1_GPIO_PORT,LED1_GPIO_PIN);\ else \ GPIO_ResetBits(LED1_GPIO_PORT,LED1_GPIO_PIN)
输入 输出
宏定义
#define LED1_GPIO_PORT GPIOB
#define LED1_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED1_GPIO_PIN GPIO_Pin_5
初始化
RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK,ENABLE); 开时钟
RCC->APB2ENR
GPIO_InitTypeDef 配置引脚
GPIO_Pin
选择管脚
输出速度 GPIO_Speed
GPIO_Speed_10MHz
GPIO_Speed_2MHz
GPIO_Speed_50MHz
输出模式 GPIO_Mode
GPIO_Mode_AIN
模拟
GPIO_Mode_IN_FLOATING
浮空
按键
GPIO_Mode_IPD
下拉
GPIO_Mode_IPU
上拉
输入
不配置时钟
GPIO_Mode_Out_OD
开漏
GPIO_Mode_Out_PP
推挽
LED
GPIO_Mode_AF_OD
复用开漏
GPIO_Mode_AF_PP
复用推挽
输出
GPIO_Init 传入与初始化GPIO
控制
GPIO_SetBits
置位
BSRR
GPIO_ResetBits
清0
BRR
时钟树
1.HSE高速外部时钟信号
4-16M
有源晶振
OSC_OUT悬空
无源晶振
OSC_IN,OUT入+谐振电容
一般8M无源
确定PLL时钟源
RCC_CFGR.17-PLLXTPRE
不分频
1
2分频
2.PLL时钟源
RCC_CFGR.16-PLLSRC
1
HSE=8M
HSI/2
内部8M高速,温漂
3.PLL时钟PLLCLK
设置PLL倍频因子
RCC_CFGR.21-18-PLLMUL
[2~16]
0111
9倍频
72M
4.系统时钟SYSCLK
RCC_CFGR.1-0-SW
01
SYSCLK=PLLCLK=72M
5.AHB总线时钟HCLK
AHB预分频器
RCC_CFGR.7-4-HPRE
[1,2,4,8,16,128,256,512]
0xxx
不分频
HCLK=SYSCLK=72M
6.APB2总线时钟PCLK2
APB2预分频器
RCC_CFGR.13-11-PPRE2
高速外设
GPIO
USART1
SPI1
[1,2,4,8,16]
0xx
不分频
PCLK2=HCLK=72M
7.APB1总线时钟PCLK1
低速APB预分频器
RCC_CFGR.10-8-PRRE1
低速外设
USART2/3/4/5
SPI2/3
I2C1/2
[1,2,4,8,16]
100
2分频
PCLK1=HCLK/2=36M
其他时钟
A-USB时钟
PLLCLK经USB预分频器
RCC_CFGR.22-USBPRE
[1,1.5]
只能48/72M
一般72,只能HSE倍频
最高48M
B-Cortex系统时钟
HCLK8分频
驱动内核系统定时器SysTick
操作系统时钟节拍/普通计时
C-ADC时钟
ADC预分频器
RCC_CFGR.15-14-ADCPRE
[2,4,6,8]
最高14M
采样周期1.5T
1μs
D-RTC时钟
RCC_BDCR.9-8-RTCSEL
HSE/128分频
低速外部时钟LSE
32.768KHz
低俗内部时钟HSI
独立看门狗时钟
LSI
32-60KHz(40)
E-MCO时钟输出
PA8
RCC_CFGR.26-24-MCO
PLLCLK/2
HSI
HSE
SYSCLK
MCO
初始化MCO引脚
MCO_GPIO_Config
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
开时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
PA8复用MCO
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
复用功能推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
输出速度
GPIO_Init(GPIOA, &GPIO_InitStructure);
初始化
设置引脚输出时钟 |
RCC_MCOConfig(RCC_MCO_SYSCLK);
RCC_MCOConfig(RCC_MCO_HSE);
RCC_MCOConfig(RCC_MCO_HSI);
RCC_MCOConfig(RCC_MCO_PLLCLK_Div2);
RCC
系统时钟SYSCLK
AHB 分频因子
HCLK
APB2 分频因子
PCLK2
72M
APB1 分频因子
PCLK1
36M
HSE_SetSysClock(uint32_t pllmul)
0
RCC外设复位
RCC_DeInit();
1
使能
RCC_HSEConfig(RCC_HSE_ON);
RCC->CR
等待
HSEStartUpStatus = RCC_WaitForHSEStartUp();
FLASH
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_2);
1、开启HSE,等待HSE稳定
2
AHB 1分频
RCC_HCLKConfig(RCC_SYSCLK_Div1);
APB2 1分频
RCC_PCLK2Config(RCC_HCLK_Div1);
APB1 1分频
RCC_PCLK1Config(RCC_HCLK_Div2);
2、设置AHB、APB2、APB1分频因子
RCC->CFGR
3, 4
PLL源HSE,倍频因子
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, pllmul);
使能
RCC_PLLCmd(ENABLE);
等待稳定
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}
3、设置PLL时钟源、倍频因子 4、开启PLL,稳定
5, 6
PLL作系统时钟来源
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
读状态位
while (RCC_GetSYSCLKSource() != 0x08){}
5、PLLCLK切换为SYSCLK 6、读时钟切换状态位
else
若HSE启动失败...
各个外设分频因子
HSI
中断
NVIC
嵌套向量中断控制器
__IO uint32_t ISER[8];
中断使能
__IO uint32_t ICER[8];
中断清除
__IO uint8_t IP[240];
中断优先级
初始化
NVIC_InitTypeDef
NVIC_IRQChannel
中断源
typedef enum IRQn
NVIC_IRQChannelPreemptionPriority
抢占优先级
NVIC_IRQChannelSubPriority
子优先级
NVIC_IRQChannelCmd
使能/失能
优先级
分组
NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
NVIC_PriorityGroup_0
NVIC_PriorityGroup_1
NVIC_PriorityGroup_2
NVIC_PriorityGroup_3
NVIC_PriorityGroup_4
EXTI- 外部中断/ 事件控制器
中断
1、中断/事件输入
GPIO/外设电平变化信号
2、↑/↓触发寄存器控制
3、|门
2
事件寄存器EXTI_SWIER
任意有效
4
6
4、&门
3
中断屏蔽寄存器EXTI_IMR
是否产生中断
EXTI_PR
5、NVIC
事件
123
6、&门
3
EXTI_EMR
是否产生事件
7、脉冲发生器
6-1产生脉冲
8、脉冲信号
触发TIM、ADC开始转换.etc
中断事件线
编程顺序
使能中断请求
外设相关中断使能位
配置中断优先级分组
编写中断服务函数
初始化
EXTI_Key_Config()
结构体
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
配置优先级
EXTI_NVIC_Config();
NVIC_InitTypeDef NVIC_InitStruct;
优先级分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
设置中断源按键1
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
PC13-ECTI15_10_IRQn
抢占优先级1
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
子优先级1
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
中断通道使能
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
初始化GPIO
RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK, ENABLE); GPIO_InitStruct.GPIO_Pin = KEY1_INT_GPIO_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStruct);
初始化EXTI
时钟允许
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
EXTI信号源选择
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
EXTI_InitStruct.EXTI_Line = EXTI_Line0;
中断模式
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
上升沿中断
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
中断使能
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct);
中断服务函数
EXTI0_IRQHandler();
#define KEY1_IRQHandler EXTI0_IRQHandler
void KEY1_IRQHandler(void) { if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) { LED1_TOGGLE; EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE); } }
SysTick- 系统定时器
简介
内核嵌套NVIC中
24位仅递减
T=1/SYSCLK
SysTick_CTRL 控制状态寄存器
16.COUNTFLAG
计到0置1
读取软件清0
2.CLKSOURCE
0
AHB/8
1
AHB
72M
1.TICKINT
数到0异常
0无动作
0.SysTick
定时器使能
SysTick_Delay_ms(uint32_t ms)
计数值
SysTick_Config(72000);
循环
for(i=0;i<ms;i++) {while( !((SysTick->CTRL) & (1<<16)) );}
清标志
SysTick->CTRL &=~ SysTick_CTRL_CLKSOURCE_Msk;
SysTick_LOAD 重装载数值寄存器
23:0.RELOAD
倒计时到0被重装的值
计算
t=reload × (1/clk)
Clk=72M时,t=(72000)*(1/72M)=1Ms
记1k次1s
Clk=72M时,t(72)*(1/72M)=1μs
程序
配置优先级
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
初始化
void SysTick_Init(void) { if (SysTick_Config(SystemCoreClock / 100000)) { while (1); } }
定时函数
void Delay_us(__IO u32 nTime) { TimingDelay = nTime; SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; while(TimingDelay != 0); }
中断服务
void SysTick_Handler(void) { TimingDelay_Decrement(); }
void TimingDelay_Decrement(void) { if (TimingDelay != 0x00) { TimingDelay--; } }
寄存器写法
static __INLINE uint32_t SysTick_Config(uint32_t ticks) { if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); SysTick->VAL = 0; SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; return (0); }
/* 大于2^24非法 Reload value impossible */ /* 初始化reload寄存器 set reload register */ /* 优先级15默认min set Priority for Cortex-M0 System Interrupts */ /* 初始化counter=0 Load the SysTick Counter Value */ /* 配置 systick 时钟72M */ /* 使能中断 */ /* 使能 systick Enable SysTick IRQ and SysTick Timer */ /* Function successful */
void SysTick_Delay_us(uint32_t us) { uint32_t i; SysTick_Config(72); for(i=0;i<us;i++) { while( !((SysTick->CTRL) & (1<<16)) ); } SysTick->CTRL &=~ SysTick_CTRL_CLKSOURCE_Msk; }
STK_CLK
72/9M
递减计数器
STK_VAL
重装载寄存器
STK_LOAD
通信1
串行
USART
波特率每秒码元个数
通信协议
物理层
协议层
数据
1起始位
逻辑0
8数据位0-7
1校验位
奇偶01无5种
1停止位
0.5、1、1.5、2个逻辑1
SPI
全
I²C
比特率bit/s
同步
效率高,时钟允许误差小
并行
SDIO
4
FSMC
16
USART
引脚
TX
RX
SW_RX(内部
接受引脚(单线、智能卡
/RTS
请求以发送
0接收器准备好接收
1寄存器已满
/CTS
清除以发送
0可以发送数据
1发完当前后停止发送
寄存器
数据寄存器
USART_DR [0,8]-DR
发送TDR
接收RDR
控制寄存器1
USART_CR1.13-UE
0
usart分频器、输出禁止
1
使能
USART_CR1.12-M
0
8位
1
9位
USART_CR1.10-PCE
0
禁止校验
USART_CR1.9-PS
0
偶校验
USART_CR1.8-PEIE
0
禁止产生中断
1
发送
USART_CR1.3-TE
1
发送使能
USART_SR.7-TXE
1
数据已经转移到移位寄存器
USART_SR.6-TC
1
发送完成
接收
USART_CR1.2-RE
1
接收使能
USART_SR.5-RXNE
1
收到数据可以读出
USART_CR1.12-M
标志寄存器
USART_SR.0-PE
0
没有奇偶校验错误
控制寄存器2
USART_CR2 [12,13]-STOP
1、0.5、2、1.5个停止位
u4、5不能.5
波特率
USARTDIV无符号定点数
fCK串口时钟
注意区分APB2、APB1
串口通信
初始化GPIO 复用到USART
推挽复用TX
浮空输入RX
初始化USART
USART_Config();
USART时钟
DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
USART_InitTypeDef
USART_BaudRate
波特率
24k, 96k, 192k, 1152k
USART_WordLength
字长
USART_StopBits
停止位
0.5, 1, 1.5, 2
USART_Parity
奇偶校验控制选择
USART_Mode
发送、接收
USART_HardwareFlowControl
硬件流控制模式有效,RTS、CTS
USART_ClockInitTypeDef(同步)
USART_Clock
同步模式SCLK输出使能控制
USART_CPOL
时钟极性
USART_CPHA
时钟相位
USART_LastBit
USART_Init(DEBUG_USARTx, &USART_InitStructure);
完成初始化
USART_Cmd(DEBUG_USARTx, ENABLE);
使能串口
初始化中断
NVIC_Configuration();
NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
嵌套中断控制器组 USART中断源 抢断优先级 子优先级 使能 初始化
发送
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch) { USART_SendData(pUSARTx,ch); while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); }
DR
数组
for(i=0; i<num; i++){Usart_SendByte(pUSARTx,array[i]); }
字符
do{Usart_SendByte( pUSARTx, *(str + k) ); k++;} while(*(str + k)!='\0');
接收
中断
void DEBUG_USART_IRQHandler(void) { uint8_t ucTemp; if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET) { ucTemp = USART_ReceiveData(DEBUG_USARTx); USART_SendData(DEBUG_USARTx,ucTemp); } }
接受并返回
查寻标志位
use microlib
stdio.h
重定向输入scanf、getchar
int fgetc(FILE *f) { while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE)==RESET); return (int)USART_ReceiveData(DEBUG_USARTx); }
重定向输出printf
int fputc(int ch, FILE *f) { USART_SendData(DEBUG_USARTx, (uint8_t) ch); while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE)==RESET); return (ch); }
DMA
DMA
直接存储器存取
1-7通道 2-5通道
仲裁器
DMA_CCRx
4优先级
通道编号
数据配置
DMA_CCR
DIR
0
外设->存储器
1
存储器->外设
MEM2MEM
1
存储器->存储器
量
PSIZE
8/16/32位
外设数据宽度
MSIZE
8/16/32位
存储器数据宽度
地址
外设地址指针
PINC
存储器地址指针
MINC
CIRC
一次传输
循环传输
DMA_ISR
传输状态标志
程序
M2M
FLASH定义好要传输数据,SRAM定义接收数据的变量
初始化DMA,DMA初始化结构体
DMA_InitTypeDef DMA_InitStructure;
使能DMA时钟
RCC_AHBPeriphClockCmd(DMA_CLOCK, ENABLE);
配置数据参数
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)aSRC_Const_Buffer;
外设(存储器)地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)aDST_Buffer;
存储器地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
方向
DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE;
传输方向
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
地址递增
DMA_InitStructure.DMA_PeripheralDataSize =DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
数据单位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;
模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
(使能M2M)
DMA_Init(DMA_CHANNEL, &DMA_InitStructure);
清除标志位
DMA_ClearFlag(DMA_FLAG_TC);
使能DMA
DMA_Cmd(DMA_CHANNEL,ENABLE);
放数据
const uint32_t aSRC_Const_Buffer[BUFFER_SIZE]= { 0x01020304,0x050……
const->flash
uint32_t aDST_Buffer[BUFFER_SIZE];
SRAM中容器
比较函数
uint8_t Buffercmp(const uint32_t* pBuffer, uint32_t* pBuffer1, uint16_t BufferLength) { while(BufferLength--) { if(*pBuffer != *pBuffer1){return 0;} pBuffer++;pBuffer1++; }return 1; }
数据长度递减 数据源不等退出 地址递增 对应数据相对
main
传输
DMA_Config();
等待
while(DMA_GetFlagStatus(DMA_FLAG_TC)==RESET){}
比较
TransferStatus=Buffercmp(aSRC_Const_Buffer, aDST_Buffer, BUFFER_SIZE);
判断
M2P
初始化串口
通信功能
配置DMA初始化结构体
工作参数
禁M2M
使能
开启串口发送DMA请求
USART_DMACmd(DEBUG_USARTx, USART_DMAReq_Tx, ENABLE);
- I2C - eeprom
I²C
物理层
速率
标准100k,快速400k,高速3.4m
协议层
主机产生
数据高电平有效低电平切换
/应答
架构
时钟控制
I2C_CCR
F/S
标准/快速
DUTY
占空比2 / 16:9
CCR
产生SCL时钟
数据控制
数据寄存器DR
自身地址寄存器OAR
1、2
PEC寄存器
运算校验
SDA
整体控制
控制寄存器
CR1/2
状态寄存器
SR1/2
通讯
发送
EV5
I2C_SR1.SB=1
起始信号已发送
EV6
I2C_SR1.ADDR=1
地址已发送
EV8
I2C_SR1.TXE=1
DR空
EV8_2
I2C_SR1.TXE/BTF=1
通讯结束
接收
EV5
I2C_SR1.SB=1
EV6
I2C_SR1.ADDR=1
EV7(_1)
I2C_SR1.RXNE=1
接受寄存器非空
模拟
起始
void i2c_Start(void)
EEPROM_I2C_SDA_1(); EEPROM_I2C_SCL_1(); i2c_Delay(); EEPROM_I2C_SDA_0(); i2c_Delay(); EEPROM_I2C_SCL_0(); i2c_Delay();
结束
void i2c_Stop(void)
EEPROM_I2C_SDA_0(); EEPROM_I2C_SCL_1(); i2c_Delay(); EEPROM_I2C_SDA_1();
设备地址
uint8_t i2c_CheckDevice(uint8_t _Address)
uint8_t ucAck; i2c_CfgGpio(); i2c_Start(); i2c_SendByte(_Address | EEPROM_I2C_WR); ucAck = i2c_WaitAck(); i2c_Stop(); return ucAck;
发
void i2c_SendByte(uint8_t _ucByte)
uint8_t i; for (i = 0; i < 8; i++) { if (_ucByte & 0x80) {EEPROM_I2C_SDA_1();} else {EEPROM_I2C_SDA_0();} i2c_Delay(); EEPROM_I2C_SCL_1(); i2c_Delay(); EEPROM_I2C_SCL_0(); if (i == 7) {EEPROM_I2C_SDA_1(); } _ucByte <<= 1; i2c_Delay(); }
收
uint8_t i2c_ReadByte(void)
uint8_t i;uint8_t value = 0; for (i = 0; i < 8; i++) { value <<= 1; EEPROM_I2C_SCL_1(); i2c_Delay(); if (EEPROM_I2C_SDA_READ()){value++;} EEPROM_I2C_SCL_0(); i2c_Delay(); } return value;
应答
void i2c_Ack(void)
EEPROM_I2C_SDA_0(); i2c_Delay(); EEPROM_I2C_SCL_1(); i2c_Delay(); EEPROM_I2C_SCL_0(); i2c_Delay(); EEPROM_I2C_SDA_1();
不应答
void i2c_NAck(void)
EEPROM_I2C_SDA_1(); i2c_Delay(); EEPROM_I2C_SCL_1(); i2c_Delay(); EEPROM_I2C_SCL_0(); i2c_Delay();
待应答
uint8_t i2c_WaitAck(void)
uint8_t re; EEPROM_I2C_SDA_1(); i2c_Delay(); EEPROM_I2C_SCL_1(); i2c_Delay(); if (EEPROM_I2C_SDA_READ()){re = 1;} else{re = 0;} EEPROM_I2C_SCL_0(); i2c_Delay(); return re;
0正确应答
读
起始
EV5
发eeprom读地址
EV6
eeprom内部地址
EV8
起始2
EV5
设备地址
EV6
循环读数据
while(NumByteToRead) { if(NumByteToRead == 1) { I2C_AcknowledgeConfig(EEPROM_I2Cx, DISABLE); I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE); } I2CTimeout = I2CT_LONG_TIMEOUT; while(I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)==0) { if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(3); } { *pBuffer = I2C_ReceiveData(EEPROM_I2Cx); pBuffer++; NumByteToRead--; } }
判断是否最后一个数据 发nACK 发停止 读一个字节 下一个地址 接收自-
写
写1字节
uint32_t I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr) { I2C_GenerateSTART(EEPROM_I2Cx, ENABLE); I2CTimeout = I2CT_FLAG_TIMEOUT; while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) {if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(0);} I2CTimeout = I2CT_FLAG_TIMEOUT; I2C_Send7bitAddress(EEPROM_I2Cx,EEPROM_ADDRESS,I2C_Direction_Transmitter); while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(1);} I2C_SendData(EEPROM_I2Cx, WriteAddr); I2CTimeout = I2CT_FLAG_TIMEOUT; while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(2);} I2C_SendData(EEPROM_I2Cx, *pBuffer); I2CTimeout = I2CT_FLAG_TIMEOUT; while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(3);} I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE); return 1; }
起始信号 超时等待时间 测EV5,清楚标志 发设备地址 测EV6,清楚标志 发送rom内部地址 检测EV8,清楚标志 发1字节 检测EV8,清楚标志 停止信号
写n字节
等待eeprom准备
I2C_EE_WaitEepromStandbyState
vu16 SR1_Tmp = 0; I2CTimeout = I2CT_LONG_TIMEOUT; do{ I2CTimeout--; I2C_GenerateSTART(EEPROM_I2Cx, ENABLE); SR1_Tmp = I2C_ReadRegister(EEPROM_I2Cx, I2C_Register_SR1); I2C_Send7bitAddress(EEPROM_I2Cx,EEPROM_ADDRESS,I2C_Direction_Transmitter); }while(!(I2C_ReadRegister(EEPROM_I2Cx, I2C_Register_SR1) & 0x0002) && (I2CTimeout > 0)); I2C_ClearFlag(EEPROM_I2Cx, I2C_FLAG_AF); I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE);
起始信号 读I2C1_SR1 eeprom写地址 addr1-发送成功 清除AF位 停止信号
页写入
for写多个,发完停止
while(NumByteToWrite--) { I2C_SendData(EEPROM_I2Cx, *pBuffer); pBuffer++; I2CTimeout = I2CT_FLAG_TIMEOUT; while (!I2C_CheckEvent(EEPROM_I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(8);} }
发缓冲区数据 缓冲区指向下一个数据 检测EV8,清除
快速写入多字节
Addr = WriteAddr % I2C_PageSize; count = I2C_PageSize - Addr; NumOfPage = NumByteToWrite / I2C_PageSize; NumOfSingle = NumByteToWrite % I2C_PageSize;
看是否整数倍 差count个可以对其到页 要写多少整数页 不满一页的字节数
初始化
串口初始化
GPIO开漏复用输出
I2C_Mode_Configu
I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;
时钟频率 <400k
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C模式
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
占空比
I2C_InitStructure.I2C_OwnAddress1 =I2Cx_OWN_ADDRESS7;
默认地址OAR1
OAR2 - I2C_OwnAddress2Config();
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ;
使能响应
I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
地址长7
I2C_Init(EEPROM_I2Cx, &I2C_InitStructure);
I2C_Cmd(EEPROM_I2Cx, ENABLE);
使能
通信
SPI
物理层
协议层
注意高低位先行
时钟极性CPOL
1
空闲状态高电平
时钟相位CPHA
1
偶数边采样
架构
时钟
fpclk1
APB1
fpclk2
APB2
数据控制
SPI_CR1-DFF
8/16位
SPI_CR1-LSBFIRST
MSB/LSB先行
控制逻辑
工作模式
CR1/CR2
SPI模式
波特率
LSB先行
主从模式
单双向模式
状态
SR
通讯
发完1帧
TXE = 1
接收1帧
RXNE =1
FLASH
写入前全部擦除
擦除时数据位全部置1
写入只能把1变0
擦除必须按最小单位
FLASH
状态寄存器
程序
初始化
使能SPI时钟
FLASH_SPI_APBxClock_FUN ( FLASH_SPI_CLK, ENABLE );
GPIO初始化
CS推挽
SCK、MISO、MOSI复用推挽
时钟
FLASH_SPI_CS_APBxClock_FUN ( FLASH_SPI_CS_CLK|FLASH_SPI_SCK_CLK|FLASH_SPI_MISO_PIN|FLASH_SPI_MOSI_PIN, ENABLE );
CS高电平
SPI_InitTypeDef
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
双向收发模式
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
数据帧长度8
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
极性
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
相位
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
NSS软件控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
4分频
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
高位先行
SPI_InitStructure.SPI_CRCPolynomial = 7;
CRC校验表达式(无效)
SPI_Init(FLASH_SPIx , &SPI_InitStructure);
使能
SPI_Cmd(FLASH_SPIx , ENABLE);
接发1字节
u8 SPI_FLASH_SendByte(u8 byte) { SPITimeout = SPIT_FLAG_TIMEOUT; while (SPI_I2S_GetFlagStatus(FLASH_SPIx , SPI_I2S_FLAG_TXE) == RESET) {if((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(0);} SPI_I2S_SendData(FLASH_SPIx , byte); SPITimeout = SPIT_FLAG_TIMEOUT; while (SPI_I2S_GetFlagStatus(FLASH_SPIx , SPI_I2S_FLAG_RXNE) == RESET) {if((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(1);} return SPI_I2S_ReceiveData(FLASH_SPIx ); }
发送缓冲区空,TXE事件 数据写入发送缓冲区 接收缓冲区非空,RXNE事件 获取接收缓冲区数据
u8 SPI_FLASH_ReadByte(void) {return (SPI_FLASH_SendByte(Dummy_Byte));}
指令功能
读ID
CS_
SPI_FLASH_CS_LOW();
指令
SPI_FLASH_SendByte(W25X_JedecDeviceID);
Temp0 = SPI_FLASH_SendByte(Dummy_Byte); Temp1 = SPI_FLASH_SendByte(Dummy_Byte); Temp2 = SPI_FLASH_SendByte(Dummy_Byte);
CS1
SPI_FLASH_CS_HIGH();
Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
写使能
CS_
SPI_FLASH_SendByte(W25X_WriteEnable);
CS1
读状态
CS_
SPI_FLASH_SendByte(W25X_ReadStatusReg);
do{FLASH_Status = SPI_FLASH_SendByte(Dummy_Byte);} while ((FLASH_Status & WIP_Flag) == SET);
持续检验BUSY位
CS1
扇区擦除
写使能
SPI_FLASH_WriteEnable(); SPI_FLASH_WaitForWriteEnd();
CS_
SPI_FLASH_SendByte(W25X_SectorErase);
擦除指令
擦除地址
SPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16); SPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8); SPI_FLASH_SendByte(SectorAddr & 0xFF);
CS1
等
SPI_FLASH_WaitForWriteEnd();
页写入
1次256字节
片选
写使能
发地址
循环写
等
不定写入
Addr = WriteAddr % I2C_PageSize; count = I2C_PageSize - Addr; NumOfPage = NumByteToWrite / I2C_PageSize; NumOfSingle = NumByteToWrite % I2C_PageSize;
看是否整数倍 差count个可以对其到页 要写多少整数页 不满一页的字节数
FatFs 文件系统
结构
数值类型定义
底层访问SPI Flash芯片
添加底层驱动函数
文件管理实现方法
核心,实现读写
简体中文GBK、Unicode转换
功能配置宏定义
裁剪FatFs功能
FSMC SRAM
SRAM
内存扩展
SDRAM
定时刷新,成本低
读
tRC
读总时间
>55ns
tAA
地址信号->有效数据
<55
tDOE
读使能->有效数据
<25
写
tWC
写总时间
>55
tSA
地址->写使能
>0
tPWE
写使能->数据采样
>40
管脚
/UB
高位允许,数据掩码
/LB
低位允许,数据掩码
19地址A
16输入输出IO
写入使能/WE
输出使能/OE
2片选CS
FSMC
FSMC_
BCR1/2/3/4控制寄存器
控制存储器类型、数据线宽、信号有效及性能参数
BTR1/2/3/4片选时序寄存器
SRAM访问时延-数据、地址保持时间
BWTR1/2/3/4写时序寄存器
写时序时间参数
地址映射
读
写
程序
配置
时序结构体
FSMC_NORSRAMTimingInitTypeDef;
FSMC_AddressSetupTime = 0;
地址建立时间
FSMC_AddressHoldTime = 0;
地址保持时间
FSMC_DataSetupTime = 2;
数据建立时间
0-0xf个HCLK周期(+1
FSMC_AccessMode;
访问模式
SRAM - A
初始化结构体
FSMC_NORSRAMInitTypeDef;
FSMC_Bank;
要控制的区域
FSMC_MemoryType;
存储器类型SRAM
FSMC_MemoryDataWidth;
存储器数据宽度
16位
FSMC_WriteOperation;
写使能
FSMC_ExtendedMode;
拓展模式
SRAMInitStruct.FSMC_WriteTimingStruct = &readTimInitStruct; SRAMInitStruct.FSMC_ReadWriteTimingStruct = &readTimInitStruct;
配置写入
FSMC_NORSRAMInit(&SRAMInitStruct);
使能
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3,ENABLE);
存8位
p = (uint8_t *)SRAM_BASE_ADDR; *p=0xAB;
存32位
p32 = (uint32_t *)SRAM_BASE_ADDR+8; *p32=0xABcdeffe;
存字符串
ps = (char *)SRAM_BASE_ADDR+40; while(*ps !='\0') { *ps=a[i]; ps++; i++; }i=0; ps = (char *)SRAM_BASE_ADDR+40; while(*ps !='\0') { b[i]=*ps; ps++; i++; } printf("¶Á³öÁË%s\n",b);
写
ADDSET+1 + DATAST+1 > 55ns
0+1+2+1
DATAST+1 > 40ns
2+1
ADDSET+1 > 0ns
0+1
读
ADDSET+1 + DATAST+1 +2 > 55ns
0+1+1+1+2
DATAST+1 > 25ns
1+1
ADDSET+1 > 0ns
0+1
FSMC 液晶
液晶屏
RGB接口
R[7:0] G[7:0] B[7:0]
565/888
CLK
像素同步时钟信号
每个时钟传1像素点数据
同步通讯
HSYNC
水平同步信号
一行像素传输结束
VSYNC
垂直同步信号
一帧像素传输结束
DE
数据使能
1有效
HBP
HSYNC到有效数据开始之间CLK个数
HFP
行有效数据结束到下个HSYNC开始的CLK
HSW
HSYNC宽度/CLK
VBP
一帧图像开始,VSYNC后无效行
VFP
一帧图像结束,VSYNC前无效行数
VSW
VSYNC宽度/行
RGB
888
3*320*240
230400
565
2*320*240
253600
8080 信号线
写命令
LCD_RST, LCD_BL
自选引脚
FSMC
NOR\PSRAM
模式B
D/CX
1数值
0命令
程序
通讯引脚、端口时钟
FSMC时钟
RCC_AHBPeriphClockCmd ( RCC_AHBPeriph_FSMC, ENABLE );
FSMC异步NOR FLASH模式
FSMC_NORSRAMTimingInitTypeDef;
FSMC_AddressSetupTime = 0;
地址建立时间
FSMC_AddressHoldTime = 0;
地址保持时间
FSMC_DataSetupTime = 2;
数据建立时间
0-0xf个HCLK周期(+1
FSMC_AccessMode;
访问模式
B
FSMC_NORSRAMInitTypeDef;
FSMC_Bank;
要控制的区域
FSMC_MemoryType;
存储器类型NOR/PSRAM
FSMC_MemoryDataWidth;
存储器数据宽度
16位
FSMC_WriteOperation;
写使能
FSMC_ExtendedMode;
拓展模式
SRAMInitStruct.FSMC_WriteTimingStruct = &readTimInitStruct; SRAMInitStruct.FSMC_ReadWriteTimingStruct = &readTimInitStruct;
发送命令、数据机制
数据
0X6C00 0000 |= (1<<23) = 0x6C80 0000
命令
0X6C00 0000 &= ~ (1<<23) = 0x6C00 0000
23+1
#define FSMC_Addr_ILI9341_DATA ( ( uint32_t ) 0x6D000000 )
#define FSMC_Addr_ILI9341_CMD ( ( uint32_t ) 0x6C000000 )
初始化
先初始化液晶再初始化串口
ILI9341_Init ( void )
ILI9341_GPIO_Config ();
ILI9341_FSMC_Config ();
ILI9341_BackLed_Control ( ENABLE );
点亮背光灯
ILI9341_Rst ();
复位
ILI9341_REG_Config ( void )
控制命令初始化液晶屏
ILI9341_GramScan ( uint8_t ucOption )
扫描方向
绘制像素点函数
ILI9341_SetCursor ( uint16_t usX, uint16_t usY )
画图
字体大小
LCD_SetFont(&Font8x16);
前背景色
LCD_SetColors(RED,BLACK);
前景色改
LCD_SetTextColor(GREEN);
清屏,全黑
ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH);
字符串
ILI9341_DispStringLine_EN(LINE(0),"BH 3.2 inch LCD para:");
清除单行
LCD_ClearLine(LINE(4));
变量转字符
sprintf(dispBuff,"Count : %d ",testCNT);
ILI9341_DispStringLine_EN(LINE(4),dispBuff);
线
ILI9341_DrawLine(50,170,210,230);
矩形
ILI9341_DrawRectangle(50,200,100,30,1);
圆
ILI9341_DrawCircle(100,200,20,0);
16位RGB
#define RGB(R,G,B) (uint16_t)(((R&0x1f)<<11)|((G&0x3f)<<5)|(B&0x1f))
字模
字模
2字节/行像素点
16行/字模
配置
阴码1
逐行
16×16
字符寻址
Addr = (((CodeH-0xA0-1)*94) +(CodeL-0xA0-1))*16*16/8
画伪播放器
ILI9341_Init(); LED_GPIO_Config(); LED_B(ON); LCD_SetColors(WHITE,RGB(2,2,3)); ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH); LCD_SetFont(&Font16x24); ILI9341_DispStringLine_EN(LINE(1)," Our Kingdom"); LCD_SetFont(&Font8x16); ILI9341_DispStringLine_EN(LINE(3)," Andreas B.>"); ILI9341_DispStringLine_EN(LINE(0)," 17:13"); LCD_SetFont(&Font24x32); ILI9341_DispStringLine_EN(LINE(1),"<"); LCD_SetFont(&Font8x16); ILI9341_DispStringLine_EN(LINE(4)," living"); ILI9341_DispStringLine_EN(LINE(16),"0:01 3:48"); LCD_SetTextColor(GREY); ILI9341_DrawLine(40,265,190,265); ILI9341_DrawLine(206,245,226,245); ILI9341_DrawLine(206,240,226,240); ILI9341_DrawLine(206,250,226,250); LCD_SetTextColor(GREY); ILI9341_DrawCircle(120,150,60,1); LCD_SetTextColor(GBLUE); ILI9341_DrawCircle(120,150,58,1); LCD_SetTextColor(RED); ILI9341_DrawCircle(24,245,10,1); LCD_SetTextColor(WHITE); ILI9341_DrawCircle(72,245,10,1); ILI9341_DrawCircle(120,245,10,0); ILI9341_DrawCircle(168,245,5,1); ILI9341_DrawCircle(10,5,5,0); ILI9341_DispStringLine_EN(LINE(18)," |< >|"); ILI9341_DrawCircle(120,295,16,0); ILI9341_DrawLine(115,290,115,300); ILI9341_DrawLine(125,290,125,300); ILI9341_DrawCircle(73,296,12,0); ILI9341_DrawCircle(167,296,12,0); ILI9341_DrawRectangle(172,3,20,13,0); LCD_SetTextColor(GRED); ILI9341_DrawRectangle(174,5,6,9,1);
液晶屏初始化 背景色 清屏 字体设置 打印歌名 Our Kingdom 作者 画进度条 控制图标 封面 控制图标 播放设置键 电量
TIM
基本定时器
CK_INT
APB1预分频
36*2=72M
CK_CNT
TIM*CLK/(PSC+1)
CNT
16位计数器
↑65535
自动重装载寄存器
ARR
计数最大值-中断
时间
1次中断
1/(CK_CLK*ARR)
初始化
TIM_Prescaler;
预分频器
1-65536
TIM_Period;
计时周期
高级定时器
TIM1/8
输入捕获、输出比较
1时钟源
内部时钟源CK_INT
72M
TIMx_SMCR.SMS=000
外时钟模式1:外输入Tlx(1,2,3,4
1时钟信号输入引脚
T1/2/3/4
TIM_CCMRx.CCxS
2滤波器
TIMx_CCMRx.ICxF
3边沿检测
4触发选择
滤波后定时器输入1/2
5模式选择
6使能计数器
外时钟模式2:外输入ETR
1时钟输入引脚
2外部触发极性
3外部触发预分频器
4滤波器
5模式选择
6使能计数器
内触发输入ITRx
2控制器
基本
16位重装载寄存器ARR
16位计数器CNT
16位可编程预分频器PCR
8位重复计数器RCR
4输入捕获
PWM只能通道1\2
计数+1
5输出比较
频率
ARR
占空比
CCR
PWM1
递增
CNT<CCR,CH有效
直流电机
10k-25k
程序
GPIO初始化
TIM1输出比较通道
PA8
TIM1输出比较互补通道
PB13
TIM1输出比较刹车通道
PB12
复用推挽
定时器模式
ADVANCE_TIM_APBxClock_FUN(ADVANCE_TIM_CLK,ENABLE);
开时钟
时基结构体
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period=ADVANCE_TIM_PERIOD;
自动重装载
TIM_TimeBaseStructure.TIM_Prescaler= ADVANCE_TIM_PSC;
CNT计数器时钟
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
分频,死区时间
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
计数模式向上
TIM_TimeBaseInit(ADVANCE_TIM, &TIM_TimeBaseStructure);
输出比较结构体
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
PWM1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
输出使能
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
互补输出使能
TIM_OCInitStructure.TIM_Pulse = ADVANCE_TIM_PULSE;
占空比大小
极性
TIM_OC1Init(ADVANCE_TIM, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(ADVANCE_TIM, TIM_OCPreload_Enable);
刹车、死区结构体
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
子主题
TIM_Cmd(ADVANCE_TIM, ENABLE);
计数器使能
TIM_CtrlPWMOutputs(ADVANCE_TIM, ENABLE);
zhu主输出使能
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
输出使能
6断路
定时
PWM
PA8
PB13
程序
GPIO初始化
时基结构体初始化
输入捕获初始化
捕获
PWM
ADDA
3ADC
12位精度
16, 16, 14外部通道
电压输入范围
由决定
VREF+
VDDA
3V3
VREF-
VSSA
GND
转换顺序
规则序列寄存器SQR3-1
注入序列寄存器JSQR
触发源
ADC_CR2.ADON
1
开始转换
触发模式
定时器
IO
转换时间
Tconv=1.5周期+12.5周期=1us
数据寄存器
DR
32位
单模式123不用高16
JDRx
4个
中断
规则结束
注入结束
DMA请求
看门狗
模拟电压出阈值
电压转换
结构体
ADC_Mode
独立模式/双模式
ADC_ScanConvMode
多通道EN
ADC_ContinuousConvMode
自动连续转换EN
ADC_ExternalTrigConv
外部出发选择
ADC_DataAlign
左右对齐
ADC_NbrOfChannel
转换通道数
编程
初始化GPIO
工作参数,初始化
ADC工作时钟
转换通道顺序,采样时间
使能中断,中断内读取数据
使能ADC
使能软件触发ADC转换
DAC
2通道
参考电压
VREF+
VDDA
3V3
VSSA
GND
通道
DORx
数字编码输入
OUTx
输出
PA4-1
PA5-2
触发源
OV7725
CCD
电荷耦合器件
电压大12V
2~5W
噪声低,成像好
CMOS
互补金属氧化物半导体
电压小3~5V
20~50mW功率
噪声高,灵敏低
主题
采集过程
SIO_C&SIO_D通过SCCB协议写初始化配置
传感器VGA时序输出图像
写入FIFO输出一帧后禁止写入
读取整帧
主题
液晶实时显示
初始化SCCB通讯目标引脚、端口时钟
初始化OV7725 VGA、FIFO引脚、时钟
SCCB写OV初始化
筛选器工作方式
测试程序,收发报文、检验
中心主题
位操作
置位
|=
*(unsigned int *) 0x40010c00 |=((1)<<(4*0)); //配置IO为输
清0
&=~
*(unsigned int *) 0x40010c0c &=~(1<<0); //控制ODR寄存器
编译
报错
void SystemInit() { //函数体空,骗过编译器不报错 }
注释
#if 0 #endif
宏定义
防止头文件重复包含
#ifndef _STM32F10X_GPIO_H #define _STM32F10X_GPIO_H …… #endif //_STM32F10X_GPIO_H
条件切换编译