索引 

        【1】led灯实验

        【2】定时器计时

        【3】矩阵按键

        【4】OLED显示实验

                       [4.1]oled i2c驱动程序

                        [4.2]oled 写数据命令

                        [4.3]SSH1106 初始化程序

                        [4.4]oled 汉字显示程序

                        [4.5]oled BMP图像显示程序

【5】

 [4.1]USART串口实验

【1】LED灯

功能:点亮PC13LED灯

​#include "stm32f10x.h"                  // Device header
void Led()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//APB2时钟GPIO_InitTypeDef led;led.GPIO_Mode=GPIO_Mode_Out_PP;led.GPIO_Pin=GPIO_Pin_13;             //PC13led.GPIO_Speed=GPIO_Speed_10MHz;GPIO_Init(GPIOC,&led);
}​int main()
{Led();while(1){GPIO_ResetBits(GPIOC,GPIO_Pin_13);//led低电平有效}
}

【2】定时器

功能:实现每秒计数加1


​#include "stm32f10x.h"                  // Device headervoid Timer_Init(unsigned int arr,unsigned int psc)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//开启APB1定时器3的时钟TIM_TimeBaseInitTypeDef Timer;Timer.TIM_ClockDivision=TIM_CKD_DIV1;Timer.TIM_CounterMode=TIM_CounterMode_Up;Timer.TIM_Period=arr;Timer.TIM_Prescaler=psc;TIM_TimeBaseInit(TIM3,&Timer);TIM_Cmd(TIM3,ENABLE);//打开定时器TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能定时器更新中断
}void TIM_IRQNHandle(void)//定时器服务函数
{if(TIM_GetITStatus(TIM3,TIM_IT_Update)){TIM_ClearFlag(TIM3,TIM_IT_Update);//清除定时器标志位sec++;  //此处为定时器服务函数,此处在oled显示秒++}}int main()
{Timer_Init(7199,9999);  //((arr+1)*(psc+1)/72M)OLED_Init(); OLED_Clear();//清屏Timer_Init(7199,9999);//((arr+1)*(psc+1)/CLK)while(1){TIM_IRQNHandle();OLED_ShowNum(1,7,sec,2);//OLED显示函数}
}

【3】矩阵按键

功能:实现S1-S16键值录入

C1-C4为行,R1-R4为列

接线:C1-C4接单片机引脚PA4-PA7;R1-R4依次接单片机引脚PB0,PB1,PB10,PB11

#include "stm32f10x.h"                  // Device header
#include <delay.h>
#define C1_H GPIO_SetBits(GPIOA,GPIO_Pin_4)
#define C2_H GPIO_SetBits(GPIOA,GPIO_Pin_5)
#define C3_H GPIO_SetBits(GPIOA,GPIO_Pin_6)
#define C4_H GPIO_SetBits(GPIOA,GPIO_Pin_7)#define C1_L GPIO_ResetBits(GPIOA,GPIO_Pin_4)
#define C2_L GPIO_ResetBits(GPIOA,GPIO_Pin_5)
#define C3_L GPIO_ResetBits(GPIOA,GPIO_Pin_6)
#define C4_L GPIO_ResetBits(GPIOA,GPIO_Pin_7)#define R1_H GPIO_SetBits(GPIOB,GPIO_Pin_0)
#define R2_H GPIO_SetBits(GPIOB,GPIO_Pin_1)
#define R3_H GPIO_SetBits(GPIOB,GPIO_Pin_10)
#define R4_H GPIO_SetBits(GPIOB,GPIO_Pin_11)#define R1_L GPIO_ResetBits(GPIOB,GPIO_Pin_0)
#define R2_L GPIO_ResetBits(GPIOB,GPIO_Pin_1)
#define R3_L GPIO_ResetBits(GPIOB,GPIO_Pin_10)
#define R4_L GPIO_ResetBits(GPIOB,GPIO_Pin_11) int KeyNum = 0;//键值void Led()
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//APB2时钟GPIO_InitTypeDef led;led.GPIO_Mode=GPIO_Mode_Out_PP;led.GPIO_Pin=GPIO_Pin_13;             //PC13led.GPIO_Speed=GPIO_Speed_10MHz;GPIO_Init(GPIOC,&led);
}void GPIO_init()
{   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitTypeDef GPIOA_InitStruct;//设置列R1-R4GPIOA_InitStruct.GPIO_Mode=GPIO_Mode_IPU;//行设置为上拉输入GPIOA_InitStruct.GPIO_Pin=GPIO_Pin_7|GPIO_Pin_6|GPIO_Pin_5|GPIO_Pin_4;GPIOA_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIOA_InitStruct);GPIO_InitTypeDef GPIOB_InitStruct;//设置行C1-C4GPIOB_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//列设置为推挽输出GPIOB_InitStruct.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_10|GPIO_Pin_1|GPIO_Pin_0;GPIOB_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIOB_InitStruct);}
void Key_Mulit()
{C1_H;C2_H;C3_H;C4_H;R1_L;R2_H;R3_H;R4_H;if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4)==0)//扫描第一行,判断第一列是否为低{Delay_ms(2);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4)==0){while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4)==0);//判断松手KeyNum=1;GPIO_ResetBits(GPIOC,GPIO_Pin_13); }}if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)==0)//扫描第一行,判断第二列是否为低{Delay_ms(2);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)==0){while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)==0);//判断松手KeyNum=2;GPIO_SetBits(GPIOC,GPIO_Pin_13); }}if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==0)//扫描第一行,判断第三列是否为低{Delay_ms(2);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==0){while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==0);//判断松手KeyNum=3;GPIO_ResetBits(GPIOC,GPIO_Pin_13); }}if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==0)//扫描第一行,判断第四列是否为低{Delay_ms(2);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==0){while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==0);//判断松手KeyNum=4;GPIO_SetBits(GPIOC,GPIO_Pin_13); }}R1_H;R2_L;R3_H;R4_H;if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4)==0)//扫描第二行,判断第一列是否为低{Delay_ms(2);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4)==0){while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4)==0);//判断松手KeyNum=5;GPIO_ResetBits(GPIOC,GPIO_Pin_13); }}if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)==0)//扫描第二行,判断第二列是否为低{Delay_ms(2);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)==0){while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)==0);//判断松手KeyNum=6;GPIO_SetBits(GPIOC,GPIO_Pin_13); }}if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==0)//扫描第二行,判断第三列是否为低{Delay_ms(2);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==0){while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==0);//判断松手KeyNum=7;GPIO_ResetBits(GPIOC,GPIO_Pin_13); }}if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==0)//扫描第二行,判断第四列是否为低{Delay_ms(2);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==0){while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==0);//判断松手KeyNum=8;GPIO_SetBits(GPIOC,GPIO_Pin_13); }}R1_H;R2_H;R3_L;R4_H;if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4)==0)//扫描第三行,判断第一列是否为低{Delay_ms(2);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4)==0){while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4)==0);//判断松手KeyNum=9;GPIO_ResetBits(GPIOC,GPIO_Pin_13); }}if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)==0)//扫描第三行,判断第二列是否为低{Delay_ms(2);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)==0){while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)==0);//判断松手KeyNum=10;GPIO_SetBits(GPIOC,GPIO_Pin_13); }}if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==0)//扫描第三行,判断第三列是否为低{Delay_ms(2);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==0){while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==0);//判断松手KeyNum=11;GPIO_ResetBits(GPIOC,GPIO_Pin_13); }}if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==0)//扫描第三行,判断第四列是否为低{Delay_ms(2);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==0){while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==0);//判断松手KeyNum=12;GPIO_SetBits(GPIOC,GPIO_Pin_13); }}R1_H;R2_H;R3_H;R4_L;if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4)==0)//扫描第四行,判断第一列是否为低{Delay_ms(2);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4)==0){while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4)==0);//判断松手KeyNum=13;GPIO_ResetBits(GPIOC,GPIO_Pin_13); }}if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)==0)//扫描第四行,判断第二列是否为低{Delay_ms(2);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)==0){while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)==0);//判断松手KeyNum=14;GPIO_SetBits(GPIOC,GPIO_Pin_13); }}if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==0)//扫描第四行,判断第三列是否为低{Delay_ms(2);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==0){while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==0);//判断松手KeyNum=15;GPIO_ResetBits(GPIOC,GPIO_Pin_13); }}if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==0)//扫描第四行,判断第四列是否为低{Delay_ms(2);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==0){while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==0);//判断松手KeyNum=16;GPIO_SetBits(GPIOC,GPIO_Pin_13); }}}
int main(void)
{Led();   //led灯初始化GPIO_init();//矩阵按键引脚GPIO_SetBits(GPIOC,GPIO_Pin_13);//关闭led灯 while (1){Key_Mulit();//用led判断矩阵按键功能是否实现}
}

【4.1】OLED I2C 驱动程序

OLED使用SSH1106驱动芯片,只需更改初始化程序即可移植

SDA 接 B9 ; SCL 接 B8

#include "stm32f10x.h"                  // Device header
#define  uint8_t  unsigned char/*引脚配置*/
#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))/*引脚初始化*/
void OLED_I2C_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;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);
}/*** @brief  I2C开始* @param  无* @retval 无*/
void OLED_I2C_Start()
{OLED_W_SDA(1);OLED_W_SCL(1);OLED_W_SDA(0);OLED_W_SCL(0);
}/*** @brief  I2C停止* @param  无* @retval 无*/
void OLED_I2C_Stop()
{OLED_W_SDA(0);OLED_W_SCL(1);OLED_W_SDA(1);
}/*** @brief  I2C发送一个字节* @param  Byte 要发送的一个字节* @retval 无*/
void OLED_I2C_SendByte(uint8_t Byte)
{uint8_t i;for (i = 0; i < 8; i++){OLED_W_SDA(Byte & (0x80 >> i));OLED_W_SCL(1);OLED_W_SCL(0);}OLED_W_SCL(1);   //额外的一个时钟,不处理应答信号OLED_W_SCL(0);
}

