GPIO输入输出

GPIO 重要函数——一个定义函数和八个读写函数

函数 参数 功能
GPIO_Init (GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
uint8_t GPIO_ReadInputDataBit (GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) (单个)代表端口的高低电平,作用:读取按键
uint16_t GPIO_ReadInputData (GPIO_TypeDef* GPIOx) (整个)读取整个输入数据寄存器
uint8_t GPIO_ReadOutputDataBit (GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) (单个)用来读取输出数据寄存器的某一位,用于输出模式
uint8_t GPIO_ReadOutputData (GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) (整个)用来读取整个输出数据寄存器
void GPIO_SetBits (GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
void GPIO_ResetBits (GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
void GPIO_WriteBit (GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
void GPIO_Write (GPIO_TypeDef* GPIOx, uint16_t PortVal)

LED闪烁 GPIO输入

static void delay_ms(uint32_t ms)    // 定义一个ms延时函数,减少移植时对外部文件依赖;
{
    ms=ms*10286;                     // 注意:打勾 "Options --> C/C++ ---> One ELF Section per Function选项" 
    for(uint32_t i=0; i<ms; i++);    // 72MHz系统时钟下,大约多少个空循环耗时1ms
}

int main(void)
{
	
	//GPIO初始化
	GPIO_InitTypeDef GPIO_InitStructrue;
	
	GPIO_InitStructrue.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructrue.GPIO_Pin = GPIO_Pin_2;//PB2 输出低电平
	GPIO_InitStructrue.GPIO_Speed = GPIO_Speed_50MHz ;
	GPIO_Init(GPIOB, &GPIO_InitStructrue );
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//调用RCC里ARB2外设时钟控制函数   打开GPIOB的端口
	
	//GPIO_WriteBit(GPIOB,GPIO_Pin_2,Bit_RESET);//点亮
	
	
	while(1)
	{
		GPIO_WriteBit(GPIOB,GPIO_Pin_2,Bit_RESET);//点亮
		delay_ms (500);
		GPIO_WriteBit(GPIOB,GPIO_Pin_2,Bit_SET);//点亮
		delay_ms (500);
		
	}

}

蜂鸣器同理 对应端口 和使用函数

有道词典——划词翻译

GPIO输入

typedef struct
{
  __IO uint32_t CRL;//端口配置低寄存器
  __IO uint32_t CRH;//端口配置高寄存器
  __IO uint32_t IDR;//端口输入数据寄存器
  __IO uint32_t ODR;//端口输出数据寄存器
  __IO uint32_t BSRR;//端口位设置/清除寄存器
  __IO uint32_t BRR;//端口位清除寄存器
  __IO uint32_t LCKR;//端口配置锁定寄存器
} GPIO_TypeDef;

√ C语言指针 √ AD/DA运算发大器 √ 模块化编程

C语言

1. stm32 代表c语言的数据类型——头文件定义的

2.指针

按键

功能和使用

原理图

在.h 文件中配置

// KEY_1_WKUP, 闲时下拉,按下时被置高电平
#define KEY_1_GPIO                GPIOA
#define KEY_1_PIN                 GPIO_Pin_0 
// KEY_2, 闲时上拉,按下时被置低电平
#define KEY_2_GPIO                GPIOA
#define KEY_2_PIN                 GPIO_Pin_1 
// KEY_2, 闲时上拉,按下时被置低电平
#define KEY_3_GPIO                GPIOA
#define KEY_3_PIN                 GPIO_Pin_4
   


#define KEY_ON     1
#define KEY_OFF    0  

在.c 文件

void Key_Init(void)
{
    //对应端口和引脚使能
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
    
     // KEY_1
    GPIO_InitStructure.GPIO_Pin  = KEY_1_PIN;               // 引脚KEY_1, 闲时下拉(重要), 按下时被置高电平
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD ;          // 闲时电平状态(使用芯片内部电阻进行电平上下拉)
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz ;      // 输出电平反转速度;在输入状态时无效,但GPIO_Init函数需要用到;
    GPIO_Init(KEY_1_GPIO, &GPIO_InitStructure);             // 初始化,调用引脚工作模式配置函数
    
    // KEY_2
    GPIO_InitStructure.GPIO_Pin  = KEY_2_PIN;               // 引脚KEY_1, 闲时下拉(重要), 按下时被置高电平
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;          // 闲时电平状态(使用芯片内部电阻进行电平上下拉)
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz ;      // 输出电平反转速度;在输入状态时无效,但GPIO_Init函数需要用到;
    GPIO_Init(KEY_2_GPIO, &GPIO_InitStructure);             // 初始化,调用引脚工作模式配置函数

    // KEY_3
    GPIO_InitStructure.GPIO_Pin  = KEY_3_PIN;               // 引脚KEY_1, 闲时下拉(重要), 按下时被置高电平
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;          // 闲时电平状态(使用芯片内部电阻进行电平上下拉)
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz ;      // 输出电平反转速度;在输入状态时无效,但GPIO_Init函数需要用到;
    GPIO_Init(KEY_3_GPIO, &GPIO_InitStructure);             // 初始化,调用引脚工作模式配置函数
}
/******************************************************************************
 * 函  数: Key_Scan
 * 功  能: 扫描按键状态
 * 参  数: GPIOx:     GPIO端口 
 *          PINx :      Pin引脚编号
 *          downStatus: 按下时的电平
 *
 * 返回值: KEY_ON : 按下
 *          KEY_OFF:无动作
 *     
 * 说  明: 1: 本函数检测方式为“while不断扫描”,发现按键按下且等待按键松开,为一次有效按下动作;   
 *          2:本方法建议只用示例使用,实际项目中,建议使用中断方法检测;
 ******************************************************************************/ 
uint8_t Key_Scan(GPIO_TypeDef* GPIOx, uint16_t PINx , uint8_t downStatus)
{	
    if(GPIO_ReadInputDataBit(GPIOx, PINx)==downStatus)
    {   
        while(GPIO_ReadInputDataBit(GPIOx, PINx)==downStatus);
        return KEY_ON;
    }		
    return KEY_OFF;	     
}

例程

int main(void)                       // 主函数, 整个工程的用户代码起始点
{   
    Led_Init();                      // LED初始化
    LED_BLUE_ON ;                    // 点亮蓝灯

    Key_Init();                      // KEY初始化        

    while(1)                         // while函数死循环,不能让main函数运行结束,否则会产生硬件错误
    { 
        // 按键1检测
        if(Key_Scan(KEY_1_GPIO, KEY_1_PIN, 1))    // 参数说明:GPIO端口,Pin引脚编号, 按下时的电平 
        {
            LED_BLUE_TOGGLE;                      // 当扫描到KEY1单击,蓝色LED反转一次
        }
        // 按键2检测
        if(Key_Scan(KEY_2_GPIO, KEY_2_PIN, 0))
        {
            LED_BLUE_TOGGLE;                      // 当扫描到KEY2单击,蓝色LED反转一次
        }
        // 按键3检测
        if(Key_Scan(KEY_3_GPIO, KEY_3_PIN, 0)) 
        {                
            LED_BLUE_TOGGLE;;                     // 当扫描到KEY3单击,蓝色LED反转一次
        }                         
    }          
}

补充

模块化

宏定义

结构体

更改变量类型名——typedef

int main()
{
    //定义一个结构体
    Struct{char x;int y;float z;}c;
    c.x = 'A';
    c.y = 66;
    c,z = 1.2;
    printf("c.x = %c\n")
}
枚举

给定参数里赋值和引用

OLCD

原理图

函数

LED函数 参数 功能
void LCD_String(uint16_t lcd_x, uint16_t lcd_y, char *pFont, uint8_t size, uint16_t fColor, uint16_t bColor) 起始坐标(x,y);内容;字体大小;颜色 在屏幕上显示字符串:支持英文、中文。符号、英文字模存放在font.h文件中,汉字字模存放在W25Q128中
void drawPoint(u16 x, u16 y, u16 color) x坐标,y坐标, 16位颜色值 画一个点
void LCD_Fill(u16 xStart, u16 yStart, u16 xEnd, u16 yEnd, u16 color) 左上角起始坐标;右上角起始坐标;颜色 在指定区域内填充单个颜色
void LCD_Circle(u16 x0, u16 y0, u8 r, u16 color) (x,y)中心点坐标;r半径;颜色 指定位置画指定大小的圆
void LCD_Image(u16 x, u16 y, u16 width, u16 height, const u8 *image) u16 x,y 左上角起始坐标 * u16 width 图片宽度 * u16 height 图片高度 * u8* image 数据缓存地址 在指定区域内填充指定图片数据
void LCD_Chinese16ForFile(uint16_t x, uint16_t y, uint8_t index, uint16_t fColor, uint16_t bColor) 起始坐标x,y;字库数据在缓存的位置 显示1个16号汉字,字库数据在font文件中,只适合少量汉字固定输出。PCtoLCD2002取模:阴码+逐列式+顺向+C51格式

实例

void LCD_GUI(void)
{
    // 显示任意中英文                                       // 优点:完整宋体中文字库,可显示任意汉字; 缺点:需要依赖开发板上已存有字库数据的Flash
    LCD_String(18, 10, "综合测试",      24, YELLOW, BLACK); // 显示字符串
    LCD_String(8, 40, "STM32-F103C8T6", 16, WHITE, BLACK);  // 显示字符串

    // 显示特定中文                                         // 优点:无须依赖外部Flash字库,数据存于:font.h; 缺点:受限芯片内部Flash大小,只能存放小量字库
    LCD_Chinese16ForFile(35, 65, 2, BLACK, WHITE);          // "显", 字模数据存放于font.h的数组中
    LCD_Chinese16ForFile(51, 65, 3, WHITE, RED);            // "示"
    LCD_Chinese16ForFile(67, 65, 4, BLACK, GREEN);          // "方"
    LCD_Chinese16ForFile(83, 65, 5, WHITE, BLUE);           // "案"

    LCD_Image(40, 100, 60, 60, imageLoge);                  // 显示图片

    LCD_Fill(1,   1,   8,   8, WHITE);                      // 屏幕填充,
    LCD_Fill(121,   1, 129,   8, RED);                      // 通过放大镜观察左上角、右上角两个色块,发现物理像素的X坐标,左边被遮挡了第1列,右边多了1列129
    LCD_Fill(1, 152,   8, 160, GREEN);                      // 用于判断XY坐标与物理像素位置是否相符
    LCD_Fill(121, 152, 129, 160, BLUE);                     //

}

中断

EXTI外部中断

数电

符号 功能
或门 )〉 多个输入,一个输出 执行或的逻辑,只有全部输入低电平0,输出才为0
与门 | 多个输入,一个输出 执行与的逻辑,只要输入一个低电平0,输出就是0
) 〕

TIM定时中断

简介:

定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断。
16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能。

定时器类型 用途
高级定时器 具有通用功能以外、还具有死区控制的互补信号输出、紧急刹车关断输入等功能
通用计时器 具备多路独立的捕获和比较通道,可以完成定时/计数、输入捕获、输出比较等功能。
基本定时器 定时、计数功能、主模式触发DAC的功能

’ C8T6的定时器资源 ':TIM1、TIM2、TIM3、TIM4

一个高级定时器和三个调用定时器,没有基本定时器