时间:12-10-2023
简介
⭕写在开头:自学于江协科大(B站),详尽的编程知识和stm32的架构。
⭕STM32采用ARM内核,功能强大,价格便宜,适合嵌入式学习。
学习笔记
⭕第一步:认识STM32F10X
采用Cortex-M3 CPU ,32位MCU ,32的意思是32位数据总线,外部引脚共48PIN。
存储器:内存SRAM20K,闪存Flash64K(基于型号,有128K内存)。
电源:3.3V 带低功耗功能开关。
⭕第二步:点灯
查看原理图,找到连接LED的IO口,也就是对应的STM32的PC13引脚。
开始写程序
#include "stm32f10x.h" // Device header
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);//GPIO时钟使能
GPIO_InitTypeDef GPIO_InitStructure; //初始化GPIO口,设置结构体变量
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //配置结构体参数,推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 ; //LED
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; //输出最高频率50M
GPIO_Init(GPIOC , &GPIO_InitStructure); //指向结构体的指针初始化函数
GPIO_ResetBits(GPIOC,GPIO_Pin_13); //低电平点亮
//GPIO_SetBits(GPIOC,GPIO_Pin_13); //高电平熄灭
}
⭕第三步:点亮OLED屏幕
OLED屏幕采用IIC通信协议,屏幕上的SCL、SDA接口接在PB8、PB9MCU接口。
开始写程序
#define OLED_W_SCL(x) GPIO_WriteBit(GPIOB, GPIO_Pin_8, (BitAction)(x))
#define OLED_W_SDA(x) GPIO_WriteBit(GPIOB, GPIO_Pin_9, (BitAction)(x))
//这两句定义了IIC通信引脚是PB8和PB9
void OLED_I2C_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}//以上,是端口输出引脚配置,和点灯的步骤一样
OLED_W_SCL(1);
OLED_W_SDA(1);
//IIC通信初始化信号,SCL、SDA拉高
OLED_WriteCommand(0xAE); //关闭显示
OLED_WriteCommand(0xD5); //设置显示时钟分频比/振荡器频率
OLED_WriteCommand(0x80);
OLED_WriteCommand(0xA8); //设置多路复用率
OLED_WriteCommand(0x3F);
OLED_WriteCommand(0xD3); //设置显示偏移
OLED_WriteCommand(0x00);
OLED_WriteCommand(0x40); //设置显示开始行
OLED_WriteCommand(0xA1); //设置左右方向,0xA1正常 0xA0左右反置
OLED_WriteCommand(0xC8); //设置上下方向,0xC8正常 0xC0上下反置
OLED_WriteCommand(0xDA); //设置COM引脚硬件配置
OLED_WriteCommand(0x12);
OLED_WriteCommand(0x81); //设置对比度控制
OLED_WriteCommand(0xCF);
OLED_WriteCommand(0xD9); //设置预充电周期
OLED_WriteCommand(0xF1);
OLED_WriteCommand(0xDB); //设置VCOMH取消选择级别
OLED_WriteCommand(0x30);
OLED_WriteCommand(0xA4); //设置整个显示打开/关闭
OLED_WriteCommand(0xA6); //设置正常/倒转显示
OLED_WriteCommand(0x8D); //设置充电泵
OLED_WriteCommand(0x14);
OLED_WriteCommand(0xAF); //开启显示
//一长串是OLED配置参数,根据SSD1306和厂家出厂资料 设置,必须要有
void OLED_WriteCommand(uint8_t Command)
{
OLED_W_SDA(1); //先拉高SDA和SCL
OLED_W_SCL(1); //MCU确认通信开始,SCL拉低允许SDA传输数据
OLED_W_SDA(0);
OLED_W_SCL(0); //IIC开始传字节
OLED_I2C_SendByte(0x78); //OLED从机地址
OLED_I2C_SendByte(0x00); //写命令
OLED_I2C_SendByte(Command);
OLED_W_SDA(0); //IIC关闭
OLED_W_SCL(1);
OLED_W_SDA(1); //IIC开启
}
⭕第四步:玩转ADC+DMA转运
ADC1和DMA配置:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启GPIOA口时钟
RCC_APB2PeriphClockCmd (RCC_APB2Periph_ADC1 ,ENABLE );//配置ADC1,位于PA0-PB0的16位ADC采集器以及最近看到了新的写法: RCC_APB2PeriphClockCmd (RCC_APB2Periph_ADC1| RCC_APB2Periph_GPIOA,ENABLE );
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //DMA是AHB总线控制
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//设置频率,ADC采集器最高频率14M,MCU72M,6分频
GPIO_InitTypeDef GPIO_InitStructure; //按照惯例,配置GPIO口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_RegularChannelConfig (ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5); //通道0放在序列1的位置,中等采样时间
ADC_RegularChannelConfig (ADC1,ADC_Channel_1,2,ADC_SampleTime_55Cycles5); //通道1放在序列2的位置,中等采样时间
ADC_InitTypeDef ADC_InitStructure; //配置ADC1
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC1独立模式(与ADC2各自工作)
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //右排列高精度模式,左排列为低精度
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不使用外部触发
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE ;//连续检测模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE ; //连续扫描模式
ADC_InitStructure.ADC_NbrOfChannel = 2; //通道数量,最高16
ADC_Init(ADC1,&ADC_InitStructure); //结构体指针,指向结构体地址
DMA_InitTypeDef DMA_InitStructure;//外设站点的起始地址
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;//外设站点DR寄存器
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //数据宽度:32位比特(取决于转运的数组是几位的)
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //地址自增(意思是目标地址有一个以上)
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)AD_Value;//存储器站点地址
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//地址自增
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//传输方向:外设→存储器
DMA_InitStructure.DMA_BufferSize = 2;//控制传输计数器,即传输次数
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//normal模式是自减到零停止
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//硬件|软件触发
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//优先级
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel1, ENABLE);//DMA使能
ADC_DMACmd(ADC1,ENABLE);//使能开启ADC到DMA的传输
ADC_Cmd (ADC1,ENABLE);//ADC电源使能控制
ADC_ResetCalibration (ADC1); //ADC重置
while (ADC_GetResetCalibrationStatus (ADC1)==SET );//等待重置标志位
ADC_StartCalibration (ADC1); //ADC校准
while (ADC_GetCalibrationStatus (ADC1)==SET);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//ADC1!启动!
⭕第五步:试玩NRF2401