【4.2】OLED 写 数据|命令


/*** @brief  OLED写命令* @param  Command 要写入的命令* @retval 无*/
void OLED_WriteCommand(uint8_t Command)
{OLED_I2C_Start();OLED_I2C_SendByte(0x78);      //从机地址OLED_I2C_SendByte(0x00);      //写命令OLED_I2C_SendByte(Command); OLED_I2C_Stop();
}/*** @brief  OLED写数据* @param  Data 要写入的数据* @retval 无*/
void OLED_WriteData(uint8_t Data)
{OLED_I2C_Start();OLED_I2C_SendByte(0x78);      //从机地址OLED_I2C_SendByte(0x40);      //写数据OLED_I2C_SendByte(Data);OLED_I2C_Stop();
}/*** @brief  OLED设置光标位置* @param  Y 以左上角为原点,向下方向的坐标,范围:0~7* @param  X 以左上角为原点,向右方向的坐标,范围:0~127* @retval 无*/
void OLED_SetCursor(uint8_t Y, uint8_t X)
{OLED_WriteCommand(0xB0 + Y);                  //设置Y位置OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4));   //设置X位置低4位OLED_WriteCommand(0x01 | (X & 0x0F));         //设置X位置高4位
}/*** @brief  OLED清屏* @param  无* @retval 无*/
void OLED_Clear(void)
{  uint8_t i, j;for (j = 0; j < 8; j++){OLED_SetCursor(j, 0);for(i = 0; i < 132; i++)  //1.3寸OLED地址偏移2,0.9寸改为128即可{OLED_WriteData(0x00);}}
}

SSH1106初始化程序

void OLED_Init()
{uint32_t i, j;for (i = 0; i < 1000; i++)         //上电延时{for (j = 0; j < 1000; j++);}OLED_I2C_Init();           //端口初始化OLED_WriteCommand(0xAE);//set display display ON/OFF,AFH/AEHOLED_WriteCommand(0x02);OLED_WriteCommand(0x10);OLED_WriteCommand(0x40);//set display start line:COM0OLED_WriteCommand(0xB0);OLED_WriteCommand(0x81);//set contrast controlOLED_WriteCommand(0xCF);OLED_WriteCommand(0xA1);//entire display on: A4H:OFF/A5H:ONOLED_WriteCommand(0xC8); //该指令控制显示方向显示方向0xc8或者0xc0//Write_Command(0xC0);OLED_WriteCommand(0xAF);OLED_WriteCommand(0xA7);//set normal/inverse display: A6H:normal/A7H:inverseOLED_WriteCommand(0xA8);//set multiplex ratioOLED_WriteCommand(0x3F);//1/64dutyOLED_WriteCommand(0xD3);//set display offsetOLED_WriteCommand(0x00);//OLED_WriteCommand(0xD5);//set display clock divide ratio/oscillator frequencyOLED_WriteCommand(0x80);//105HzOLED_WriteCommand(0xD9);//Dis-charge /Pre-charge Period Mode SetOLED_WriteCommand(0xF1);//OLED_WriteCommand(0xDA);//Common Pads Hardware Configuration Mode SetOLED_WriteCommand(0x12);//OLED_WriteCommand(0xDB);//set vcomh deselect levelOLED_WriteCommand(0x40);//VCOM = β X VREF = (0.430 + A[7:0] X 0.006415) X VREFOLED_WriteCommand(0xA4);OLED_WriteCommand(0xA6);OLED_WriteCommand(0xAF);//set display display ON/OFF,AEH/AFH//这两条指令是设置反显,取消注释即为打开反显,//OLED_WriteCommand(0xAF);//OLED_WriteCommand(0xA7);//set normal/inverse display: A6H:normal/A7H:inverseOLED_Clear();
}

【4.3】OLED 汉字字模库 | BMP图像库

//使用软件添加字模库
//16*16
const unsigned char Tab[]={0x20,0x24,0x24,0x24,0xFE,0x23,0x22,0x20,//我
0x20,0xFF,0x20,0x22,0x2C,0xA0,0x20,0x00,
0x00,0x08,0x48,0x84,0x7F,0x02,0x41,0x40,
0x20,0x13,0x0C,0x14,0x22,0x41,0xF8,0x00,    0x00,0xF8,0x0C,0x0B,0x08,0x08,0xF8,0x40,//的
0x30,0x8F,0x08,0x08,0x08,0xF8,0x00,0x00,
0x00,0x7F,0x21,0x21,0x21,0x21,0x7F,0x00,
0x00,0x00,0x43,0x80,0x40,0x3F,0x00,0x00,};//BMP图像库const unsigned char BMP0[]={
0x00,0xFE,0xFE,0x06,0x06,0xE6,0xE6,0xE6,
0xE6,0xE6,0x06,0xFE,0xFE,0x00,0x00,0xC6,
0xD8,0xD8,0xDE,0xDE,0xDE,0xF8,0xF8,0x1E,
0xD8,0xD8,0xDE,0xCE,0xC0,0x04,0x06,0x20,
0x20,0x20,0x30,0x3E,0xDE,0xDE,0x00,0x0C,
0x1E,0x1E,0x1E,0xD8,0xDC,0xFE,0xFE,0xFE,
0x38,0x00,0x00,0xFE,0xFE,0x06,0xE6,0xE6,
0xE6,0xE6,0xE6,0x06,0x06,0xFE,0xFE,0x00,
0x00,0x00,0x1F,0x1F,0x18,0x18,0xDB,0x1B,
0x1B,0xDB,0xD9,0xD8,0xDF,0xDF,0x00,0x00,
0xD8,0x01,0x01,0xD8,0x21,0x23,0x1B,0x1B,
0x24,0x3B,0x3B,0x23,0x23,0xDB,0x04,0x04,
0xFB,0xFB,0xE7,0xEF,0x9C,0xE4,0xE4,0xFC,
0x7C,0x26,0xD8,0xD8,0xE0,0x9E,0x1F,0xC7,
0xC7,0x3F,0xC0,0xC0,0x1F,0x1F,0x18,0x19,
0x1B,0xDB,0x9B,0x1B,0x18,0x18,0xDF,0x9F,
0x00,0x00,0x00,0xE0,0xE0,0xE0,0xE0,0x03,
0x90,0x98,0x60,0x60,0x0C,0x64,0x64,0x9B,
0x91,0x80,0x10,0x10,0x80,0x9F,0x9F,0x03,
0x03,0xFF,0x60,0x60,0x73,0x7B,0x1C,0x63,
0xE3,0x63,0x63,0x63,0x23,0x03,0x7C,0x7C,
0x73,0x9C,0x9C,0x9C,0x9C,0x7C,0xBC,0x98,
0x83,0x83,0x83,0x73,0x7B,0xE4,0xE4,0x04,
0x7C,0x7C,0xE3,0xE3,0x80,0xE7,0xE7,0x84,
0x84,0x00,0x00,0x00,0x03,0x03,0x00,0x00,
0x7C,0xF3,0xF3,0x6C,0x6C,0x6F,0x93,0x93,
0x8F,0x87,0x00,0x9C,0x9C,0x70,0x0F,0x0F,
0xEC,0xEC,0xEF,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x9C,0x70,0x70,0x7F,0x4D,
0x0C,0x00,0x01,0xF3,0x30,0x10,0x73,0x73,
0x0F,0x8F,0x8F,0x90,0x91,0x83,0xF3,0xF3,
0xFF,0xFF,0x00,0x00,0x00,0x38,0x38,0x46,
0xC6,0xF8,0xCF,0xCF,0x38,0xB8,0xC8,0xC9,
0xC9,0x07,0x87,0xC6,0xF7,0xF7,0xC8,0xC6,
0xC6,0xFF,0xFF,0x03,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFF,0xC8,0xCC,0xFE,
0xFE,0xFE,0x08,0x0C,0xCF,0x0C,0x08,0xBE,
0x3E,0x0E,0x47,0xC7,0x01,0x01,0x41,0xFF,
0xFF,0xC1,0xC1,0x00,0x00,0x00,0x27,0x37,
0xC6,0xC6,0x07,0xC0,0xC0,0x07,0x07,0x31,
0x36,0x36,0xCF,0xCF,0xC9,0xCE,0xDE,0x39,
0x47,0xC7,0xF8,0xF8,0xC7,0xE1,0xF1,0x06,
0x06,0x18,0x0E,0x0E,0x37,0x37,0x36,0xB2,
0xF1,0x38,0x38,0xF0,0xC8,0xC8,0xC6,0xC6,
0xD9,0xC9,0xD9,0xC6,0xC6,0xFE,0x9E,0x0E,
0xF7,0xE7,0xC0,0x20,0x30,0x0F,0x0F,0x00,
0x39,0x39,0xF7,0xE7,0x00,0x00,0x00,0xF9,
0xF9,0x18,0x18,0xD9,0xD9,0xD9,0xD9,0x99,
0x19,0xF9,0xF9,0x01,0xA4,0xE6,0x3E,0x3E,
0xC0,0xE0,0xE0,0xFE,0xFE,0xDE,0x38,0x38,
0x38,0x38,0x00,0x84,0xC6,0xDF,0xDF,0xD9,
0xDB,0x3F,0x00,0x00,0x01,0x86,0xC6,0x1F,
0x1F,0xE1,0xE1,0xE1,0x1F,0x1F,0xFF,0xC3,
0xC1,0xD9,0xD9,0xC1,0xFF,0xFF,0xC1,0x81,
0x18,0xF9,0xF9,0x3E,0x3C,0x00,0x00,0x00,
0x7F,0x7F,0x60,0x60,0x67,0x67,0x67,0x67,
0x67,0x60,0x7F,0x7F,0x00,0x04,0x04,0x64,
0x64,0x00,0x1C,0x1C,0x78,0x78,0x1F,0x3B,
0x7B,0x7C,0x7C,0x60,0x61,0x63,0x03,0x03,
0x03,0x11,0x18,0x78,0x78,0x18,0x11,0x03,
0x1B,0x1B,0x1B,0x14,0x04,0x1B,0x1B,0x7B,
0x07,0x07,0x60,0x60,0x7F,0x6C,0x64,0x07,
0x07,0x00,0x73,0x7B,0x67,0x67,0x00,0x00,};

