9.14学习笔记
作业1:
利用定时器/计数器T0从P1.0输出周期为1S的方波,是发光二极管一1Hz闪烁,设晶振的频率为12MHz
#include<reg52.h> #define uint unsigned int #define uchar unsigned char sbit led = P1^0; uchar tt; uint aa; void init() { TMOD = 0x01;//设置定时器模式0 TH0 = (65535- 50000)/256; TL0 = (65535 - 50000)%256; EA = 1;//开总中断 ET0 =1;//开定时器中断 TR0 = 1;//启动定时器 tt=1; } main() { init(); while(1) { led = 1; if(tt == 20) { tt = 1; led = 0; aa=1000; while(aa--);//延时看效果 } } } void time_1()interrupt 1 { TH0 = (65535- 50000)/256; TL0 = (65535 - 50000)%256; tt ++; }
作业2:利用定时器计数器T1产生定时时钟,由P1口控制8个发光二极管,使8个指示灯依次一个一个的闪烁闪动的频率为10次/s(8个灯依次亮一变为一个周期)循环
#include<reg52.h> #include<intrins.h> #define uint unsigned int #define uchar unsigned char uchar aa,tt; void init() { TMOD = 0x01; TH0 =(65535-50000)/256; TL0 = (65535-50000)%256; EA = 1;//开总中断 ET0 = 1;//开定时器中断 TR0 =1;//启动定时器 aa = 0xfe; tt = 0; } void main() { init(); while(1) { if(tt ==2) { tt =0; P1 =aa; aa = _crol_(aa,1);//循环左移 } } } void timer_0()interrupt 1 { TH0 =(65535-50000)/256; TL0 = (65535-50000)%256; tt ++; }
作业三:编写程序,使流水灯流转,数码管每2s动态显示0~16,这个程序要注意一个地方,就是时间轴的分配问题,因为while中有延时,所以,对于进入中断的判定,要特别注意使中断操作放在中断函数中
错误代码:
#include<reg52.h> #include<intrins.h> #define uint unsigned int #define uchar unsigned char uchar code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void delay(uint z); uchar temp,aa,num; sbit dula =P2^6; sbit wela = P2^7; void main() { TMOD = 0x01; TH0 = (65536 -50000)/256; TL0 = (65536 -50000)%256; EA = 1;//开总中断 ET0 = 1;//开定时器中断 TR0 = 1;//启动定时器 temp = 0xfe; P1 = temp; wela = 1; P0 = 0x0; wela = 0; dula = 1; P0 = table[0]; dula = 0; aa =0; while(1) { delay(100); temp = _crol_(temp,1);//循环移位 P1 = temp; if(aa == 40)//在主函数中判断aa的值,这样与上面的delay()会产生冲突 { aa = 0; num ++; dula = 1; P0 = table[num]; dula = 0; if(num ==16) num =0; } } } void delay(uint z) { uint x,y; for(x = z;x>0;x--) for(y = 110;y>0;y--); } void time_0()interrupt 1 { TH0 = (65536 -50000)/256; TL0 = (65536 -50000)%256; aa++;//这样的操作不妥 }
正确代码:
#include<reg52.h> #include<intrins.h> #define uint unsigned int #define uchar unsigned char uchar code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void delay(uint z); uchar temp,aa,num; sbit dula =P2^6; sbit wela = P2^7; void main() { TMOD = 0x01; TH0 = (65536 -50000)/256; TL0 = (65536 -50000)%256; EA = 1;//开总中断 ET0 = 1;//开定时器中断 TR0 = 1;//启动定时器 temp = 0xfe; P1 = temp; wela = 1; P0 = 0x0; wela = 0; dula = 1; P0 = table[0]; dula = 0; aa =0; while(1) { delay(100); temp = _crol_(temp,1);//循环移位 P1 = temp; } } void delay(uint z) { uint x,y; for(x = z;x>0;x--) for(y = 110;y>0;y--); } void time_0()interrupt 1 { TH0 = (65536 -50000)/256; TL0 = (65536 -50000)%256; aa++; if(aa == 40)//不在主函数中判断aa的值,才是正确的操作 { aa = 0; num ++; dula = 1; P0 = table[num]; dula = 0; if(num ==16) num =0; } } /*在主函数中进行流水灯的操作,在中断函数中进行数码管的操作,这样才能避免 时间轴长度不一致的问题 */
数码管的动态显示
动态显示的特点是将所有位数码管的段选线并联在一起,并由位选线控制哪一个数码管有效这样一来就没有必要每一位数码管分配一个锁存器,从而大大简化了硬件电路。动态显示的亮度要比静态显示的要差一些,所以,选择限流电阻应该略小于静态显示电路中的
#include<reg52.h> #define uint unsigned int #define uchar unsigned char void delay(uint z); sbit dula = P2^6; sbit wela = P2^7; uchar aa,numw,numd; /*编码表的定义与c语言的十分相似,但是多了一个关键字 code,code表示编码的意思,需要注意的是*单片机c语言中定义 数组时是占用内存空间的,而定义编码时这是直接分配到程序空间 间,编译后编码占用的是程序存储空间,而不是内存空间间*/ uchar code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; uchar code table_we[]={0xfe,0xfd,0xfb,0xf7, 0xef,0xdf,0xbf,0x7f }; void main() { TMOD = 0x01; TH0 = (65535-500)/256; TL0 = (65535-100)%256; EA =1 ; ET0 =1; TR0 = 1; numw =0; numd =0; while(1) { if(aa==8) { aa =0; wela = 1; P0 = table_we[numw]; wela = 0; numw++; if(numw==8) numw =0; P0 = 0xff; dula = 1; P0 = table[numd]; dula = 0; numd++; if(numd==8) numd =0; P0 = 0xff; } } while(1); } void time_0()interrupt 1 { TH0 = (65535-500)/256; TL0 = (65535-100)%256; aa++; }
数码管显示三位数,使这个数一秒加一
注意在主函数中必须不断调用显示函数,才能稳定显示,否则不显示,还有要注意消影P0 = 0xff
#include<reg52.h> #define uint unsigned int #define uchar unsigned char void delay(uint z); sbit dula = P2^6; sbit wela = P2^7; uchar aa,numw,numd,ge,shi,bai; uint num; void delay(uint z); void displays(uchar bai,uchar shi,uchar ge); void init(); /*编码表的定义与c语言的十分相似,但是多了一个关键字 code,code表示编码的意思,需要注意的是*单片机c语言中定义 数组时是占用内存空间的,而定义编码时这是直接分配到程序空间 间,编译后编码占用的是程序存储空间,而不是内存空间间*/ uchar code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; uchar code table_we[]={0xfe,0xfd,0xfb,0xf7, 0xef,0xdf,0xbf,0x7f }; void main() { init(); while(1) { if(aa == 20) { aa = 0; num ++; ge = num%10; shi = num/10%10; bai = num/100; } displays(bai,shi,ge);//要不断调用函数才能显示数字,否则不显示 } } //初始化函数 void init() { TMOD = 0x01; TH0 = (65535-50000)/256; TL0 = (65535-50000)%256; EA = 1 ; ET0 = 1; TR0 = 1; aa =0; num =0; } void delay(uint z) { uint x,y; for(x= z;x>0;x--) for(y = 110 ;y>0;y--); } //显示函数就是显示作用,没有num++= void displays(uchar bai,uchar shi,uchar ge) { wela = 1; P0 = 0xfe; wela = 0; P0 = 0xff;//消影 dula = 1; P0 = table[bai]; dula = 0; delay(3); wela = 1; P0 = 0xfd; wela = 0; P0 = 0xff;//消影 dula = 1; P0 = table[shi]; dula = 0; delay(3); wela = 1; P0 = 0xfb; wela = 0; P0 = 0xff;//消影 dula = 1; P0 = table[ge]; dula = 0; delay(3); } //定时器函数 void time_0()interrupt 1 { TH0 = (65535-50000)/256; TL0 = (65535-50000)%256; aa++; }
版权所有,转载请注明链接地址:http://www.cnblogs.com/fengdashen/p/3321092.html