小弟已郁闷两天,底层驱动用的原子哥的SYS,USART,DELAY,用寄存器写的4X4矩阵键盘,按0键在数码管上显示0,以此类推。。软件仿真结果都正确,但就是实际出不来。以下附上原理图和主程序及矩阵键盘驱动。
原理图:
主程序:
#include <stm32f10x.h>
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "io.h"
#include "key4_4.h"
/*==================================================================================================*/
//LED控制位,共阳数码管,0亮
//数码管控制(位选四位,段选8位)共13位(有一位为LED灯控制位),17个状态
uint8_t seg[17][13]={
{1, 0,0,0,0, 1, 1,0,0,0,0,0,0}, //0
{1, 0,0,0,0, 1, 1,1,1,1,0,0,1}, //1
{1, 0,0,0,0, 1, 0,1,0,0,1,0,0}, //2
{1, 0,0,0,0, 1, 0,1,1,0,0,0,0}, //3
{1, 0,0,0,0, 1, 0,0,1,1,0,0,1}, //4
{1, 0,0,0,0, 1, 0,0,1,0,0,1,0}, //5
{1, 0,0,0,0, 1, 0,0,0,0,0,1,0}, //6
{1, 0,0,0,0, 1, 1,1,1,1,0,0,0}, //7
{1, 0,0,0,0, 1, 0,0,0,0,0,0,0}, //8
{1, 0,0,0,0, 1, 0,0,1,0,0,0,0}, //9
{1, 0,0,0,0, 1, 0,0,0,1,0,0,0}, //A
{1, 0,0,0,0, 1, 0,0,0,0,0,1,1}, //B
{1, 0,0,0,0, 1, 1,0,0,0,1,1,0}, //B
{1, 0,0,0,0, 1, 0,1,0,0,0,0,1}, //D
{1, 0,0,0,0, 1, 0,0,0,0,1,1,0}, //E
{1, 0,0,0,0, 1, 0,0,0,1,1,1,0}, //F
{1, 1,1,1,1, 1, 1,1,1,1,1,1,1}, //全灭
};
/*==================================================================================================*/
int main(void)
{
uint8_t i,key=16;
Stm32_Clock_Init(9); //系统时钟设置,外部高速时钟HSE,9倍频
Delay_Init(72); //延时初始化,设置在系统时钟下,必须始终初始化一致
IO_Init(); //初始化IO接口
while(1)//死循环
{
key=KEY_Scan(); //读取键盘信息
for(i=0;i<13;i++)
{
SER=seg[key];
SHCLK=1;
Delay_Us(1);
SHCLK=0;
Delay_Us(1);
}
STCLK=1;
Delay_Us(1);
STCLK=0;
Delay_Us(1);
}
}
矩阵键盘驱动源程序:
#include <stm32f10x.h>
#include "key4_4.h"
#include "delay.h"
/*===================================================================================================*/
void KEY_Init1(void)
{
RCC->APB2ENR|=0x2<<2; //使能PORTA.B时钟
GPIOA->CRL&=0x00000FFF; //清空PA3.4.5.6.7模式
GPIOA->CRL|=0x83333000; //设置PA7上拉/下拉输入,PA3.4.5.6推挽输出
GPIOB->CRL&=0xFFFFF000; //清空PB0.1.2模式
GPIOB->CRL|=0x00000888; //设置PB0.1.2上拉/下拉输入
GPIOA->ODR|=1<<7; //PA7上拉
GPIOB->ODR|=0x7<<0; //PB0.1.2上拉
// GPIOA->ODR|=0xf<<3; //PA3.4.5.6置高
}
void KEY_Init2(void)
{
RCC->APB2ENR|=0x2<<2; //使能PORTA.B时钟
GPIOA->CRL&=0x00000FFF; //清空PA3.4.5.6.7模式
GPIOA->CRL|=0x38888000; //设置PA7推挽输出,PA3.4.5.6上拉/下拉输入
GPIOB->CRL&=0xFFFFF000; //清空PB0.1.2模式
GPIOB->CRL|=0x00000333; //设置PB0.1.2推挽输出上拉/下拉输入
GPIOA->ODR|=0xf<<3; //PA3.4.5.6上拉
// GPIOA->ODR|=1<<7; //PA7置高
// GPIOB->ODR|=0x7<<0; //PB0.1.2置高
}
/*==================================================================================================*/
uint8_t KEY_Scan(void)
{
uint8_t key;
uint8_t temp=0;
KEY_Init1();
//行为高电平,列为低电平
GPIOA->ODR&=~(0xf<<3); //PA3.4.5.6置低
Delay_Us(1);
if(KEY_H1==0) temp=1;
if(KEY_H2==0) temp=2;
if(KEY_H3==0) temp=4;
if(KEY_H4==0) temp=8;
if(temp==1) // PA7被拉低
key=0;
else
if(temp==2) // PB0被拉低
key=4;
else
if(temp==4) // PB1被拉低
key=8;
else
if(temp==8) // PB2被拉低
key=12;
else
key=16;
KEY_Init2();
temp=0;
//列为高电平,行为低电平
GPIOA->ODR&=~(1<<7); //PA7置低
GPIOB->ODR&=~(0x7<<0); //PB0.1.2置低
Delay_Us(1);
if(KEY_L1==0) temp=1;
if(KEY_L2==0) temp=2;
if(KEY_L3==0) temp=4;
if(KEY_L4==0) temp=8;
if(temp==1) // PA6被拉低
key=key;
else
if(temp==2) // PA5被拉低
key=key+1;
else
if(temp==4) // PA4被拉低
key=key+2;
else
if(temp==8) // PA3被拉低
key=key+3;
else
key=16;
return key;
}
矩阵键盘驱动头文件程序:
#ifndef __KEY4_4_H
#define __KEY4_4_H
#include "sys.h"
/*==================================================================================================*/
//矩阵键盘行列接口,H A7,PB0.1.2 L A3.4.5.6
#define KEY_L4 PAin(3) //PA3
#define KEY_L3 PAin(4) //PA4
#define KEY_L2 PAin(5) //PA5
#define KEY_L1 PAin(6) //PA6
#define KEY_H1 PAin(7) //PA7
#define KEY_H2 PBin(0) //PB0
#define KEY_H3 PBin(1) //PB1
#define KEY_H4 PBin(2) //PB2
/*==================================================================================================*/
//void KEY_Init1(void);//按键1初始化
//void KEY_Init2(void);//按键2初始化
uint8_t KEY_Scan(void); //按键扫描函数
#endif
请各位大神看看。。。郁闷啊!!软件仿真明明都对的。。找不出问题 |