【4.4】OLED 汉字显示

x 取值 0-127

y 取值 0-8

N为字模第n组数组显示的汉字


void Chinese_Dis(unsigned char x,unsigned char y,unsigned char N)//显示16*16汉字
{unsigned int Num =N*32;unsigned int i = 0;OLED_SetCursor(y,x+2);        for ( i = 0; i < 16; i++){OLED_WriteData(Tab[Num]);       Num+=1;}OLED_SetCursor(y+1,x+2);        for (i = 0; i < 16; i++){OLED_WriteData(Tab[Num]);        Num+=1;}
}   int main()
{OLED_Init();   while(1){Chinese_Dis(1,1,0);Chinese_Dis(16,1,1);}
}

x取值范围:0-127

y取值范围:0-7

N为字模库第几个字

oled显示展示

【4.5】OLED BMP显示


void Oled_DisBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,const unsigned char Disp[])
{unsigned int j=0;unsigned char x,y;if(y1%8==0) {y=y1/8;}      else {y=y1/8+1;}for(y=y0;y<y1;y++){OLED_SetCursor(y,x0);for(x=x0;x<x1;x++){      OLED_WriteData(Disp[j++]);          }}
}

函数内有五个参数,x0与·y0是BMP图像在oled显示起始位置,x1,y1是图像末位置,Disp 是显示那个BMP字库数组名称,例如:要显示BMP0[]={...} 这个数组,则在函数中输入  Oled_DisBMP(x0,x1,y0,y1,BMP0);

