《[计算机软件及应用]微机原理实验报告.doc》由会员分享,可在线阅读,更多相关《[计算机软件及应用]微机原理实验报告.doc(35页珍藏版)》请在三一文库上搜索。
1、微机控制系统及其应用实验报告目录实验一:代码转换1实验二 液晶显示程序设计6实验三 串行通讯程序设计23实验四 A/D转换实验26实验五 D/A转换实验31实验一:代码转换1 设计并调试一个程序,将片内20H单元中8位无符号二进制数转化为BCD码,结果存入以30H开始的单元中。1.1 算法分析如下:由于8位无符号二进制数最大为255,其可以表示为XYZ,所以对其进行数学计算(/100,/10,%10等)以转化成BCD码。(1)、进行/100运算,取出百位数X;(2)、进行/10%10运算,取出十位数Y;(3)、进行%10运算,取出个位数Z;(4)、将ZYX存入以30H开始的单元中,即完成了BC
2、D码的转化。1.2 程序流程图如下:1.3程序代码如下:#includevoid main() unsigned char *p1; unsigned char *p2; unsigned int h,t,o; p1=0x20; p2=0x30; *p1=0xff h=*p1/100; t=*p1/10%10; o=*p1%10; *p2=o; *(p2+1)=t; *(p2+2)=h; while(1);1.4实验结果如下:本实验中输入初值为0ffH,输出应为5 5 2,分别存入30H,31H,32H中运行结果如下:2 设计并调试一个程序,将片内以20H开始的单元中的4字节无符号二进制数转化
3、为BCD码,结果存入以30H开始的单元中,低位字节在低地址端。2.1算法分析如下:本题目与上题之间差别极小,区别在于要转化的二进制数a的长度不同,需要定义不同的变量,比如long。(1)、当a不为0时,p2(30H)中存入的数就为20H中数的个位数;(2)、20H中存入的数就变为了a/10,即其向右移一位去整数部分,且p2+;(3)、重复(1)、(2),知道a为0结束。2.2流程图如下:2.3程序代码如下:#includevoid main() unsigned long *p1; unsigned char *p2; p1=0x20; p2=0x30; *p1=0xffffffff; whi
4、le(*p1!=0) *p2=*p1%10; *p1=*p1/10; p2+;while(1);2.4运行结果如下:本实验中输入初值为0ffffffffH,输出应为5 9 2 7 6 9 4 9 2 4,分别存入30H,31H39H中,运行结果如下:3 设计并调试一个程序,将累加器A中的二进制数(0F)转化为ASC码,结果仍放在A中。3.1算法分析:由ASC表可知,欲把二进制数0-9变为ASC码,需在二进制数的基础上加上30H;把二进制数a-f变为ASC码,需在二进制数基础上加上37H。(1)、判断ACC中的数在0-9中还是a-f中;(2)、如果在0-9中,使其加上30H存入ACC中;(3)、
5、如果在a-f中,使其加上37H存入ACC中;3.2流程图如下:3.3程序代码如下:#includevoid main() unsigned char y; ACC=0x08; y=ACC; if(y9) y=y+0x37;else y=y+0x30;ACC=y; while(1);3.4运行结果如下:实验二 液晶显示程序设计1设计并调试一个显示程序,利用所提供液晶显示器滚动显示123456这六个数字,并以每字符500毫秒的速度向右移动循环。1.1算法分析:由于本实验中有现成的程序可以调用,我们要做的就是写一小段程序使得屏幕可以显示123456(LCDC_DispWord()函数)这几个数字,然
6、后使其能够以500ms的速度向右循环。这里以for循环来实现,循环一次变量x加1,直到结果30+x=127(因为屏幕横屏只有128个点)时,把x清零,从头循环。1.2流程图(主函数)如下:1.3主程序代码如下:void main (void)unsigned char x=0; /禁止看门狗定时器WDTCN = 0xde; WDTCN = 0xad; /初始化SYSCLK_Init (); PORT_Init (); Key_Init();LCDC_Init();for(;)LCDC_DispWord (0+x, 2, WLib_0_5x8, 1, 5, 1); LCDC_DispWord (
7、5+x, 2, WLib_1_4x8, 1, 5, 1); LCDC_DispWord (9+x, 2, WLib_2_5x8, 1, 5, 1); LCDC_DispWord (14+x, 2, WLib_3_5x8, 1, 5, 1); LCDC_DispWord (19+x, 2, WLib_4_6x8, 1, 5, 1); LCDC_DispWord (25+x, 2, WLib_5_5x8, 1, 5, 1); Delay_ms(500);LCDC_DisFull(Clr); x=x+1; if(30+x=127)x=0;2实现秒表计时功能。用键盘产生中断控制秒表的开始和停止。2.1
8、算法分析:程序首先调用使得屏幕00:00:00,采用getkey函数控制是否开始计时,计时程序采用算法:延时10ms,当最末位(第六位)到10时进1,当第五位到10时继续进1,当第四位到10时进1,当第三位到6时进1,当第二为到10时进1。计时器数字的显示要编辑子函数draw_t(unsigned int x,int y,int n),采用switch语句,其中x为行坐标,y为纵坐标,n要显示的数字。子程序程序如下:draw_t(unsigned int x,int y,int n) switch(n) case 0;LCDC_DispWord(x,2,WLib_0_5x8,1,5,1);br
9、eak;case 1:LCDC_DispWord(x,2,WLib_1_4x8,1,5,1);break;case 2:LCDC_DispWord(x,2,WLib_2_5x8,1,5,1);break;case 3:LCDC_DispWord(x,2,WLib_3_5x8,1,5,1);break;case 4:LCDC_DispWord(x,2,WLib_4_6x8,1,5,1);break;case 5:LCDC_DispWord(x,2,WLib_5_5x8,1,5,1);break;case 6:LCDC_DispWord(x,2,WLib_6_5x8,1,5,1);break;ca
10、se 7:LCDC_DispWord(x,2,WLib_7_5x8,1,5,1);break;case 8:LCDC_DispWord(x,2,WLib_8_5x8,1,5,1);break;case 9:LCDC_DispWord(x,2,WLib_9_5x8,1,5,1);break; 2.2主函数程序流程图如下:2.3主程序代码如下:void main (void)unsigned char xdata a1,a2,a3,a4,a5,a6,key;WDTCN = 0xde; WDTCN = 0xad;SYSCLK_Init (); PORT_Init (); Key_Init();LCD
11、C_Init();a1=a2=a3=a4=a5=a6=0;LCDC_DisFull(Clr); for(;)key=GetKey();if(key!=0xFF) while(1) key=GetKey(); if(key!=0xFF) break; LCDC_DisFull(Clr); if(a6=10) a6=0;a5=a5+1; if(a5=10) a5=0;a4=a4+1; if(a4=10) a4=0;a3=a3+1; if(a3=6) a3=0;a2=a2+1; if(a2=10) a2=0;a1=a1+1; draw_t(35,20,a1); draw_t(41,20,a2); L
12、CDC_DispWord (47, 20, WLib_ddot_3x8, 1, 3, 1); draw_t(50,20,a3); draw_t(56,20,a4); LCDC_DispWord (62, 20, WLib_ddot_3x8, 1, 3, 1); draw_t(65,20,a5); draw_t(71,20,a6); Delay_ms(10); a6=a6+1; LCDC_DisFull(Clr);3实现日历功能,并将日历显示在液晶屏上。主要函数代码:#include main.hbit Flag0,Flag1,Flag2,Flag3,Flag4,Flag5,Flag6;/时分秒
13、等值修改有效标志位void Flag_Set(unsigned char dat)/修改有效标志位 0-6选中相应参数标志位 其他标志位全部置1Flag0=1;Flag1=1;Flag2=1;Flag3=1;Flag4=1;Flag5=1;Flag6=1;switch (dat)case 0x00:Flag0=0;break;case 0x01:Flag1=0;break;case 0x02:Flag2=0;break;case 0x03:Flag3=0;break;case 0x04:Flag4=0;break;case 0x05:Flag5=0;break;case 0x06:Flag6=
14、0;break;default: break;/* 主循环程序*/void main (void)unsigned char xdata keyvalue; /按键值bit Cir_Flag,Change_Flag;/Cir_Flag时间显示状态标志位;Change_Flag时间设置状态标志位unsigned char Count_Flag;/时间设置 修改量位号变量,与Flag0-6及void Flag_Set(unsigned char dat)配合完成修改量选择/以及选定修改量反色显示标志位设置WDTCN = 0xde;/ disable watchdog timerWDTCN = 0x
15、ad;SYSCLK_Init();PORT_Init();LCDC_Init();SMBusInit();Key_Init();LCDC_DisFull(Full);/全屏Delay_ms(500);LCDC_DisFull(Clr);/清屏dis_start0();Delay_ms(500);Flag_Set(0xff);/选定修改变量标志位初始化ENABLE_INTERRUPTS; while(1) keyvalue=GetKey();/调用键盘扫描函数,返回的键值送变量keyif(keyvalue!=0xFF)Alarm(1);/响铃Delay_ms(50);Alarm(0);/关闭铃声
16、switch (keyvalue)case 0x0a: Cir_Flag=1;/时间显示状态有效LCDC_DisFull(Clr);/清屏ENABLE_INTERRUPTS;/开中断/时间显示状态下 恒显示字符 显示程序LCDC_DispWord(0,16,&WLib_shi_16x16,2,16,1);LCDC_DispWord(16,16,&WLib_jian_16x16,2,16,1);LCDC_DispWord(32,16,&WLib_maohao_8x16,2,8,1);LCDC_DispWord(64,16,&WLib_maohao_8x16,2,8,1);LCDC_DispWor
17、d(88,16,&WLib_maohao_8x16,2,8,1);LCDC_DispWord(0,32,&WLib_ri_16x16,2,16,1);LCDC_DispWord(16,32,&WLib_qi_16x16,2,16,1);LCDC_DispWord(32,32,&WLib_maohao_8x16,2,8,1);LCDC_DispWord(64,32,&WLib_heng_8x16,2,8,1);LCDC_DispWord(88,32,&WLib_heng_8x16,2,8,1);LCDC_DispWord(0,48,&WLib_xing_16x16,2,16,1);LCDC_Di
18、spWord(16,48,&WLib_qi_16x16,2,16,1);LCDC_DispWord(32,48,&WLib_maohao_8x16,2,8,1);while(Cir_Flag)/时间显示状态 在时间显示有效的循环内实现两大部分功能:时间显示 键值检测及功能RTC_Read();/更新返回的时间值/*时间显示*/LCDC_DispWord(48,16,&WLib_Num_8x16(df2&0x3f)/16*16,2,8,Flag4);LCDC_DispWord(56,16,&WLib_Num_8x16(df2&0x3f)%16*16,2,8,Flag4);LCDC_DispWor
19、d(72,16,&WLib_Num_8x16(df1&0x7f)/16*16,2,8,Flag5);LCDC_DispWord(80,16,&WLib_Num_8x16(df1&0x7f)%16*16,2,8,Flag5);LCDC_DispWord(96,16,&WLib_Num_8x16(df0&0x7f)/16*16,2,8,Flag6);LCDC_DispWord(104,16,&WLib_Num_8x16(df0&0x7f)%16*16,2,8,Flag6);LCDC_DispWord(48,32,&WLib_Num_8x16df6/16*16,2,8,Flag1);LCDC_Dis
20、pWord(56,32,&WLib_Num_8x16df6%16*16,2,8,Flag1);LCDC_DispWord(72,32,&WLib_Num_8x16(df5&0x1f)/16*16,2,8,Flag2);LCDC_DispWord(80,32,&WLib_Num_8x16(df5&0x1f)%16*16,2,8,Flag2);LCDC_DispWord(96,32,&WLib_Num_8x16(df3&0x3f)/16*16,2,8,Flag3);LCDC_DispWord(104,32,&WLib_Num_8x16(df3&0x3f)%16*16,2,8,Flag3);if (
21、df4&0x07)!=0x00) LCDC_DispWord(71,48,&WLib_Num_8x16(df4&0x07)*16,2,8,Flag0);else/返回值为0是星期日LCDC_DispWord(71,48,&WLib_Num_8x167*16,2,8,Flag0);/*键值检测*/keyvalue=GetKey();/调用键盘扫描函数,返回的键值送变量keyif(keyvalue!=0xFF)Alarm(1);/响铃Delay_ms(50);Alarm(0);/关闭铃声if(keyvalue=0x0f)/*返回开机界面*/LCDC_DisFull(Clr);dis_start0(
22、);Cir_Flag=0;else if(keyvalue=0x0b)/*时间设置*/Change_Flag=Change_Flag;if(Change_Flag=1)/进入时间设置状态Count_Flag=0;/选定设置 星期 参数Flag_Set(Count_Flag);/设置星期参数显示设定update6=df6;/更新 设置数组 update5=df5;update4=df4;update3=df3;update2=df2;update1=df1;else/退出时间设置状态Count_Flag=0xff;/取消所有时间参数设置Flag_Set(Count_Flag);/取消时间参数显示
23、设置else if(keyvalue=0x0c)/*选择时间参数*/if(Change_Flag=1)/是否在时间设置状态下 否则此次无效Count_Flag+;if(Count_Flag=0x07)Count_Flag=0x00;Flag_Set(Count_Flag);else if(keyvalue=0x0d)/*被选定时间参数数值增加*/if(Change_Flag=1)/是否在时间设置状态下 否则此次无效switch (Count_Flag)/转入 修改参数 对应程序case 0x00:/星期update4+;if(update4&0x0f)0x06)update4=0x00;upd
24、ate0=df0;/秒值保留原值不更新break;case 0x01:/年update6+;if(update6&0x0f)0x09)update6=(update6+0x10)&0xf0;if(update60x99)update6=0x00;update0=df0;/秒值保留原值不更新break;case 0x02:/月update5+;if(update5&0x0f)0x09)update5=(update5+0x10)&0x10;if(update50x12)update5=0x01;update0=df0;/秒值保留原值不更新break;case 0x03:/日update3+;if
25、(update3&0x0f)0x09)update3=(update3+0x10)&0x30;if(update30x31)update3=0x01;update0=df0;/秒值保留原值不更新break;case 0x04:/时update2+;if(update2&0x0f)0x09)update2=(update2+0x10)&0x30;if(update20x23)update2=0x00;update0=df0;/秒值保留原值不更新break;case 0x05:/分update1+;if(update1&0x0f)0x09)update1=(update1+0x10)&0x70;i
26、f(update10x59)update1=0x00;update0=df0;/秒值保留原值不更新break;case 0x06:/秒update0=0x00;break;default: break;RTC_Set();/更新后的时间值 设置到实时芯片else if(keyvalue=0x0e)/*被选定时间参数数值减少*/if(Change_Flag=1)/是否在时间设置状态下 否则此次无效switch (Count_Flag)/转入 修改参数 对应程序case 0x00:/星期 if(update4=0x00)update4=0x06;elseupdate4-;update0=df0;/
27、秒值保留原值不更新break;case 0x01:/年if(update6=0x00)update6=0x99;else if(update6&0x0f)=0x00)update6=(update6-0x10)|0x09;elseupdate6-;update0=df0;/秒值保留原值不更新break;case 0x02:/月if(update5=0x01)update5=0x12;else if(update5=0x10)update5=0x09;elseupdate5-;update0=df0;/秒值保留原值不更新break;case 0x03:/日if(update3=0x01)upda
28、te3=0x31;else if(update3&0x0f)=0x00)update3=(update3-0x10)|0x09;elseupdate3-;update0=df0;/秒值保留原值不更新break;case 0x04:/时if(update2=0x00)update2=0x23;else if(update2&0x0f)=0x00)update2=(update2-0x10)|0x09;elseupdate2-;update0=df0;/秒值保留原值不更新break;case 0x05:/分if(update1=0x00)update1=0x59;else if(update1&0
29、x0f)=0x00)update1=(update1-0x10)|0x09;elseupdate1-;update0=df0;/秒值保留原值不更新break;case 0x06:/秒update0=0x00;break;default: break;RTC_Set();/更新后的时间值 设置到实时芯片/按键检测及功能部分执行完毕/时间显示状态循环体结束break;case 0x0f:LCDC_DisFull(Clr);dis_start0();break;default: break; Delay_ms(500);实验总结:通过本次实验,我加深了对单片机的理解以及单片机对液晶显示器的控制,掌握
30、了如何对单片机的液晶显示器进行编程操作。 实验三 串行通讯程序设计1 设计并调试一个串行通讯程序,利用单片串行端口将片外RAM中以3000H为起始地址的1024个字节通过串行发送端口A输出,并以自闭环的形式由串行接收口B接收,并存储到以4000H为起始地址的空间中。1.1程序流程图:1.2程序代码:void main (void)unsigned char xdata *temp0; unsigned char xdata *temp1; unsigned int i; WDTCN=0xDE; /禁止看门狗定时器 WDTCN=0xAD;SYSCLK_Init();PORT_Init();LCD
31、C_Init();LCDC_DisFull(Clr);dis_start0();Delay_ms(50);Uart0_Init(BaudRate_115200);Uart1_Init(BaudRate_115200);temp0=0x3000; temp1=0x4000; for(i=0;i=1023;i+) *temp0=0x99; temp0+; i=0;temp0=0x3000; while(i=1023) Uart0_SendByte(*temp0); Delay_ms(5); while(1) Uart0_SendByte(*temp0); Delay_ms(5);*temp1=Ua
32、rt1_ReceiveData(); if(*temp1!=0xff)break; temp0+; temp1+;i+;实验四 A/D转换实验1 设计并调试一个A/D采样程序,使用外部22.1184MHz 晶振。利用定时器中断,每1秒钟中断一次并采样。采样AIN0,1和温度通道信号,并在LCD 上显示其电压和温度值。通过手动调节VR2电位器,观察电压值的变化。实验程序:#include main.hvoid main (void)unsigned long voltage; / 电压值(毫伏)int i; / 循环计数器 WDTCN = 0xde; WDTCN = 0xad;SYSCLK_In
33、it(); / 系统时钟初始化 PORT_Init(); / 系统端口初始化LCDC_Init(); / LCD初始化Timer3_Init(SYSCLK/SAMPLERATE0); / 初始化Timer3溢出的值ADC1_Init ();/ ADC初始化Uart0_Init(BaudRate_115200);Uart0_SendString(rn);Uart0_SendString(TeL:029-88223597-802rn);LCDC_DisFull(Full);/满屏LCDC_DisFull(Clr);/清屏dis_start0();/显示开机界面ADC1_enable(1);/ADC1使能Delay_s(3);LCDC_DisFull(Clr);/清屏while (1)Delay_ms(300);for (i=0;i8;i+)/ ADC1八个通道 Delay_ms(100); DISABLE_INTERRUPTS;/ 关闭中断 voltage = ADC_Valud_Return(i);/ 给全局变量赋ADC的值 ENABLE_INTERRUPTS;/ 重新开启中断 voltage = voltage * VREF0*10;/ 实际电压DISABLE_INTERRUPTS;/ 关中断 switch(i)case 0:/ 通道0显示
链接地址:https://www.31doc.com/p-1991942.html