主题中讨论的其他器件:TM4C123
工具/软件:TI C/C++编译器
您好!
我将2x3矩阵键盘与 TM4C123微控制器相连。 我所写的程序在第一行中工作正常、因为每当我按下第一行中的按钮时、液晶屏上都会显示相应的谐振数据。 我所面临的问题与第二行有关。
第0排门 PIN7, 第1排 PORTF PIN0
列 PORTF 引脚1、2、3
RS 连接到端口 G 引脚4、使能引脚连接到端口 G 引脚5、D0到 D4分别连接到端口 G 引脚0到引脚4。I AM 使用的 LCD 是4位模式 LCD。
下面给出了我的程序
#include
#include
#include "inc/hw_i2c.h"
#include
#include
#include "inc/hw_i2c.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/i2c.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/SysTick .h"
#include "inc/hw_NVIC.h"
#include "inc/hw_types.h"
#include "driverlib/pin_map.h"
#include "driverlib/interrupt.h"
volatile uint32_t msTicks = 0;
unsigned char temp;
/
SysTick 中断功能
(二 /
空 SysTick 处理程序(空)
{
//
//更新 SysTick 中断计数器。
//
/* delay 中必需的递增计数器()*/
msTicks++;
}
空延迟(uint32_t dlyTicks)
{
uint32_t curTicks;
curTicks = msTicks;
while (msTicks - curTicks )< dlyTicks;
}
/
SysTick 中断结束
(二 /
void lcd_command (unsigned char cmd)
{
//发送较高的四位
temp= cmd;
temp=(temp>>4)& 0x0F);//将数据向右移动四位,从而使较高半字节位于较低半字节位置
//temp=(temp & 0x0F);
//delay (1000);
//GPIOPinWrite (GPIO_PORTD_base、GPIO_PIN_0、com);//LCD 模式
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3、temp);//LCD 数据
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_4、0);// RS=0GPIO 引脚4、E=0 GPIO 引脚5
延迟(50);
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_5、0);//make E=0
//delay (50);
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_5、GPIO_PIN_5);// RS=0、E=1通过高电平到低电平脉冲启用 LCD
//delay (50);
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_5、0);// RS=0、E=0
//delay (50);
//发送低4位
temp=cmd;//发送低半字节
//temp=temp>>4;//将数据向右移动四位,从而在半字节位置将较高的半字节引入
temp=(temp & 0x0F);
//GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_4|GPIO_PIN_5、0x00);// RS=0GPIO 引脚4、E=0 GPIO 引脚5
//delay (1000);
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3、temp);//写入数据
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_5、0);//make E=0
//delay (50);
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_5、GPIO_PIN_5);// RS=0、E=1通过高电平到低电平脉冲启用 LCD
//delay (50);
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_5、0);// RS=0、E=0
延迟(50);
}
void LCD_data (无符号字符数据)
{
temp=数据;
temp=(temp>>4)& 0x0F);//将数据向右移动四位,从而使较高半字节位于较低半字节位置
//temp=(temp & 0x0F);
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3、temp);//LCD 数据
//GPIOPinWrite (GPIO_PORTD_base、GPIO_PIN_0、com);//LCD 模式
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_4、GPIO_PIN_4);// RS=1 GPIO 引脚-4、E=0 GPIO 引脚5
//delay (50);
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_5、0);//make E=0
//delay (50);
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_5、GPIO_PIN_5);//E=1通过高电平到低电平脉冲启用 LCD
//delay (50);
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_5、0);//make E=0
//delay (50);
temp= data;////发送低半字节
//temp=temp>>4;
temp=(temp & 0x0F);
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3、temp);//LCD 数据
//delay (1000);
//GPIOPinWrite (GPIO_PORTD_base、GPIO_PIN_0、com);//LCD 模式
//GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_4|GPIO_PIN_5、0x10);//make RS=1GPIO 引脚4、E=0 GPIO 引脚5
//delay (1000);
//
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_5、0);//make E=0
//delay (50);
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_5、GPIO_PIN_5);//make RS=1、E=1、通过高电平到低电平脉冲启用 LCD
//delay (50);
GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_5、0);//make RS=1、E=0
延迟(50);
}
void LCD_Init()
{
LCD_COMMAND (0x28);//4位模式 LCD、在5x7矩阵之间具有2行和字符形状。
延迟(50);//提供500ms 延迟
LCD_COMMAND (0x06);//显示打开、光标关闭/进入模式它告诉 LCD 我们将要使用。
延迟(50);//提供500ms 延迟
//LCD_COMMAND (0x0E);//显示光标打开,显示方向。
//delay (50);//提供500ms 延迟
LCD_COMMAND (0x01);//清除屏幕
延迟(50);//提供500ms 延迟
LCD_COMMAND (0x0F);//将光标显示在上,显示在上。
延迟(50);//提供500ms 延迟
}
void LCD_String_Display (无符号字符*str)
{
while (*str!='0')
{
lcd_data (*str);
STR++;
}
}
/
键盘功能
「香港 /
空 key_detect (无符号字符值)
{
if (value ==1)//column 1键被按下
{
GPIOPinWrite (GPIO_Porte _BASE、GPIO_PIN_7、GPIO_PIN_7);//将行0设为高电平
if (GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_1)=0x02)//列1状态从低电平变为高电平
{
LCD_COMMAND (0x01);//清除屏幕
LCD_COMMAND (0xC0);
LCD_String_Display ("Row0 colmn1");
延迟(50);
}
其他
{
GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_0、GPIO_PIN_0);//将行1设为高电平
if (GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_1)=0x02)//列1状态从低电平变为高电平
{
LCD_COMMAND (0x01);//清除屏幕
LCD_COMMAND (0xC0);
LCD_String_Display ("行1颜色1");//检查行1状态是否变为低电平
}
}
}
if (value ==2)//column 1键被按下
{
GPIOPinWrite (GPIO_Porte _BASE、GPIO_PIN_7、GPIO_PIN_7);//将行0设为高电平
GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_0、GPIO_PIN_0);
if (GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_2)=0x04)//列2状态从低电平变为高电平
{
LCD_COMMAND (0x01);//清除屏幕
LCD_COMMAND (0xC0);
LCD_String_Display ("行0 Colm 2");
}
其他
{
if (GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_2)=0x04)//列2状态从低电平变为高电平
{
LCD_COMMAND (0x01);//清除屏幕
LCD_COMMAND (0xC0);
LCD_String_Display ("行1 Colm 2");
}
}
}
if (value ===3)//column 1键被按下
{
GPIOPinWrite (GPIO_Porte _BASE、GPIO_PIN_7、GPIO_PIN_7);//将行0设为高电平
GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_0、GPIO_PIN_0);
if (GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_3)=0x08)
{
LCD_COMMAND (0x01);//清除屏幕
LCD_COMMAND (0xC0);
LCD_String_Display ("Row 0 Colm 3");//column 3状态从低电平变为高电平
}
其他
{
if (GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_3)=0x08)//列3状态从低电平变为高电平
{
LCD_COMMAND (0x01);//清除屏幕
LCD_COMMAND (0xC0);
LCD_String_Display ("行1 Colm 3");
}
}
}
延迟(50);
GPIOPinWrite (GPIO_Porte _BASE、GPIO_PIN_7、0);
GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_0、0);
}
/
键盘功能结束
(二 /
/
主程序
(二 /
int main()
{
SysCtlClockSet (SYSCTL_SYSDIV_1|SYSCTL_USE_OSC |SYSCTAL_8MHZ|SYSCTL_OSC_MAIN);//8MHz 停止晶体器
IntMasterEnable();//启用处理器中断。
SysTickPeriodSet (7997);//为 SysTick 计时器设置1ms 的周期。
SysTickIntEnable();//启用 SysTick 中断。
SysTickEnable();
//启用端口
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOG);
//while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOG));
//定义引脚
GPIOPinTypeGPIOOutput (GPIO_PORTG_base、GPIO_PIN_0|GPIO_PIN_1_GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5);
端口 F 的//引脚连接到键盘的行1、2
GPIOPinTypeGPIOOutput (GPIO_Porte _BASE、GPIO_PIN_7);
GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、GPIO_PIN_0);
GPIODirModeSet (GPIO_Porte _BASE、GPIO_PIN_7、GPIO_DIR_MODE_OUT);
GPIODirModeSet (GPIO_PORTF_BASE、GPIO_PIN_0、GPIO_DIR_MODE_OUT);
//GPIOPadConfigSet (GPIO_Porte _BASE、GPIO_PIN_7、GPIO_Strength _2mA、GPIO_PIN_TYPE_OD);
//GPIOPadConfigSet (GPIO_PORTF_BASE、GPIO_PIN_0、GPIO_Strength _2mA、GPIO_PIN_TYPE_OD);
//PORTF 引脚1、2、3为输入
GPIOPinTypeGPIOInput (GPIO_PORTF_BASE、GPIO_PIN_1_GPIO_PIN_2 | GPIO_PIN_3);
//GPIODirModeSet (GPIO_PORTF_BASE、GPIO_PIN_1_GPIO_PIN_2 | GPIO_PIN_3、GPIO_DIR_MODE_HW);
GPIOPadConfigSet (GPIO_PORTF_BASE、GPIO_PIN_1|GPIO_PIN_2 | GPIO_PIN_3、GPIO_Strength _2mA、GPIO_PIN_TYPE_STD_WPU);
LCD_COMMAND (0x01);//清除屏幕
延迟(50);
LCD_Init();
LCD_String_Display ("欢迎...");
LCD_COMMAND (0x01);//清除屏幕
延迟(50);
//将行引脚设为低电平
GPIOPinWrite (GPIO_Porte _BASE、GPIO_PIN_7、0);
GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_0、0);
//将列引脚设为高电平
//GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_1 | GPIO_PIN_2| GPIO_PIN_3、0x0E);
//GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_1、0);
//GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_2、0);
//GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_3、0);
//GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_1、0);
while (1)
{
//检查任何按键是否被按下/列中的任何一个变为低电平,然后进入该功能并检查按哪个行键
//uint8_t A =GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_1);
//uint8_t B =GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_2);
//uint8_t C =GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_3);
if (GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_1)=0x00)//check 列1为低电平、其他列为1
{
//lcd_data ('1');
key_detect (1);
延迟(50);
}
否则、如果(GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_2)=0x00)//检查列2为低电平且其他列为一列
{
//lcd_data ('2');
key_detect (2);
延迟(50);
}
否则、如果(GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_3)=0x00)//检查第3列为低电平且其他列为1
{
//lcd_data ('3');
KEY 检测(3);
延迟(50);
}
否则、如果(((GPIOPINREAD (GPIO_PORTF_BASE、GPIO_PIN_1)!=0x0C)&&(GPIOPINREAD (GPIO_PORTF_BASE、GPIO_PIN_2)!=0x0A)&&(GPIOPINREAD (GPIO_PORTF_BASE、GPIO_PIN_3)!=0x06)))))
{
LCD_COMMAND (0x01);//清除屏幕
LCD_COMMAND (0xC0);
LCD_String_Display ("按键未按下...");
}
}
}
我遵循的过程是、
在初始阶段将 ROW 作为输出、将 COLUN 作为输入、并将 ROW 引脚作为逻辑"低电平"、将 COLUN 作为"高电平"。
1.按"读取所有列"按钮,检查任何列是否为零。
2.找到列后,它将搜索行。
3.查找行时,我将使每个行处于高电平,并使列处于读取状态。
4.红色列为高则表示已按下行按钮
我对引脚配置有一点怀疑、因为第一行连接到 Porte PIN7、第二行连接到 PORTF pin0。 列引脚分别连接到同一 PORTF 引脚1、2、3。
我检查了行是否正在更改其状态,我发现 第一行是将其状态从高电平更改为低电平,但第二行不是。 它仅处于低电平状态。
我无法将行引脚更改为任何其他端口,该板已为我的项目设计。
请告诉我、是否有任何方法可以解决此问题。
期待快速回复...
此致、
Alphy