x1,x0 范围:0-127

y1 ,x1 范围:0-7


int main()
{OLED_Init();while(1){Oled_DisBMP(0,0,65,8,BMP0);}
}

BMP显示实验展示

[图片]

【5】USART  串口实验

#include "stm32f10x.h"                  // Device header
#include "stdio.h"void led()//led PE5初始化
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_6;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOE,&GPIO_InitStruct);
}
void CUSART_init()//串口初始化函数
{GPIO_InitTypeDef GPIO_InitStruct;//GPIO结构体USART_InitTypeDef USART_InitStruct;//USART结构体NVIC_InitTypeDef NVIC_InitStruct;//中断结构体RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;//GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;//设置RX,TX端口串口使能GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//设置端口浮空输入GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;//设置RX,TX端口串口使能GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);USART_InitStruct.USART_BaudRate=9600;//波特率USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//硬件流设置USART_InitStruct.USART_Mode=USART_Mode_Tx | USART_Mode_Rx;//设置串口模式USART_InitStruct.USART_Parity=USART_Parity_No;//不使用奇偶校验USART_InitStruct.USART_StopBits=USART_StopBits_1;//设置停止位 1USART_InitStruct.USART_WordLength=USART_WordLength_8b;//传输或接受传输数据位USART_Init(USART1,&USART_InitStruct);USART_Cmd(USART1,ENABLE);//使能串口USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启串口接受中断     NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;NVIC_Init(&NVIC_InitStruct);
}#define USAERT_REC_LEN 200
unsigned char USART_RX_BUF[USAERT_REC_LEN]; //接受缓冲
unsigned int USART_RX_STA =0; //接受状态标志位/*
USART_RX_STA 定义为一个 16进制的标志位
接收到 0x8000 为 1000 0000 0000 0000 最高位(第15位)接收到1,表示接受完成
接收到 0x4000 同上第14位接收到1,表示接受到0x0d
0d 表示回车
oa 表示换行
以0d,0a结尾表示接收完成注意:蓝牙和STM32的波特率必须一致
如需使用蓝牙app与MCU通信将TX接到RX*/
void USART1_IRQHandler()//串口一中断服务函数
{unsigned char res;  //将接受的数据存放dataif(USART_GetITStatus(USART1,USART_IT_RXNE)!= RESET)//接受的数据以0x0d,0x0a结尾{res=USART_ReceiveData(USART1);//读取接受数据if((USART_RX_STA&0x8000)==0)//接受未完成{if(USART_RX_STA&0x4000)//接收到0x0d{if(res != 0x0a)//如果未接受到0x0a{USART_RX_STA=0;}else{USART_RX_STA|=0x8000;//接收完成 }}else//如果未接受到0x0d{if(res==0x0d)//接收到了{USART_RX_STA|=0x4000;}else{USART_RX_BUF[USART_RX_STA&0x3ffff]=res;// 0011 1111 1111 1111,储存数据个数USART_RX_STA++;//接受到的有效数据个数+1 GPIO_SetBits(GPIOE,GPIO_Pin_6);//关闭ledif(res== 0x45)//HC-05接收到0x45这个数据{GPIO_SetBits(GPIOE,GPIO_Pin_5);//关闭led}if(USART_RX_STA>(USAERT_REC_LEN-1))//接收数据出错,重新开始接受{USART_RX_STA=0;}}}}USART_SendData(USART1,res);//将储存的数据发送出去}} // 发送数据int fputc(int ch, FILE *f){USART_SendData(USART1, (unsigned char) ch);// USART1 可以换成 USART2 等while (!(USART1->SR & USART_FLAG_TXE));return (ch);}// 接收数据int GetKey (void) {while (!(USART1->SR & USART_FLAG_RXNE));return ((int)(USART1->DR & 0x1FF));}int main()
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);CUSART_init();led();//GPIO_ResetBits(GPIOE,GPIO_Pin_5);//关闭ledwhile(1){USART1_IRQHandler();}}

