2. 通用并行接口GPIO

2.  通用并行接口GPIO

  2.1 GPIO结构及寄存器说明

  2.2 GPIO设计实例

    2.2.1 直接操作寄存器软件设计

    2.2.2 使用库函数范例程序(v2.0.1)

    2.2.3 用GPIO控制LCD

2.1 GPIO结构及寄存器说明

  • GPIO包括多个16位I/O端口,每个端口可以独立设置3种输入方式和4种输出方式,并可独立地置位或复位
  • GPIO由寄存器、输入驱动器和输出驱动器等部分组成

  • GPIO通过7个32位寄存器进行操作

偏移地址

名称

类型

复位值

说明

0X00

CRL

读/写

0X44444444

配置寄存器低位(每个端口4位)

0X04

CRH

读/写

0X44444444

配置寄存器高位(每个端口4位)

0X08

IDR

0X0000

16位输入数据寄存器

0X0C

ODR

读/写

0X0000

16位输出数据寄存器

0X10

BSRR

0X00000000

位置位/复位寄存器

0X14

BRR

0X0000

位复位寄存器

0X18

LCKR

读/写

0X00000

配置锁定寄存器

  • 每个端口的4个配置位是CNF[1:0]和MODE[1:0]
CNF[1:0] MODE[1:0] 输入配置 CNF[1:0] MODE[1:0](2) 输出配置
00  00  模拟输入 00 01/10/11 通用推挽输出
01  00  浮空输入(复位状态) 01 01/10/11 通用开漏输出
10 00 上拉/下拉输入(1) 10 01/10/11 复用推挽输出
11  00 保留 11 01/10/11 复用开漏输出

注:(1)ODR = 1:上拉,ODR = 0;下拉

(2)01/10/11 依次对应最大输出频率为10MHz/2MHz/50MHz

2.2 GPIO设计实例

  • 系统包括Cortex-M3 CPU(内嵌SYSTick定时器)、存储器、2个按键接口和4个LED接口,实现用2个按键控制4个LED的流水显示方向,4个LED流水显示,每1s移位1次

    2.2.1 直接操作寄存器软件设计

  • 头文件(main.h)
//包含结构定义头文件
#include "stm32f10x_map.h"
//声明函数
void SysTick_Init(void);
void SysTick_Proc(void);
void Key_init(void);
void Key_Proc(void);
void Led_Init(void);
void Led_Proc(void);
  • 源文件(main.c)(主程序)
//包含头文件
#include "main.h"
//定义全局变量
char Clag = 0 , sec = 0 , secl = 0 ;
unsigned short led_dat[4] = {1 << 12 , 1 << 13 , 1 << 14 , 1 << 15 }; 
char led_num = 0 ;
//主函数
int main(void)
{
    SysTick_Init();								//系统定时器初始化
    Key_Init();								//按键接口初始化
    Led_Init();								//LED接口初始化
    while(1)
    {
        SysTick_Proc();						//定时器处理函数
        Key_Proc();							//按键处理函数
        Led_Proc();							//LED处理函数
    }
}
  • 源文件(main.c)定时器子程序
//系统定时器初始化子程序
void SysTick_Init(void)
{
    SysTick->LOAD = 1E6;						//设置(时钟频率)
    SysTick->CTRL = 1 ;						//启动定时器
}
//定时处理子程序
void SysTick_Proc(void)
{
    if(SysTick->CTRL & 1<<16)     				//1s时间到
    {	
        sec += 1 ;
        if((sec &	0xf)	>	9)
        sec += 6;							//2-10进制调整
    }
}
  • 源文件(main.c)(按键子程序)
//按键接口初始化子程序
void Key_Init(void)
{
    RCC->APB2ENR	|=	1<<3	;			//开启按键接口(GPIOB)时钟
}

//按键处理子程序
void Key_Proc(void)
{
    if(~GPIOB->IDR	&	1<<8)					//KEY1按下(PB.08=0)
        flag	=	0;
    if(~GPIOB->IDR	&	1<<9)
        flag	=	1;								//KEY2按下(PB.09=0)
}
  • 源文件(main.c)(LED子程序)
//LED接口初始化程序
void Led_Init(void)
{
    RCC->APB2ENR	|=	1<<3;					//开启LED接口(GPIOB)时钟
    GPIOB->CRH	&=	0x0000ffff;
    GPIOB->CRH	|=	0x33330000;					//PB.15-PB.12通用推挽输出
}
//LED处理子程序
void Led_Proc(void)
{
    if(sec	!=	sec1	)							//1s时间到
    {
        sec1	=	sec;
        GPIOB->BSRR	=	0xf000;				//灭所有LED
        GPIOB->BRR	=	led_dat[led_num];			//亮指定LED	
        if(flag)
        {
            if(++led_num	==	4)
                led_num	=	0;					//左环移
        }
        else
        {
            if(led_num--	==	0)
                led_num	=	3;					//右环移
        }
    }
}

使用仿真器调试和运行目标程序文件

  • 使用仿真器调试和运行目标程序文件通过仿真硬件实现,不需要目标硬件
  • 使用仿真器调试和运行目标程序还具有分析(Analysis)功能,包括逻辑分析仪(Logic Analyzer)、性能分析仪(Performance Analyzer)和代码覆盖率(Code Coverage)
  • 逻辑分析仪(Logic Analyzer)是非常有用的调试功能

    2.2.2 使用库函数范例程序

  • 在C:\Keil\ARM\Examples\ST\STM32F10xFWLib\Examples\SysTick目录包含有使用库函数的SysTick和GPIO范例程序
  • 其中包含下列7个文件:

