程序1.docx
《程序1.docx》由会员分享,可在线阅读,更多相关《程序1.docx(36页珍藏版)》请在冰豆网上搜索。
![程序1.docx](https://file1.bdocx.com/fileroot1/2023-2/24/1eac3921-c407-416e-b633-9fc35cdc2793/1eac3921-c407-416e-b633-9fc35cdc27931.gif)
程序1
目录
目录1
图1.102
LM3245
LM386集成功率放大器6
CM12864-127
51单片机带字库12864液晶动态汉字显示11
单片机课程设计报告——电子琴13
音频放大器:
19
4*4矩形式键盘原理图22
图1.10
ORG0000H
LJMPMAIN
ORG0040H
MAIN:
MOVA,#FEH
LOOP:
MOVP2,A
LCALLD01S
RLA
AJMPLOOP
D01S:
MOVR6,#100
D10mS:
MOVR5,#40
DL:
MOVR4,#123
NOP
DJNZR4,$
DJNZR5,DL
DJNZR6,D10mS
RET
END
硬件双机通信:
ORG0000H
LJMPMAIN
ORG0023H
LJMPSINT
ORG0040H
MAIN:
MOVSP,#5FH
MOVTMOD,#20H
MOVTH1,#FDH
MOVTL1,#FDH
MOVPCON,#00H
SETBTR1
MOVSCON,#50H
SETBEA
SETBES
SJMP$
SINT:
CLRRI
MOVA,SBUF
MOVP2,A
INCA
MOVSBUF,A
JNBTI,$
CLRTI
RETI
END
独立式按键与LED显示图4.10
TEMPEQU30H
ORG0000H
JMPSTART
ORG0100H
START:
MOVSP.#5FH
MOVP0,#8CH
MOVP3,#0FFH
MOKEY:
MOVA,P3
CPLA
JZNOKEY
MOVTEMP,NOKEY
MOVR7,#16
MOVR2,#0
LOOP:
MOVA,R2
MOVDPTR,#CODE-P0
MOVCA,@A+DPTR
MOVP0,A
INCR2
SETBRS0
CALLD-1S
CLRRS0
DJNZR7,LOOP
JMPSTART
D-1S:
MOVR6,#100
D10:
CALLD10ms
RET
D10ms:
MOVR5,#10
D1ms:
MOVR4,#249
DL:
NOP
NOP
DJNZR4,DL
DJNZR5,D1ms
RET
CODE-P0:
DB0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H
DB80H,90H,88H,83H,0C6H,0A1H,86H,8EH
END
LM324
的4脚接+12V,11脚接-12V
LM386集成功率放大器
电压增益26—45dB,电源电压+5V.
集成稳压器CW317输入电压4—40V,输出调整电压1.2—37V,输出电流0.1—1.5A,从左到右依次是ADJ,Uo,Ui
CM12864-12
模块基本参数:
产品型号:
CM12864-12
显示内容:
8个中文字*4行,128*64点阵
外形尺寸(mm):
93*70*13.5
视域尺寸(mm):
73.5*39
点尺寸(mm):
0.48*0.48
控制器:
ST7920
(1)电压:
3.3V,5.0V;模块内自带-10V负压,用于LCD的驱动电压。
(2)STN正视反射模式
(3)显式模式:
黄绿膜、灰膜、蓝膜、黑白膜、
(4)显式角度:
6点钟直视
(5)与CPU接口采用8位数据总线并行输入输出和8条控制线
(6)工作温度(Ta):
-10℃~+60℃,存储温度:
-20℃~+70℃
(7)背光特征:
LED背光(黄绿色、白色、蓝色、红色)
(8)模块封装方式:
COB
(9)功耗:
模块自带负压
12864汉字液晶屏图形模式研究
本系统采用的显示液晶为12864,横向上有128个点,纵向上有64个点。
我所购买的这块液晶的控制芯片为st7920,内置字库为曰汉字屏。
汉字屏并非点阵屏,其画图能力不强大。
由于本次要做的系统需要显示点阵,经过几天的研究,我成功实现定点函数Point(x,y)的编写。
1.切入点
这块液晶是可以显示图片的,需要准备一张128x64的bmp图片,利用转换软件将其转换为数组,数组的存放格式为0xXX(X代表一个16进制数)。
分析其画图函数可以得出,每次写入的数据恰为0xXX,即每次写入8个点。
2.XY坐标研究
先分清两个概念,内部地址和物理观察地址不一样!
设内部地址变量为LCD_X和LCD_Y,设直观物理观察,左上角物理坐标地址为(x,y)为(0,0)。
2864屏并非真正的128x64,而是由256x32人为走线成4行,并且横向X一次移动16个物理点(分两次写入),即内部横向LCD_X坐标范围0-15,内部纵向LCD_Y坐标范围0-31。
其实际初始内部坐标并非为0,而是(LCD_X,LCD_Y)=(80,80)。
举例来说,LCD_X=80+8,LCD_Y=80所代表的点的位置为物理位置为从(0,32)开始的纵向16个点。
3.缺点和改进
汉字液晶毕竟不是点阵液晶,通过读取数据的方式再写入数据,势必将增大液晶显示的响应时间,特别对本次示波器的高速系统影响较大。
如果单片机内存空间足够,可以在其SRAM中开1KB的存储空间用来映射液晶的RAM,可惜本次系统对单片机内部空间要求比较高,若外扩SRAM,必可以提高液晶的响应速度。
4.LCD12864液晶图文菜单制作
如果采用整屏刷新显然速度太慢,而且存储的数据量太大所以可以采用局部更新的办法,只改变屏上需要变动的某一部分以下就是用这种办法做出的菜单。
/**********************************************************************************
*文件名:
LCD12864.c
*功能:
LCD12864液晶屏驱动程序代码
**********************************************************************************/
ucharAC_TABLE[]=
{
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
};
voiddelayus(uintus)
{
while(us--);
}
voidWrite_byte(ucharbyte)
{
uchari;
CLK=0;
delayus
(2);
for(i=0;i<8;i++)
{
if(byte&0x80)SID=1;
elseSID=0;
CLK=1;
delayus(7);
byte<<=1;
CLK=0;
delayus(7);
}
}
voidWrite_command_12864(ucharcom)
{
CS=1;
Write_byte(0xf8);
Write_byte(com&0xf0);
Write_byte((com&0x0f)<<4);
CS=0;
}
voidWrite_data_12864(uchardata)
{
CS=1;
Write_byte(0xfa);
Write_byte(data&0xf0);
Write_byte((data&0x0f)<<4);
CS=0;
}
voidPutStr(ucharrow,ucharcol,uchar*puts)
{
Write_command_12864(0x30);
Write_command_12864(AC_TABLE[8*row+col]);
while(*puts!
='\0')
{
if(col==8)
{
col=0;
row++;
if(row==4)row=0;
}
Write_command_12864(AC_TABLE[8*row+col]);
Write_data_12864(*puts);
puts++;
Write_data_12864(*puts);
puts++;
col++;
}
}
voidLcmClearTXT()
{
uchari;
Write_command_12864(0x30);
Write_command_12864(0x80);
for(i=0;i<64;i++)Write_data_12864(0x20);
}
voidLcmClearBMP()
{
unsignedchari,j;
Write_command_12864(0x34);//8Bit扩充指令集,即使是36H也要写两次
Write_command_12864(0x36);//绘图ON,基本指令集里面36H不能开绘图
for(i=0;i<32;i++)//12864实际为256x32
{
Write_command_12864(0x80|i);//行位置
Write_command_12864(0x80);//列位置
for(j=0;j<32;j++)//256/8=32byte
Write_data_12864(0);
}
}
voidPutBMP(constuchar*puts)
{
uintx=0;
uchari,j;
Write_command_12864(0x34);//8Bit扩充指令集,即使是36H也要写两次
Write_command_12864(0x36);//绘图ON,基本指令集里面36H不能开绘图
for(i=0;i<32;i++)//12864实际为256x32
{
Write_command_12864(0x80|i);//行位置
Write_command_12864(0x80);//列位置
for(j=0;j<32;j++)//256/8=32byte
{//列位置每行自动增加
Write_data_12864(puts[x]);
x++;
}
}
}
voidWrite_dot(ucharadd,constuchar*puts)
{
uintx=0;
uchari,j,lie;
Write_command_12864(0x34);//8Bit扩充指令集,即使是36H也要写两次
Write_command_12864(0x36);
if(add<=0x8f)lie=0;
if(add>0x8f)lie=16;
for(i=0+lie;i<16+lie;i++)
{
Write_command_12864(0x80|i);
Write_command_12864(add);
for(j=0;j<2;j++)
{
Write_data_12864(puts[x]);
x++;
}
}
}
voidLCD_12864_Init()
{
Write_command_12864(0x30);
Write_command_12864(0x03);
Write_command_12864(0x0c);
Write_command_12864(0x01);
Write_command_12864(0x06);
}
51单片机带字库12864液晶动态汉字显示
C语言源程序
实验芯片为:
AT89S52,带字库液晶屏:
12864,实现的目的:
动态一个汉字一个汉字显示。
其实和显示汉字的程序一样,只是稍做一下修改即可。
C语言源程序如下:
#include
#include
#include
#include
sbitRS=P2^4;
sbitWRD=P2^5;
sbitE=P2^6;
sbitPSB=P2^1;
sbitRES=P2^3;
voidTransferData(chardata1,bitDI);
voiddelayms(unsignedintn);
voiddelay(unsignedintm);
voidlcd_mesg003(unsignedcharcode*addr1);
unsignedcharcodeIC_DAT[]={
"我是一个中国人啊"};
voidinitinal(void)
{
delay(40);
PSB=1; //并口工作模式
delay
(1);
RES=0;//复位
delay
(1);
RES=1; //复位置高
delay(10);
TransferData(0x30,0);
delay(100);
TransferData(0x30,0);
delay(37);
TransferData(0x08,0);
delay(100);
TransferData(0x10,0);
delay(100);
TransferData(0x0C,0);
delay(100);
TransferData(0x01,0);
delay(10);
TransferData(0x06,0);
delay(100);
}
voidmain(void)
{
while
(1)
{
initinal();//调用LCD字库初始化程序
delay(100);
lcd_mesg003(IC_DAT);
}
}
voidlcd_mesg003(unsignedcharcode*addr1)
{
unsignedchari;
//第一行
TransferData(0x80,0);
delay(100);
for(i=0;i<16;i++)
{
TransferData(*addr1,1);
addr1++;
delayms(50);
}
}
voidTransferData(chardata1,bitDI)//传送数据或是命令,当DI=0时,传送命令,当DI=1时,传送数据
{
WRD=0;
RS=DI;
delay
(1);
P0=data1;
E=1;
delay
(1);
E=0;
}
voiddelayms(unsignedintn)
{
unsignedinti,j;
for(i=0;i for(j=0;j<2000;j++);
}
voiddelay(unsignedintm)
{
unsignedinti,j;
for(i=0;ifor(j=0;j<10;j++);
}
原理就是在显示每个汉字的时候加了一个延时程序,当然可以用定时器来实现,这样的话,不占用CPU处理时间。
单片机课程设计报告——电子琴
设计原理
设计采用P1口作为扫描键盘接口,P3.7口作为输出,P1口低4位接4X4矩阵键盘的列,高4位接行。
CPU工作在查询方式下并开放中断,且将定时器T1设为最高优先级。
当程序扫描到按键时调用延时防抖后再次扫描并判断键值,并转入相应的按键处理子程序,在子程序中向定时器装入初值并启动其工作,当定时器溢出时向CPU申请中断,CPU响应中断后转入中断子程序,输出预定频率的方波并送到音频放大模块进行放大输出。
由于单片机晶振为12MHZ,那么定时器的计数周期为1MHZ,假如选择工作方式1,那T值便为T=216--5﹡105/相应的频率,根据不同的频率计算出应该赋给定时器的计数值,列出不同音符与单片机计数T0相关的计数值如下表所示:
简谱
频率Hz
简谱码T
1
523
64578
2
587
64686
3
659
64778
4
693
64821
5
784
64898
6
880
64968
7
988
65029
本设计所用芯片为H51/TPOD-8031,程序为C语言。
二硬件电路设计
三流程图
按键——断键值——按键0-7——脉冲倒计数__启动定时器
NO
中断
电平取反
脉冲数=0
YES
NO
END
四程序设计
软件程序设计分为,主程序,按键判断程序,键盘扫描程序,T1定时程序,延时程序,显示程序。
#include
codeunsignedinttone[7]={64578,64686,64778,64821,64898,64968,65029};
//音调
#definev10
sbitP1_0=P1^0;
sbitP1_1=P1^1;
sbitP1_2=P1^2;
sbitP1_3=P1^3;
sbitout=P3^7;
//声音输出
unsignedcharpulse;
unsignedcharpulse_cnt;
unsignedcharhigh,low;
unsignedcharkey,temp;
voidKeyScan(void);
voiddelay10ms(unsignedchartime);
voidDispaly(void);
/*按键判断程序******/
sure()
{
P1=0xF0;
delay10ms(v);
temp=P1;
temp&=0xF0;
if(temp!
=0xF0)
{
delay10ms(v);
temp=P1;
temp&=0xF0;
if(temp!
=0xF0)
return1;
else
return0;
}
}
/***主函数**/
voidmain()
{inta;
TCON=0x00;
TMOD=0x10;//方式1定时
IE=0x88;//T1中断
IP=0x08;//T1中断优先
while
(1)
{
a=sure();
if(a==1)
KeyScan();
}
}
/*键盘扫描程序**/
voidKeyScan()
{
//intj;
P1=0xFF;
P1_0=0;
temp=P1;
temp&=0xF0;
if(temp!
=0xF0)
{
delay10ms(v);
temp=P1;
temp&=0xF0;
if(temp!
=0xF0)
{
temp=P1;
temp&=0xF0;
switch(temp)
{
case0x70:
key=10;break;
case0xB0:
key=11;break;
case0xD0:
key=12;break;
case0xE0:
key=13;break;
}
}
}
P1=0xFF;
P1_1=0;
temp=P1;
temp&=0xF0;
if(temp!
=0xF0)
{
delay10ms(v);
temp=P1;
temp&=0xF0;
if(temp!
=0xF0)
{
temp=P1;
temp&=0xF0;
switch(temp)
{
case0x70:
key=9;break;
case0xB0:
key=6;break;
case0xD0:
key=3;break;
case0xE0:
key=14;break;
}
}
}
P1=0xFF;
P1_2=0;
temp=P1;
temp&=0xF0;
if(temp!
=0xF0)
{
delay10ms(v);
temp=P1;
temp&=0xF0;
if(temp!
=0xF0)
{
temp=P1;
temp&=0xF0;
switch(temp)
{
case0x70:
key=8;break;
case0xB0:
key=5;break;
case0xD0:
key=2;break;
case0xE0:
key=15;break;
}
}
}
P1=0xFF;
P1_3=0;
temp=P1;
temp&=0xF0;
if(temp!
=0xF0)
{
delay10ms(v);
temp=P1;
temp&=0xF0;
if(temp!
=0xF0)
{
temp=P1;
temp&=0xF0;
switch(temp)
{
case0x70:
key=7;break;
case0xB0:
key=4;break;
case0xD0:
key=1;break;
case0xE0:
key=0;break;
}
}
}
/*******************************************************************/
if(key>=1&&key<=7)
{
low=tone[key-1]&0x00ff;
high=tone[key-1]>>8;
key=0;
TH1=high;
TL1=low;
TR1=1;//开始计数
pulse_cnt=500;
while(pulse_cnt!
=0);
out=0;
TR1=0;
}
}
/********************************************************************
T1定时程序
********************************************************************/
voidt1()interrupt3//T1中断,方式1
{
TR1=0;
TH1=high;
TL1=low;
TR1=1;
out=pulse;
pulse=~pulse;
pulse_cnt--;
}
/********************************************************************
延时程序
********************************************************************/
voiddelay10ms(un