实验效果 :

未显示打印信息可能是未勾选[Use MicroLIB选项]

勾选上即可

滴答定时器延时1us

void Delay_us(uint32_t xus)
{SysTick->LOAD = 72 * xus;              //设置定时器重装值SysTick->VAL = 0x00;                  //清空当前计数值SysTick->CTRL = 0x00000005;                //设置时钟源为HCLK,启动定时器while(!(SysTick->CTRL & 0x00010000));   //等待计数到0SysTick->CTRL = 0x00000004;             //关闭定时器
}

STM32 F103 基础实验相关推荐

  1. 第一章 stm32 cubemx基础配置实验以及proteus 8的使用

    第一章 stm32 cubemx基础配置实验以及proteus 8的使用 文章目录 第一章 stm32 cubemx基础配置实验以及proteus 8的使用 前言 一.STM32 Cubemx基础配置 ...

  2. NB-IOT实验练习2——STM32基础实验

    STM32基础实验 上一节介绍了江苏学蠡信息科技有限公司的无线传感器网络实验平台关于NB-IOT实验所需要的各项硬件以及所需要的软件组成部分,这一章,主要是使用STM32F103单片机的基础实验进行介 ...

  3. ESP8266的一些MicroPython基础实验

    文章目录 ▌ESP8266模块 1.模块基本信息 2.模块管脚配置 ▌02 基础实验 1.测试GPIO (1)ON_OFF实验 (2)端口中断 2.测试PWM 3.测试ADC (1)基础的ADC (2 ...

  4. 基于STM32的步进电机实验

    目录 基于STM32的步进电机实验 步进电机介绍 步进电机基础知识 步进电机参数说明 例题说明 基于28BYJ步进电机的介绍 28BYJ步进电机的配置流程 电机工作状态与引脚的关系 四相八拍的正向旋转 ...

  5. CC2530基础实验:(8)串口通讯-发送字符串控制LED

     目录 前言 一.实验相关电路图 二.实验相关理论与寄存器 1.并行通信与串行通信 2.URAT 3.同步通信与异步通信 4.外设I/O 5.CC2530 的串口通信模块 6.相关寄存器 三.源码分析 ...

  6. [nRF51822] 8、基础实验代码解析大全 · 实验11 - PPI

    前一篇分析了前十个基础实验的代码,从这里开始分析后十个~ 一.PPI原理: PPI(Programmable Peripheral Interconnect),中文翻译为可编程外设互连. 在nRF51 ...

  7. 计算机应用基础实验报告册,计算机应用基础实验报告(flash)

    实 验 报 告 计算机应用基础实验报告 姓名 班级 学号 实验日期 课程名称 计算机应用基础 指导教师 成绩 实验名称:简单动画制作 实验目的: 掌握逐帧动画.形状渐变动画.运动渐变动画的制作方法 实 ...

  8. Grove Beginner Kits基础实验 Arduino

    简 介: 本文就Arduino的基础实验以及与ESP8266连接进行了初步实验.并基于此,给出了基于人脸识别只能门锁系统的硬件设计. 关键词: Arduino,ESP8266 §01 Arduino ...

  9. 计算机网络基础实验简答题,计算机网络基础实验报告.doc

    计算机网络基础实验报告 计算机科学与技术系 实 验 报 告专业名称课程名称计算机网络基础项目名称局域网组网实验班 级学 号姓 名同组人员实验日期实验目的与要求: (一).实验目的: 通过组建局域网,了 ...

最新文章

  1. ios 项目的.gitignore
  2. Java---replace与replaceAll的区别
  3. Bootstrap3 栅格系统-媒体查询
  4. 20180925-4 单元测试,结对
  5. synchronized原理_浅谈synchronized的实现原理
  6. web前端基础(01html基本标签)
  7. hive当前日期超前_微博数仓数据延时优化方案
  8. openresty查看log
  9. flash mx拖拽实例_Flash MX 2004 Professional的照片闪光器效果面板
  10. DiskFileUpload上传文件并获取前端表单数据
  11. cmd查看mysql的ip地址_怎么在cmd中查看数据库ip地?
  12. Anaconda下载官网
  13. 在matlab中syms是什么,syms在matlab中的作用是什么?
  14. Linux(CentOS下)更改终端命令行颜色及网络配置
  15. KeyError(‘metric mAP is not supported‘.format(metric))
  16. CVPR2022 目标检测方向文章(附摘要)
  17. 计算机汉字的输入和编辑教案,计算机汉字录入教案.doc
  18. 【短期利率模型之Rendleman-Bartter模型】
  19. [PaperNote] Confidential Computing Direction
  20. WebMatrix快捷键

热门文章

  1. 解决内联汇编64位Linux系统调用提示Bad Address
  2. allergo(16.6)创建异形焊盘
  3. 绘制炫酷逼真的三维地形图
  4. WebKit研究报告(转自http://blog.csdn.net/hou_jiong/archive/2009/01/18/3831022.aspx)
  5. 2022年11月前端学习笔记
  6. 如何卸载Model Sim
  7. 人面不知何处去,桃花依旧笑春风
  8. DDR4 Spec 第四章 4.19-4.23
  9. 【学习笔记】SAP固定资产的减值功能
  10. linux当前目录改为桌面,Latte Dock 作为一个 KDE 漂亮的桌面面板替换