当前位置:文档之家› 矩阵LU分解求逆详细分析与C语言实现

矩阵LU分解求逆详细分析与C语言实现

矩阵LU分解求逆详细分析与C语言实现
矩阵LU分解求逆详细分析与C语言实现

题目要求

给定一个多维矩阵,实现该矩阵的求逆运算。

1、理论分析

矩阵的一种有效而广泛应用的分解方法是矩阵的LU 三角分解,将一个n 阶矩阵A 分解为一个下三角矩阵L 和一个上三角矩阵U 的乘积。所以首先对矩阵进行三角分解,这里采用Doolittle 分解,即分解为一个下三角矩阵(对角元素为1),和一个上三角矩阵的乘积。再进行相应的处理。

所以,矩阵求逆的算法流程可表述如下:

输输输输A

输输输LU 输输

L 输输输输U 输输输输

输输U 输输输输L 输

输输A 输输输输

U

L

图1 矩阵求逆流程图

1)进行LU 分解;

2)对分解后的L 阵(下三角矩阵)和U 阵(上三角矩阵)进行求逆;; 3)L 阵的逆矩阵和U 阵的逆矩阵相乘,即可求得原来矩阵的逆。即:

1111()A LU U L ----== (1)

1.1矩阵的LU 分解

若n 阶方阵

n

n n