main.c:主程序文件

main.h:主程序头文件

stm32f10x_it.c:中断服务程序文件

stm32f10x_it.h:中断服务程序头文件

platform_config.h:开发版配置文件

stm32f10x_conf.h:库配置文件

readme.txt:范例说明文件

    2.2.3 用GPIO控制LCD

1、LCM046简介

  • LCM046是4位多功能通用型8段(8.8.8.8)液晶显示模块内置显示RAM,可以显示任意字段笔画,3-4线串行接口

引脚       功能       方向           说明                         引脚          功能          方向         说明

1            /CS        输入          片选(内部上拉)      6             VLCD        输入         对比度调整

2            /RD        输入             读(内部上拉)      7              VDD         输入        电源(2.7-5.5V)

3            /WR       输入             写(内部上拉)      8              IRQ           输出       定时器中断

4            DA         双向          数据(内部上拉)      9              BZ            输出        蜂鸣器正极

5            GND       -                 地                            10            /BZ            输出        蜂鸣器负极

  • LCM046写操作时序

  • 写命令格式为:100命令代码(C7-C0:8位)0,共12位
  • 写数据格式为:101地址(A5-A0:6位)数据(D0-D3:4位),共13位
  • LCM046常用命令代码

命令代码                      功能                  命令代码                   功能

0000 0000               关振荡器             0001 0100           定义外部晶体振荡器工作

0000 0001               开振荡器             0001 1000           定义内部RC振荡器工作

0000 0010               关显示器              0010 1001          初始化模块

0000 0011                开显示器

  • 初始化模块的步骤是:

(1)初始化模块命令 (2)定义内部RC振荡器工作

(3)开振荡器 (4)开显示器

  • LCM046地址数据

地址                             数据                         地址                                  数据

A5-A0              D3     D2     D1     D0           A5-A0                  D3    D2     D1     D0

000000           COL   1E     1F     1A            000001                1D    1C     1G     1B

000010           DP1    2E    2F     2A            000011                 2D    2C     2G     2B

000100           DP2    3E    3F     3A            000101                 3D    3C     3G    3B

000110           DP3     4E   4F     4A             000111                 4D    4C    4G     4B

2、GPIO控制LCM046程序设计(写子程序)

//LCM046写子程序
//入口参数:data=写数据,bit=数据位
void Lcd_Write(short	data,	char 	bit)
{
    short m,n;
    GPIOA->BRR	=	1<<4;						//	PA.04(LCD_CS)=0
    for(m=bit-1;	m>=0;	m--)
    {
        GPIOA->BRR	=	1<<5;					//	PA.05(LCD_WR)=0
        if(data	&	1<<m)
            GPIOA->BSRR	=	1<<7;			//	PA.07(LCD_DA)=1
        else
            GPIOA->BRR	=	1<<7;				//	PA.07(LCD_DA)=0
        GPIOA->BSRR	=	1<<5;				//	PA.05(LCD_WR)=1
        for(n=0;	n<5;	n++);						//	延时
    }
    GPIOA->BSRR	=	1<<7;					//	PA.07(LCD_DA)=1
    GPIOA->BSRR	=	1<<4;					//	PA.04(LCD_CS)=1
}

2、GPIO控制LCM046程序设计(写命令/数据子程序)

//LCM046写命令子程序
//入口参数:code-8位命令代码
void Lcd_Code_Write(char	code)
{
    short data	=	(4<<9)+(code <<1);
    Lce_Write(data,12);
}
//LCM046写数据子程序
//入口参数:addr-6位地址,data-4位数据
void Lcd_Data_Write(char	addr,	char		data)
{
    short	data1	=	(5<<10)+(addr<<4)+data;
    Lcd_Write(data1,13);
}

2、GPIO控制LCM046程序设计(初始化子程序)

//LCM046初始化子程序
void Lcd_Init(void)
{
    RCC->APB2ENR	|=	1<<2;						//开启LCD接口(GPIOA)时钟
    GPIOA->CRL	|=	0x70770000;					//PA.07、PA.05和PA.04通用开漏输出
    GPIOA->ODR	|=	0x00b0;						//PA.07、PA.05和PA.04输出高电平
    Lcd_Code_Write(0x29);								//初始化模块
    Lcd_Code_Write(0x18);								//内部振荡器
    Lcd_Code_Write(0x01);								//开振荡器
    Lcd_Code_Write(0x03);								//开显示器
}

2、GPIO控制LCM046程序设计(显示处理子程序)

//LCM046显示处理子程序
//入口参数:data1-前2位显示数据,data2-后2位显示数据,dot-COL DP1 DP2 DP3
void Lcd_Proc(char data1,char data2,char dot)
{
    char	i;
    //0-9,A-F倒显编码(格式AFE.BGCD)
    char lcd_code[16]={0xeb,0x60,0xad,0xe5,0x66,0xe7,0xcf,0x61,//0 1 2 3 4 5 6 7
    0xef,0xef,0x6f,0xce,0x8b,0xec,0x8f,0x0f//8 9 A B C D E F
    };
    short	data	=	(data1<<8)+data2;
    for(	i=0;	i<4	;i++)
    {
        data1	=	lcd_code[(data>>(4*i))&0xf];
        Lcd_Data_Write(2*i,(data1>>4)+((dot>>(3-i))&0x1));
        Lcd_Data_Write(2*i+1,data1&0xf);
    }
}

2、GPIO控制LCM046程序设计(信号波形)

猜你喜欢

转载自blog.csdn.net/SherlockHolmess/article/details/87709809
2.