11. #define KEY_8 P3^0 12. #define KEY_9 P3^1 13. #define KEY_A P3^2 14. #define KEY_B P3^3 15. #define KEY_C P3^4 16. #define KEY_D P3^5 17. #define KEY_E P3^6 18. #define KEY_F P3^7 19. Code unsigned char Seg7Code[16]= //用十六进数作为数组下标,可直接取得对应的七段编码字节 20. // 0 1 2 3 4 5 6 7 8 9 A b C d E F 21. {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71}; 22. void main( void ) 23. { 24. unsigned char i=0; //作为数组下标 25. P2 = 0xff; //P2作为输入,初始化输出高 26. P3 = 0xff; //P3作为输入,初始化输出高 27. While( 1 ) 28. { 29. if( KEY_0 == 0 ) i=0; if( KEY_1 == 0 ) i=1; 30. if( KEY_2 == 0 ) i=2; if( KEY_3 == 0 ) i=3; 31. if( KEY_4 == 0 ) i=4; if( KEY_5 == 0 ) i=5; 32. if( KEY_6 == 0 ) i=6; if( KEY_7 == 0 ) i=7; 33. if( KEY_8 == 0 ) i=8; if( KEY_9 == 0 ) i=9; 34. if( KEY_A == 0 ) i=0xA; if( KEY_B == 0 ) i=0xB; 35. if( KEY_C == 0 ) i=0xC; if( KEY_D == 0 ) i=0xD; 36. if( KEY_E == 0 ) i=0xE; if( KEY_F == 0 ) i=0xF; 37. SLED = Seg7Code[ i ]; //开始时显示0,根据i取应七段编码 38. } 39. } 共9页: 上一页 [1] 2 [3] [4] [5] [6] [7] [8] [9] 下一页
第二节:双数码管可调秒表
解:只要满足题目要求,方法越简单越好。由于单片机I/O资源足够,所以双数码管可接成静态显示方式,两个共阴数码管分别接在P1(秒十位)和P2(秒个位)口,它们的共阴极都接地,安排两个按键接在P3.2
编辑版word
(十位数调整)和P3.3(个位数调整)上,为了方便计时,选用12MHz的晶体。为了达到精确计时,选用定时器方式2,每计数250重载一次,即250us,定义一整数变量计数重载次数,这样计数4000次即为一秒。定义两个字节变量S10和S1分别计算秒十位和秒个位。编得如下程序: 代码 1. #include 2. Code unsigned char Seg7Code[16]= //用十六进数作为数组下标,可直接取得对应的七段编码字节 3. // 0 1 2 3 4 5 6 7 8 9 A b C d E F 4. {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71}; 5. void main( void ) 6. { 7. unsigned int us250 = 0; 8. unsigned char s10 = 0; 9. unsigned char s1 = 0; 10. unsigned char key10 = 0; //记忆按键状态,为1按下 11. unsigned char key1 = 0; //记忆按键状态,为1按下 12. //初始化定时器 Timer0 13. TMOD = (TMOD & 0xF0) | 0x02; 14. TH1 = -250; //对于8位二进数来说,-250=6,也就是加250次1时为256,即为0 15. TR1 = 1; 16. while(1){ //----------循环1 17. P1 = Seg7Code[ s10 ]; //显示秒十位 18. P2 = Seg7Code[ s1 ]; //显示秒个位 19. while( 1 ){ //----------循环2 20. //计时处理 21. if( TF0 == 1 ){ 22. TF0 = 0; 23. if( ++us250 >= 4000 ){ 24. us250 = 0; 25. if( ++s1 >= 10 ){ 26. s1 = 0; 27. if( ++s10 >= 6 ) s10 = 0; 28. } 编辑版word
29. break; //结束“循环2”,修改显示 30. } 31. } 32. //按十位键处理 33. P3.2 = 1; //P3.2作为输入,先要输出高电平 34. if( key10 == 1 ){ //等松键 35. if( P3.2 == 1 ) key10=0; 36. } 37. else{ //未按键 38. if( P3.2 == 0 ){ 39. key10 = 1; 40. if( ++s10 >= 6 ) s10 = 0; 41. break; //结束“循环2”,修改显示 42. } 43. } 44. //按个位键处理 45. P3.3 = 1; //P3.3作为输入,先要输出高电平 46. if( key1 == 1 ) //等松键 47. { if( P3.3 == 1 ) key1=0; } 48. else { //未按键 49. if( P3.3 == 0 ){ key1 = 1; 50. if( ++s1 >= 10 ) s1 = 0; 51. break; //结束“循环2”,修改显示 52. } 53. } 54. } //循环2’end 55. }//循环1’end 56. }//main’end 共9页: 上一页 [1] [2] 3 [4] [5] [6] [7] [8] [9] 下一页
第三节:十字路口交通灯
如果一个单位时间为1秒,这里设定的十字路口交通灯按如下方式四个步骤循环工作: 60个单位时间,南北红,东西绿;
编辑版word
10个单位时间,南北红,东西黄; 60个单位时间,南北绿,东西红; 10个单位时间,南北黄,东西红; 解:用P1端口的6个引脚控制交通灯,高电平灯亮,低电平灯灭。 代码 1. #include 2. //sbit用来定义一个符号位地址,方便编程,提高可读性,和可移植性 3. sbit SNRed =P1^0; //南北方向红灯 4. sbit SNYellow =P1^1; //南北方向黄灯 5. sbit SNGreen =P1^2; //南北方向绿灯 6. sbit EWRed =P1^3; //东西方向红灯 7. sbit EWYellow =P1^4; //东西方向黄灯 8. sbit EWGreen =P1^5; //东西方向绿灯 9. /* 用软件产生延时一个单位时间 */ 10. void Delay1Unit( void ) 11. { 12. unsigned int i, j; 13. for( i=0; i<1000; i++ ) 14. for( j<0; j<1000; j++ ); //通过实测,调整j循环次数,产生1ms延时 15. //还可以通过生成汇编程序来计算指令周期数,结合晶体频率来调整j循环次数,接近1ms 16. } 17. /* 延时n个单位时间 */ 18. void Delay( unsigned int n ){ for( ; n!=0; n-- ) Delay1Unit(); } 19. void main( void ) 20. { 21. while( 1 ) 22. { 23. SNRed=0; SNYellow=0; SNGreen=1; EWRed=1; EWYellow=0; EWGreen=0; Delay( 60 ); 24. SNRed=0; SNYellow=1; SNGreen=0; EWRed=1; EWYellow=0; EWGreen=0; Delay( 10 ); 25. SNRed=1; SNYellow=0; SNGreen=0; EWRed=0; EWYellow=0; EWGreen=1; Delay( 60 ); 26. SNRed=1; SNYellow=0; SNGreen=0; EWRed=0; EWYellow=1; EWGreen=0; Delay( 10 ); 27. } 编辑版word
28. } 共9页: 上一页 [1] [2] [3] 4 [5] [6] [7] [8] [9] 下一页 第四节:数码管驱动 显示“12345678” P1端口接8联共阴数码管SLED8的段极:P1.7接段h,…,P1.0接段a P2端口接8联共阴数码管SLED8的段极:P2.7接左边的共阴极,…,P2.0接右边的共阴极 方案说明:晶振频率fosc=12MHz,数码管采用动态刷新方式显示,在1ms定时断服务程序中实现 代码 1. #include 2. unsigned char DisBuf[8]; //全局显示缓冲区,DisBuf[0]对应右SLED,DisBuf[7]对应左SLED, 3. void DisplayBrush( void ) 4. { code unsigned char cathode[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //阴极控制码 5. Code unsigned char Seg7Code[16]= //用十六进数作为数组下标,可直接取得对应的七段编码字节 6. {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; 7. static unsigned char i=0; // (0≤i≤7) 循环刷新显示,由于是静态变量,此赋值只做一次。 8. P2 = 0xff; //显示消隐,以免下一段码值显示在前一支SLED 9. P1 = Seg7Code[ DisBuf[i] ]; //从显示缓冲区取出原始数据,查表变为七段码后送出显示 10. P2 = cathode[ i ]; //将对应阴极置低,显示 11. if( ++i >= 8 ) i=0; //指向下一个数码管和相应数据 12. } 13. void Timer0IntRoute( void ) interrupt 1 14. { 15. TL0 = -1000; //由于TL0只有8bits,所以将(-1000)低8位赋给TL0 16. TH0 = (-1000)>>8; //取(-1000)的高8位赋给TH0,重新定时1ms 17. DisplayBrush(); 18. } 19. void Timer0Init( void ) 20. { TMOD=(TMOD & 0xf0) | 0x01; //初始化,定时器T0,工作方式1 21. TL0 = -1000; //定时1ms 22. TH0 = (-1000)>>8; 23. TR0 = 1; //允许T0开始计数 24. ET0 = 1; //允许T0计数溢出时产生中断请求 编辑版word