C A *∈的各阶顺序主子式不等于零,即:

),,,2,1(,0212222111211n k akk

ak ak k a a a k a a a k

=≠=

? (2)

则A 的LU 分解A L U =?存在且唯一。

111111*********r n r rr rn n nr nn r n r rr rn n nr nn a a a A a a a a a a U U U L U U LU

L L U ??

??????==

????????????

????????

????=????

????

???????

?

(3)

由矩阵的乘法原理, 可推导出LU 分解的迭代算法

(4)

000

,(0,1,2,,1),i i a l i n u ==- (5)

1

1

11

,

(0,1,2,,1;,,1),

r rj ik kj

r k rj rj rk kj k rr

a l u u a l u l r n j r n --==-=

=-=-=-∑∑ (6)

00,(0,1,2,,1),

j j U a j n ==-

1

1

,

(0,1,2,,1;1,,1)

r ir ik kr

k ir rr

a l u l u r n i r n -=-=

=-=+-∑ (7)

矩阵的LU 分解是一个循环迭代的过程, U 矩阵是从第1行迭代到第n 行, 而L 矩阵则是从第1列迭代到第n 列, 且U 矩阵先于L 矩阵一个节拍。

1.2 L 矩阵和U 矩阵求逆

首先假设下三角矩阵L 的逆矩阵为l ,不失一般性,考虑4阶的情况,利用Ll I =,有:

(1)10000l L -= 11111l L -=,12222l L -=,1

3333l L -=;

(2)10001110();l l l L =- (3)200021102220();l l l L l L =-+ (4)3000311032203330()r r r L r L r L =-++ 。 从而求得下三角矩阵L 的逆矩阵R 式如下:

11,(),,0ii

j

ji ii jk ki k i l i j r r r l i j i j

-=+?=??

=-<

??>??

∑, (8)

上三角矩阵U 的逆矩阵可以由下式得到:。

1

1

,1

(),,0jj

i

ji jk ki k j jj u i j u U u i j u i j

-=+?=??=->

??<

??

∑, (9)

矩阵求逆是一个迭代的过程,依次循环, 迭代1n -次, 求出整个逆矩阵。其中U 矩阵的循环迭代时按行顺序,列倒序进行,L 矩阵的循环迭代按列顺序,行顺序进行,直到计算出整个矩阵的所有结果为止。

1.3 矩阵相乘

上三角矩阵U 的逆矩阵u 与下三角矩阵L 的逆矩阵l 相乘, 最终得到原始矩阵A 的逆矩阵111A U L ul ---==, 完成整个矩阵求逆的过程。对于n 阶矩阵相乘的迭代形式可表示如下:

1

[][][][][][]n

k j A i j u i k l k j -==?∑ (10)

1.4 实例分析

例:给定一4阶矩阵4

21

58

721048366

849A ??

???

?=??

??

??,通过LU 分解求逆矩阵1A -。 解:算法过程为:

1111()A L U U L u l ----=?=?=?, 第一步:求LU 矩阵

00000102

0310

1111121320212222

2330

31

32

3333000000000000L U U U U L

L U U U L U L L L U U L L L L U →

????

?????????=↓?????????????

通过(4)~(7)式可逐步进行矩阵L 和U 中元素的计算,如下所示:

001122330000010102020303102030102030000000111110011212100213131003()

1,(U )

4,2,1,5,(L )846

2,1, 1.5,444

(U )

7223,2210,10L L L L L U a U a U a U a a a a L L L U U U U a L U U a L U U a L U =============

=========-=-?==-=-?==-=计算的对角的第一行的第一列的第二行2121200111313130011122222002211223232003211332323002311222250,(L )11

()(812)23115

()(8 1.52)33

U 311202,615201,L 11()(412L a L U U L a L U U U a L U L U U a L U L U L a L U L U U -?==-=?-?==

-=?-?==--=-?-?==--=-?-?==

--=?-的第二列(的第三行)

(的第三列)33333003311332235

.510) 1.25,3

U 5

9 1.550 1.2510.25;3

U a L U L U L U ?-?==---=-?-

?-?=(的第四行)

经迭代计算,最后得到L 和U 矩阵为:

第二步:求L 和U 矩阵的逆u ,l

11,;u U l L --==

(1)求U 矩阵的逆

1

1

00010203000102

031112

1311121322232223333342

1

500030000000021000

000

00

00.25U U U U u u u u U U

U u u u u U U u u U u --????

?????????

??

???===↑??????

?

?????

??????

由式(9)可得矩阵U 的逆的各元素计算如下:

000011010111110022122222110112022200332333332211

(1),

4

111111

(2)()(2),

3436111

(3)0.5()(00.5)0

311

()(2010.5)0.1254

111(4)4()(14)2

2u U u u U u U U u U u U U U u U u U u U u U U =====-=-?=-===-=-?==-

+=-?+?=-===-=-?=-12022313,,u u ,u u 12231333110113022303330011

()(0(2)04)03

11

()(201(2)54) 4.54

U u U u U U u U u U u U =-+=-?-+?==-

++=-?+?-+?=-03u

(2)求L 矩阵的逆

1

1

000010111011202122202122303132333031

32330000

01

000000021000012101.50.6667 1.25

1L l L L l l l L L L l l l L L L L l l l l --????

???????????

???===↓????

??

????????????

由(8)式可得L 矩阵的逆的各元素计算如下

001010002020002110303000311032201121113131113221223222(1)1,2,()3,

5

()(1.51(2)13) 1.916667

3

(2)2,()0.83333(3)() 1.251;

l l L l l L l L l l L l L l L l l l L l l L l L l l l L l l ==-=-=-+==-++=-?+?-+?≈-=-=-=-+==-=-=213233=1,=1,(4)

所以得到L 和U

的逆矩阵为:

(3)求A 的逆矩阵

由式(10)可计算得到矩阵A 的逆,如下:

10.250.1666670.125 4.5100

000.33333002100000.5232100

004 1.9166670.83333 1.2518.833334 3.66667 5.5 4.50.666670.33333005.333333 2.66667327.666667 3.333335

4A u l

-=?---????????-????=?????--?

??

?--????

--???-?

=?--?

--??

????

由程序计算出的结果如下:

2、C 语言程序设计及测试 2.1 算法c 程序实现

#include #include #define N 4 void main() { float a[N][N];

float L[N][N],U[N][N],out[N][N], out1[N][N];

float r[N][N],u[N][N]; memset( a , 0 , sizeof(a)); memset( L , 0 , sizeof(L)); memset( U , 0 , sizeof(U));

memset( r , 0 , sizeof(r)); memset( u , 0 , sizeof(u)); int n=N; int k,i,j; int flag=1; float s,t;

////////////////////input a matrix//// printf("\ninput A="); for(i=0;i

//////////////////figure the input

matrix//////////////////////////

printf("输入矩阵:\n");

for(i=0;i

{

for (j = 0; j < n; j++)

{

printf("%lf ", a[i][j]);

}

printf("\n");

}

for(j=0;j

a[0][j]=a[0][j]; //计算U矩阵的第一行

for(i=1;i

a[i][0]=a[i][0]/a[0][0]; //计算L矩

阵的第1列

for(k=1;k

{

for(j=k;j

{

s=0;

for (i=0;i

s=s+a[k][i]*a[i][j]; //累加

a[k][j]=a[k][j]-s; //计算U矩阵的其

他元素

}

for(i=k+1;i

{

t=0;

for(j=0;j

t=t+a[i][j]*a[j][k]; //累加

a[i][k]=(a[i][k]-t)/a[k][k]; //计算L矩阵的其他元素

}

}

for(i=0;i

for(j=0;j

{ if(i>j)

{ L[i][j]=a[i][j]; U[i][j]=0;}//如果i>j,说明行大于列,计算矩阵的下三角部分,得出L的值,U的//为0

else

{ U[i][j]=a[i][j];

if(i==j) L[i][j]=1; //否则如果i

else L[i][j]=0;

}

}

if(U[1][1]*U[2][2]*U[3][3]*U[4][4]==0 ){

flag=0;

printf("\n逆矩阵不存在");}

if(flag==1){

/////////////////////求L和U矩阵的逆

for (i=0;i

for (k=i-1;k>=0;k--)

{s=0;

for (j=k+1;j<=i;j++)

s=s+U[k][j]*u[j][i];

u[k][i]=-s/U[k][k];//迭代计算,按列倒序依次得到每一个值,

}

}

for (i=0;i

{r[i][i]=1; //对角元素的值,直接取倒数,这里为1

for (k=i+1;k

{for (j=i;j<=k-1;j++)

r[k][i]=r[k][i]-L[k][j]*r[j][i]; //迭代计算,按列顺序依次得到每一个值

}

}

/////////////////绘制矩阵LU分解后的L和U 矩阵///////////////////////

printf("\nLU分解后L矩阵:");

for(i=0;i

{ printf("\n");

for(j=0;j

printf(" %lf",L[i][j]);

}

printf("\nLU分解后U矩阵:");

for(i=0;i

{ printf("\n");

for(j=0;j

printf(" %lf",U[i][j]);

}

printf("\n");

////////绘制L和U矩阵的逆矩阵printf("\nL矩阵的逆矩阵:");

for(i=0;i

{ printf("\n");

for(j=0;j

printf(" %lf",r[i][j]);

}

printf("\nU矩阵的逆矩阵:");

for(i=0;i

{ printf("\n");

for(j=0;j

printf(" %lf",u[i][j]);

}

printf("\n");

//验证将L和U相乘,得到原矩阵printf("\nL矩阵和U矩阵乘积\n"); for(i=0;i

{

for(j=0;j

{out[i][j]=0;}

}

for(i=0;i

{

for(j=0;j

{

for(k=0;k

{out[i][j]+=L[i][k]*U[k][j];}

}

}

for(i=0;i

{

for(j=0;j

{

printf("%lf\t",out[i][j]);

}

printf("\r\n");

}

//////////将r和u相乘,得到逆矩阵printf("\n原矩阵的逆矩阵:\n");

for(i=0;i

{

for(j=0;j

{out1[i][j]=0;}

}

for(i=0;i

{

for(j=0;j

{

for(k=0;k

{out1[i][j]+=u[i][k]*r[k][j];}

}

}

for(i=0;i

{

for(j=0;j

{

printf("%lf\t",out1[i][j]);

}

printf("\r\n");

}

}

}

2.2 数据测试(1)非满秩矩阵1>、整数矩阵

2>、小数矩阵

(2)满秩矩阵1> 整数矩阵的测试

2> 小数矩阵的测试

电子琴C程序代码,四乘四矩阵键盘输入

电子琴C程序代码,四乘四矩阵键盘输入#include #define uchar unsigned char #define uint unsigned int sbit duan=P 2八6; sbit wei=P 2八7; sbit bee=P 2八3; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; uchar code tablewe[]={ 0x7f,0xbf,0xdf,0xef, 0xf7,0xfb,0xfd,0xfe}; uchar disp[16]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; // 在里面输入按下键值为0~15 对应要显示的第一位码值uchar disp1[16]={0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71,0x3f}; // 在里面输入按下键值为0~15 对应要显示的第二位码值unsigned char temp; unsigned char key; unsigned char i,j;

unsigned char STH0; unsigned char STL0; unsigned int code tab[]={ //63625, 63833, 64019, 64104, 64260, 64400, 64524 ,// 低音区:1 2 3 4 64580, 64685, 64778, 64820, 64898, 64968, 65030 ,// 中音区:1 2 3 4 5 65058, 65110, 65157, 65178, 65217, 65252, 65283 ,// 高音区:1 2 3 4 5 65297 ,// 超高音:1 }; // 音调数据表可改 void delay(uchar x) uchar y,z; for(y=x;y>0;y--) for(z=0;z<110;z++); void init() TMOD=0x01; ET0=1; EA=1; void display() { for(i=0;i<2;i++)

MSP430单片机的4X4矩阵键盘C语言程序

MSP430单片机的4X4矩阵键盘C语言程序 #include #define uchar unsigned char#define uint unsigned int uchar table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; void delay(unsigned int i) //延时子程序{while(i--);} uchar keyvalue(){ uchar key; uchar np10,np11,np12,np13; P1DIR=0x0f;//第一排P1OUT=~BIT3; delay(10); np10=P1IN&BIT4; if(np10==0) { key=0; } np11=P1IN&BIT5; if(np11==0) { key=1; } np12=P1IN&BIT6; if(np12==0) { key=2; } np13=P1IN&BIT7; if(np13==0) { key=3; } //第二行P1OUT=~BIT2; delay(10); np10=P1IN&BIT4; if(np10==0) { key=4; } np11=P1IN&BIT5; if(np11==0) { key=5; } np12=P1IN&BIT6; if(np12==0) { key=6; } np13=P1IN&BIT7; if(np13==0) { key=7; } //第三行P1OUT=~BIT1; delay(10); np10=P1IN&BIT4; if(np10==0) { key=8; } np11=P1IN&BIT5; if(np11==0) { key=9; } np12=P1IN&BIT6; if(np12==0) { key=10; } np13=P1IN&BIT7; if(np13==0) { key=11; } //第四行P1OUT=~BIT0; delay(10); np10=P1IN&BIT4; if(np10==0) { key=12; } np11=P1IN&BIT5; if(np11==0) { key=13; } np12=P1IN&BIT6; if(np12==0) { key=14; } np13=P1IN&BIT7; if(np13==0) { key=15; } P1OUT=0X00; return key; while(1) { if((P1IN&0X0F)==0x0f) break; }} void main(){ uchar key_value; WDTCTL=WDTPW+WDTHOLD; P1DIR=0X0F; P2DIR=0XFF; P2OUT=0XFF; while(1) { if((P1IN&0XF0)!=0XF0) { delay(100); if((P1IN&0XF0)!=0XF0) { delay(100); if((P1IN&0XF0)!=0XF0) { key_value=keyvalue(); } } } P2OUT=~key_value; }} tips:感谢大家的阅读,本文由我司收集整编。仅供参阅!

51单片机矩阵键盘的C语言程序与分析

51单片机矩阵键盘的C语言程序与分析 2009-10-17 19:25 学习51单片机矩阵键盘时,我有点迷乱了,不知道是怎样处理的,经过仔细分析电路,然后终于明白其中的原理,这样的话,再看程序,就是那样的简单了。。 首先看一下电路图是怎样连接的,我买的开发板上是AT89S52单片机,矩阵键盘在P3口。接法如下图: 当然上面的图的意思是P3.1~P3.3 跟P3.4~P3.7不一样的,他们是相互连接(当按下键时),组成4*4=16个键的。

如果给P3一个扫描初值的话:如0x0F ,则没有键按下时为: P3.1~P3.3为1,P3.4~P3.7为0。 如果有键按下,则情况发生变化:高电平接入低电平:如P3.3与P3.7连接的键按下,则P3.3与P3.7为0,即接地了。 则P3此时为:0000 0111,这时如果用P3&0x0F,则高四位为0,低四位保留,可以得到低四位的内容了。 通过去抖操作,即一个delay,可以得到低四位内容。这里设为:h=P3&0x0F; 如果再得到高四位内容,则可以组成一个数,来定位哪个键了。 用P3=h|0xF0;这会出现什么情况呢?1|0=1 1| 1 =1,这里难道高四位全置1 吗?不是的,当赋值后,如果有键按下的话,P3高四位不会全为1111,被拉到0了。如P3.3与P3.7连接的键按下,则P3.3与P3.7为0,即接地了。即:0111 0111,&F0之后,得到0111 0000,这样的话,我们得到高四位的值了, 用高四位+低四位,就可以得到一个数值,确定一个键。 下面看看人家编写的程序,相信不是太难了吧。 //keyboard.c 这里的行与列的扫描,也就是把字节的8位,高四位与低四位分开来,从而确定坐标。 //行列扫描程序,可以自己定义端口和扫描方式,这里做简单介绍 #include //包含头文件 #define uchar unsigned char #define uint unsigned int unsigned char const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F,数码管来显示按下键的值。 uchar keyscan(void); //主要的矩阵键盘扫描函数。 void delay(uint i); void main() { uchar key; P2=0x00;//1数码管亮按相应的按键,会显示按键上的字符 while(1) { key=keyscan();//调用键盘扫描,

矩阵键盘程序c程序,51单片机.

/*编译环境:Keil 7.50A c51 */ /*******************************************************/ /*********************************包含头文件********************************/ #include /*********************************数码管表格********************************/ unsigned char table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x 8E}; /**************************************************************************** 函数功能:延时子程序 入口参数: 出口参数: ****************************************************************************/ void delay(void) { unsigned char i,j; for(i=0;i<20;i++) for(j=0;j<250;j++); } /**************************************************************************** 函数功能:LED显示子程序 入口参数:i 出口参数: ****************************************************************************/ void display(unsigned char i) { P2=0xfe; P0=table[i]; } /**************************************************************************** 函数功能:键盘扫描子程序 入口参数: 出口参数: ****************************************************************************/ void keyscan(void) { unsigned char n; //扫描第一行 P1=0xfe;

单片机矩阵键盘检测程序并用数码管显示c语言程序

#include #define uint16 unsigned int #define uint8 unsigned char //控制数码管段选锁存口 sbit P3_7=P3^7; //共阴数码管显示 uint8 code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71,0}; uint8 temp; uint16 num; //延时子函数 void delay(uint16 z) { uint16 x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } //子函数声明 uint8 keyscan(); void display(uint8);

void main() { num=17; while(1) { display(keyscan()); } } void display(uint8 num1) { P2=0xf8; P3_7=1; P0=table[num1-1]; P3_7=0; } uint8 keyscan() { P1=0xfe; temp = P1;

temp=temp&0xf0; while(temp!=0xf0) { delay(5); temp=P1; temp=temp&0xf0; while(temp!=0xf0) { temp=P1; switch(temp) { case 0xee:num=1;break; case 0xde:num=2;break; case 0xbe:num=3;break; case 0x7e:num=4;break; default:break; } while(temp!=0xf0)//检测按键是否放开 { temp=P1; temp=temp&0xf0; }

基于C51单片机矩阵键盘控制蜂鸣器的应用

学校代码 10126 学号科研创新训练论文 题目基于C51单片机的蜂鸣器和流水灯的 应用 院系内蒙古大学鄂尔多斯学院 专业名称自动化 年级 2013 级 学生姓名高乐 指导教师高乐奇 2015年06月20日

基于C51单片机的蜂鸣器和流水灯的应用 摘要 当今时代是一个新技术层出不穷的时代,在电子领域尤其是自动化智能控制领域,传统的分立元件或数字逻辑电路构成的控制系统,正以前所未见的速度被单片机智能控制系统所取代。单片机具有体积小、功能强、成本低、应用面广等优点,可以说,智能控制与自动控制的核心就是单片机。本文介绍了单片机的发展及应用,和基于单片机的蜂鸣器和流水灯的知识及应用,还介绍了此次我所设计的课题。 关键词:C-51单片机,控制系统,流水灯,蜂鸣器,程序设计

The application of buzzer and flowing water light based on C51 MCU Author:GaoLe Tutor:GaoLeQi Abstract This age is a new technology emerge in endlessly era, in the electronic field especially automation intelligent control field, the traditional schism components or digital logic circuit, is composed of control system with unprecedented speed was replaced by micro-controller intelligent control system. SCM has small, strong function, low cost, etc, it can be said that wide application, intelligent control and automatic control core is the micro-controller.This article introduces the MCU development and application,the knowledge and application of buzzer and flowing water light based on MCU,then introduces the task I have designed this time. Keyword:C51 micro-controller,control system,flowing water light,buzzer ,programming

STM32-矩阵键盘程序4×4

/*--------------------------------------------------------------------------------------* 矩阵键盘驱动 * 文件: keyboard.c * 编写人:LiuHui * 描述:扫描4x4 矩阵键盘输入,并返回键值 * 适用范围:驱动采用ST3.5 库编写,适用于STM32F10x 系列单片机 * 所用引脚:PA0-PA7 * 编写时间:2014 年5 月20 日 --------------------------------------------------------------------------------------*/ #include "stm32f10x.h" #include "keyboard.h" #include "dealy.h" /*--------------------------------矩阵键盘初始化----------------------------------------* 功能:初始化stm32 单片机GPIO //PA0-PA7 * 参数传递: * 输入:无 * 返回值:无 --------------------------------------------------------------------------------------*/ void KeyBoard_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3); GPIO_ResetBits(GPIOA, GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7); } /*------------------------------矩阵键盘扫描--------------------------------------------* 功能:扫描矩阵键盘,并返回键值 * 参数: * 输入:无 * 返回:有键按下返回该键值 * 无键按下时则返回0 --------------------------------------------------------------------------------------*/ u8 Read_KeyValue(void) { u8 KeyValue=0; if((GPIO_ReadInputData(GPIOA)&0xff)!=0x0f) {

矩阵键盘单个数码管显示C语言程序

#include #define uchar unsigned char #define uint unsigned int uchar code_h,code_l; //定义行扫描码,列检测数据uchar tmp,keyvalue; //定义接收键值 /*函数说明*/ void delay(void); uchar keyscan(); /*主函数*/ void main () //键值处理 { while(1) { tmp=keyscan();//调用键盘扫描程序 switch(tmp) { case 0x11: P0=0x3f; break; //0 case 0x12: P0=0x06; break; //1 case 0x14: P0=0x5b; break; //2 case 0x18: P0=0x4f; break; //3 case 0x21: P0=0x66; break; //4 case 0x22: P0=0x6d; break; //5 case 0x24: P0=0x7d; break; //6 case 0x28: P0=0x07; break; //7 case 0x41: P0=0x7f; break; //8 case 0x42: P0=0x67; break; //9 case 0x44: P0=0x77; break; //a case 0x48: P0=0x7c; break; //b case 0x81: P0=0x39; break; //c case 0x82: P0=0x5c; break; //d case 0x84: P0=0x79; break; //e case 0x88: P0=0x71; break; //f case 0x00: ; break; default:P0=0x00; } delay(); } } /*延时函数*/ void delay(void) {uchar i; for(i=0;i<200;i++){} } /*键盘扫描函数*/ uchar keyscan(void)

矩阵键盘编程

矩阵键盘编程 键盘结构与类型 独立式按键键盘由若干独立式按键组成。独立式按键指每个按键作为一位占用一根I/O口线,直接用I/O口线构成单个按键电路。独立式按键键盘可分为中断方式和查询方式两种。独立式按键键盘优点是配置灵活,软件结构简单,操作速度快;缺点是按键多时I/O口浪费较大,故只在按键数目不多时采用。 行列式键盘(矩阵式键盘)用I/O口线组成行、列结构,按键设置在行列的交点上。在按键较多时可节省I/O口线,如4×8行列结构可构成32个键的键盘。 行列式键盘键输入过程及接口软件应解决的任务 键开关状态的可靠输入主要应解决抖动问题。 对按键编码以便识别对按键编码,使不同的按键有不同的键值或键号。 按键状态的输入方式有中断方式与查询方式两种。 编制键盘程序检测有无按键按下、去抖动、按键信息的逻辑处理、 输出确定的键号等。 行列式键盘(矩阵式键盘)及接口程序设计 行列式键盘的结构及键值赋值方法 键盘行线的一端经上拉电阻接+5v电源,另一端接单片机的输入口(因而各输入口均被钳位于高电平)。各列线的一端接单片机的输出口,另一端悬空。按键设置在行列线的交点上,行、列线分别连接到按键的两端,按键按下则相应交点的行列线接通。由图可见,矩阵式键盘接口的设计思想是把键盘既作为输入设备又作为输出设备对待的。 为了让CPU能识别是哪个按键被按下,必须给每个按键都分配一个键号(一般以十进制数表示)。例如,4×4列矩阵式键盘共16个按键,键号依次按顺序排列为0~15。 对行列式键盘的每个按键,还有一个更重要的概念:键值或者说键码。键值是一个可表征按键状态的8位数据,不同的按键有不同的键值。按键后根据键值便能转到相应的键处理子程序,实现键盘的数据输入功能或命令处理功能。 同一个按键的键值和键号可以相同,也可以不相同,这主要取决于键盘的结构与采用的编码方法。 对行列式键盘来说,识别被按键的位置也就是找出被按键所在行和列的坐标值。对于4行×4列行列式键盘,被按键所在行和列的坐标值为两个4位数据;

电子琴C程序代码,四乘四矩阵键盘输入

电子琴C程序代码,四乘四矩阵键盘输入#include #define uchar unsigned char #define uint unsigned int sbit duan=P2^6; sbit wei=P2^7; sbit bee=P2^3; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; uchar code tablewe[]={ 0x7f,0xbf,0xdf,0xef, 0xf7,0xfb,0xfd,0xfe}; uchar disp[16]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; // 在里面输入按下键值为0~15对应要显示的第一位码值 uchar disp1[16]={0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71,0x3f}; // 在里面输入按下键值为0~15对应要显示的第二位码值 unsigned char temp; unsigned char key; unsigned char i,j;

unsigned char STH0; unsigned char STL0; unsigned int code tab[]={ //63625, 63833, 64019, 64104, 64260, 64400, 64524 ,//低音区:1 2 3 4 5 6 7 64580, 64685, 64778, 64820, 64898, 64968, 65030 ,//中音区:1 2 3 4 5 6 7 65058, 65110, 65157, 65178, 65217, 65252, 65283 ,//高音区:1 2 3 4 5 6 7 65297 ,//超高音:1 }; //音调数据表可改 void delay(uchar x) { uchar y,z; for(y=x;y>0;y--) for(z=0;z<110;z++); } void init() { TMOD=0x01; ET0=1; EA=1; } void display() { for(i=0;i<2;i++)

4-4矩阵键盘控制16个LED灯

一、任务说明 本次的任务是利用51单片机设计一个4*4矩阵键盘输入系统,用16个发光二级管对应16个不同的按键。每按下一个按键对应的发光二极管就亮。 矩阵式键盘又称行列键盘,它是用N条I/O线作为行线,N条I/O线作为列线组成的键盘。在行线和列线的每个交叉点上设置一个按键。这样键盘上按键的个数就为N*N个。这种行列式键盘结构能有效地提高单片机系统中I/O口的利用率。 最常见的键盘布局如图1所示。一般由16个按键组成,在单片机中正好可以用一个P口实现16个按键功能,这也是在单片机系统中最常用的形式,本设计就采用这个键盘模式。 图1 键盘布局 利用单片机的并行口P1连接4×4矩阵键盘,并以单片机的P1.0-P1.3各管脚作输入线,以单片机的P1.4-P1.7各管脚作输出线;利用P2、P3口控制灯1-灯16,。用Proteus绘制其电路原理图(附录一)。此任务用到了AT89C51芯片,还用到了晶体振荡器、按钮开关、发光二级管以及一些电阻。 这次任务中采用C语言编写程序,在编译过程中设置成自动产生HEX文件,将此文件导入AT89C51中,即可实现相应的功能。 二、原理图绘制说明 电路原理图的设计与绘制是整个电路设计的基础,设计一个电路原理图的工作包括:设置电路图图纸的大小,规划电路图的总体布局,在图纸上放置元器件并对元器件进行调整,进行布线和整体布局,最后保存并打印输出等几个步骤。 安装完Proteus后,运行ISIS 7 Professional,在原理图编辑窗口绘制电路图,在该界面下还有预览窗口和元件列表区,在左侧的工具箱中还有模型选择工具栏,方向工具栏及仿真按钮等工具。其具体的使用步骤如下: 1.运行该软件后,新建一个设计文件,设置图纸大小。选择界面如图2所示。

矩阵键盘C语言程序

/***************************************************************************** *** * 描述: * * 矩阵键盘数码管显示键值 * * 排线连接方法:JP8(P1)与JP4(矩阵键盘接口)连接 P0与JP3(静态数码管)连接 * * 矩阵键盘定义: * * P1.1-P1.4为列线,P1.4-P1.7为行线 * * 喇叭接P1.5口矩阵键盘P1口, * * 注意:请将JP165短路冒断开 * ****************************************************************************** **/ #include #include #define uchar unsigned char #define uint unsigned int uchar dis_buf; //显示缓存 uchar temp; uchar key; //键顺序吗 void delay0(uchar x); //x*0.14MS #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();}; // 此表为 LED 的字模 0 1 2 3 4 5 6 7 8 9 a b c d e f unsigned char code LED7Code[] = {~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F,~0x77,~0x7C,~0x39 ,~0x5E,~0x79,~0x71}; /*************************************************************/ /* */ /* 延时子程序 */ /* */ /*************************************************************/

51单片机的矩阵按键扫描的设计C语言程序

//-----------------------函数声明,变量定义 -------------------------------------------------------- #include #define KEY P1 //-----------------------变量声明 --------------------------------------------------------------------- void program_SCANkey(); //程序扫描键盘,供主程序调用 void delay(unsigned int N) ;//延时子程序,实现(16*N+24)us的延时 bit judge_hitkey(); //判断是否有键按下,有返回1,没有返回0 unsigned char scan_key(); //扫描键盘,返回键值(高四位代表行,低四位代表列) void key_manage(unsigned char keycode); //键盘散转 void manage_key1(void); //按键1处理程序 void manage_key2(void); //按键2处理程序 void manage_key3(void); //按键3处理程序 void manage_key4(void); //按键4处理程序 //...........每个按键对应一个处理程序,这里 //-------------------------------- ------------------------------------------------------------------ // 函数名称: program_SCANkey // 函数功能:程序扫描键盘, // 有键按下完成按键处理,无键按下直接返回 //-------------------------------------------------------------------------------------------------- void program_SCANkey() { unsigned char key_code; if(judge_hitkey()) //判断是否有键按下 { delay(1000); //延时20ms左右,消除抖动干扰 if(judge_hitkey()) //判断是否有效按键 { key_code=scan_key(); while(judge_hitkey()); //等待按键释放 key_manage(key_code); //键盘扫描、键盘散转、按键处理 } } } //-------------------------------- ------------------------------------------------------------------ // 函数名称: delay // 入口参数: N // 函数功能:延时子程序,实现(16*N+24)us的延时

51单片机矩阵键盘按键C语言程序

#include #define uchar unsigned char #define uint unsigned int uchar smg_du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39, 0x5e,0x79,0x71} ; uchar smg_we[]={0x08,0x18,0x28,0x38,0x48,0x58,0x68,0x78} ; //有一篇74HC573必须为高电平 //*************************8 //12M频率下大约50US延时 //************************** void delay_50us(uint t){uchar j; for(;t>0;t--) for(j=19;j>0;j--) ;}void delay_50ms(uint t){uchar j; for(;t>0;t--) for(j=6245;j>0;j--);}/* 这个程序可以不用松手检测,因为我们程序首选判断键是否按下 然后发现按下后我们延时5MS,然后再检测。确实是按下啦。我们再执行在第二个循环假如我们继续检测,那么消耗时间10MS这个短时间中 我们的按键已经松手啦。不会在执行后面的。 */

void main(){uchar key_l,key_h; uchar key; while (1){P3=0xf0; // 首先给P3 口赋值 key_l=P3;// 从p3 口读一个数据到key_l key_l=key_l&0xf0; if(key_l!=0xf0) // 如果不等于的话,说明有按键按下去{delay_50us (100);// 稍微延时一下 if(key_l!=OxfO){key_l二P3&0xfO;//111OOO 再读一次P3 的值然后和OxfO 相与key_l=key_l|0x0f;//111011 P3=key_l;//在把key_l 的值送给P3 口 //此时P3 口的值为111011,而正在此时我们把键按下啦因此按下的键为 1110 与111011 // 相与还是1110; key_h=P3; 〃再读一次P3 口,键还是按下,可以得到行的值。 key_h=key_h&0x0f; //001110 key_l=key_l&0xf0; //111000 key=key_l+key_h;//1110}} switch(key){case 0xee: P1=smg_du[0];break;

矩阵键盘逐行扫描及反转扫描c程序

矩阵键盘: unsigned char read_key() { unsigned char h,l; P1=0x0f; h=P1&0x0f; P1=0xf0; l=P1&0xf0; switch(h+l) { case 0x7e:return(0);break; case 0x7d:return(1);break; case 0x7b:return(2);break; case 0x77:return(3);break; case 0xbe:return(4);break;

case 0xbd:return(5);break; case 0xbb:return(6);break; case 0xb7:return(7);break; case 0xde:return(8);break; case 0xdd:return(9);break; case 0xdb:return(10);break; case 0xd7:return(11);break; case 0xee:return(12);break; case 0xed:return(13);break; case 0xeb:return(14);break; case 0xe7:return(15);break; default :return(255); } } ////////////////////////////////////////////////////////////// unsigned char read_key2() { unsigned char a,i,k=0xfe; for(i=0;i<4;i++) { P1=k; if((P1&0xf0)!=0xf0) { switch(P1&0xf0) { case 0x70:a=(i<<2)+1;break;//为了加快执行速度,i*4写为i<<2 case 0xb0:a=(i<<2)+2;break; case 0xd0:a=(i<<2)+3;break; case 0xe0:a=(i<<2)+4;break; default:a=0; } return(a); } k=k<<1|0x01; } return(0); }

基于msc51单片机实现的四位4乘4矩阵键盘计算器的C语言程序及其PROTUES电路和仿真_课程设计报告

单片机原理及接口技术 课程设计报告设计题目:计算器设计 信息与电气工程学院 二零一三年七月

计算器设计 单片机体积小,功耗小,价格低,用途灵活,无处不在,属专用计算机。是一种特殊器件,需经过专门学习方能掌握应用,应用中要设计专用的硬件和软件。近年来,单片机以其体积小、价格廉、面向控制等独特优点,在各种工业控制、仪器仪表、设备、产品的自动化、智能化方面获得了广泛的应用。与此同时,单片机应用系统的可靠性成为人们越来越关注的重要课题。影响可靠性的因素是多方面的,如构成系统的元器件本身的可靠性、系统本身各部分之间的相互耦合因素等。其中系统的抗干扰性能是系统可靠性的重要指标。 数学是科技进步的重要工具,数据的运算也随着科技的进步越发变得繁琐复杂,计算器的出现可以大大解放人在设计计算过程中的工作量,使计算的精度、速度得到改善,通过msc51单片机,矩阵键盘和LED数码管可以实现简单的四位数的四则运算和显示,并当运算结果超出范围时予以报错。 注:这一部分主要描述题目的背景和意义,对设计所采取的主要方法做一下简要描述。字数不要太多,300-500字。 另注:本文要当做模板使用,不要随意更改字体、字号、行间距等,学会使用格式刷。文中给出的各项内容都要在大家的报告中体现,可采用填空的方式使用本模板。 1. 设计任务 结合实际情况,基于AT89C51单片机设计一个计算器。该系统应满足的功能要求为: (1) 实现简单的四位十进制数字的四则运算; (2) 按键输入数字,运算法则; (3) LED数码管移位显示每次输入的数据和运算结果; (4) 当运算结果超出范围时实现报错。 主要硬件设备:AT89C51单片机、LED数码管、矩阵键盘。 注:这一部分需要写明系统功能需求,用到的主要硬件(参考实验箱的说明书)。

44矩阵键盘扫描C程序(C51)

#include #include #define uchar unsigned char #define uint unsigned int uchar dis_buf; //显示缓存 uchar temp; uchar key; //键顺序吗 void delay0(uchar x); //x*0.14MS #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();}; // 此表为LED 的字模0 1 2 3 4 5 6 7 8 9 a b c d e f unsigned char code LED7Code[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71}; /*************************************************************/ /* */ /* 延时子程序*/ /* */ /*************************************************************/ void delay(uchar x) { uchar j; while((x--)!=0) { for(j=0;j<125;j++) {;} } } /*************************************************************/ /* */ /* 键扫描子程序(4*4 的矩阵) P2.4 P2.5 P2.6 P2.7为行*/ /* P2.0 P2.1 P2.2 P2.3为列*/ /* */ /*************************************************************/ void keyscan(void) { temp = 0; P2=0xF0; //高四位输入行为高电平列为低电平 delay(1); temp=P2; //读P2口 temp=temp&0xF0; //屏蔽低四位

矩阵键盘扫描的C语言实例

矩阵键盘扫描的C语言实例 1、按键扫描(线反转) //-------------------------------- ------------------------------------------------------------------ // 函数名称:program_SCANkey // 函数功能:程序扫描键盘, // 有键按下完成按键处理,无键按下直接返回 //-------------------------------------------------------------------------------------------------- void program_SCANkey() { unsigned char key_code; if(judge_hitkey()) //判断是否有键按下 { delay(1000); //延时20ms左右,消除抖动干扰 if(judge_hitkey()) //判断是否有效按键{ key_code=scan_key();//获取键值 while(judge_hitkey()); //等待按键释放 { } key_manage(key_code); //键盘扫描、键盘散转、按键处理} } } //-------------------------------------------------------------------------------------------------- // 函数名称:judge_hitkey // 函数功能://判断是否有键按下,有返回1,没有返回0 // 列判断,还可以用行判断。 //-------------------------------------------------------------------------------------------------- bit judge_hitkey() //判断是否有键按下,有返回1,没有返回0 { unsigned char scancode,keycode; scancode=0x0F; //开始设定P1.0~P1.3输出全1(初值)即表明无键闭合KEY=scancode; keycode=KEY; //读取P1.0~P1.3的真实状态,从而确定有没有键被按下if(keycode==0x0F) return(0); //全1则无键闭合 else return(1); //否则有键闭合 } //-------------------------------------------------------------------------------------------------- // 函数名称:scan_key

相关主题
文本预览
相关文档 最新文档