本帖最后由 heicad 于 2016-3-11 22:22 编辑
下面是一个51单片机的程序:中断和计数初值这看不懂
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- uint num=0; //外部中断次数
- uchar num1=0;
- uint Speed_dat=0;
- uint Total_Dis=0;
- uchar Beep_speed=40;
- sbit KEY1=P3^5;
- sbit KEY2=P3^6;
- sbit KEY3=P3^7;
- void delayms(uint xms)
- {
- uint i,j;
- for(i=xms;i>0;i--)
- for(j=110;j>0;j--);
- }
- #include"LCD1602.H"
- #include"AT24C02.H"
- void keyscan()
- {
- if(!KEY1)
- {
- delayms(5);
- if(!KEY1)
- {
- if(Beep_speed<255)
- Beep_speed++;
- while(!KEY1);
- }
- }
- else if(!KEY2)
- {
- delayms(5);
- if(!KEY2)
- {
- if(Beep_speed>0)
- Beep_speed--;
- while(!KEY2);
- }
- }
- else if(!KEY3)
- {
- delayms(5);
- if(!KEY3)
- {
- Write_AT24C02_Byte(0,0);
- Write_AT24C02_Byte(1,0);
- Total_Dis=0;
- dis_Mileage();
- while(!KEY3);
- }
- }
- }
- void main()
- {
- uchar dat=0;
- float M_dat=0.0;
- init_1602();
- Init_AT24C02();
- dat=Read_AT24C02_Random(0);
- Total_Dis=dat*256+Read_AT24C02_Random(1);
- dis_Mileage();
- TMOD=0X01;
- TH0=(65536-1000)/256;
- TL0=(65536-1000)%256;
- ET0=1;
- TR0=1;
- IT0=1; //边沿触发中断
- EX0=1;
- EA=1;
- while(1)
- {
- if(num1>99)
- {
- num1=0;
- M_dat+=(float)(Cur_Speed/3.60); //每0.1s走的米数
- }
- if(M_dat>1000.0) //路程每增加100m储存一次
- {
- M_dat-=1000.0;
- Total_Dis+=1;
- Write_AT24C02_Byte(0,Total_Dis/256);
- Write_AT24C02_Byte(1,Total_Dis%256);
- dis_Mileage();
- }
- display();
- keyscan();
- }
- }
- void T0_time() interrupt 1 //定时器0
- {
- TH0=(65536-1000)/256;
- TL0=(65536-1000)%256;
- if(num<500)
- num++;
- else
- Speed_dat=0;
- if(num1<100)
- num1++;
- }
- void ex_0() interrupt 0 //外部中断0
- {
- Speed_dat=(500/num);
- num=0;
- }
- #define uchar unsigned char
- #define uint unsigned int
- sbit EN=P2^7;
- sbit RS=P2^5;
- sbit RW=P2^6;
- sbit BEEP=P2^0;
- sbit LED1=P1^2;
- sbit LED2=P1^3;
- uchar LCD1602_Table[]="0123456789";
- //LCD1602显示标尺 //0123456789abcdef
- uchar code DIS_TAB1[]={" Speed:---Km/h "};
- uchar code DIS_TAB2[]={"M: Km---Km/h"};
- uint sum_dat=0;
- uchar Cur_Speed=0;
- extern uint Speed_dat;
- extern uint Total_Dis;
- extern void delayms(uint xms);
- void WRITE_LCD1602_DAT(uchar date)
- {
- EN=0;
- RS=1;
- P0=date;
- EN=0;
- delayms(5);
- EN=1;
- }
- void WRITE_LCD1602_COM(uchar date)
- {
- EN=0;
- RS=0;
- P0=date;
- EN=0;
- delayms(5);
- EN=1;
- }
- void init_1602()
- {
- unsigned char i;
- RW=0;
- WRITE_LCD1602_COM(0x38);
- WRITE_LCD1602_COM(0x0c);
- WRITE_LCD1602_COM(0x06);
- WRITE_LCD1602_COM(0x01);
- WRITE_LCD1602_COM(0x80);
- for(i=0;i<16;i++)
- WRITE_LCD1602_DAT(DIS_TAB1[i]);
- WRITE_LCD1602_COM(0x80+0x40);
- for(i=0;i<16;i++)
- WRITE_LCD1602_DAT(DIS_TAB2[i]);
- }
- void display()
- {
- static uint dat=0;
- static uchar i=0;
- if(i<6)
- {
- i++;
- sum_dat+=Speed_dat;
- }
- else
- {
- i=0;
- dat=sum_dat/10;
- sum_dat=0;
- }
- Cur_Speed=dat;
- WRITE_LCD1602_COM(0x80+7);
- if(dat/100>0)
- WRITE_LCD1602_DAT(LCD1602_Table[dat%1000/100]);
- else
- WRITE_LCD1602_DAT(' ');
- if(dat/10>0)
- WRITE_LCD1602_DAT(LCD1602_Table[dat%100/10]);
- else
- WRITE_LCD1602_DAT(' ');
- WRITE_LCD1602_DAT(LCD1602_Table[dat%10]);
- WRITE_LCD1602_COM(0x80+9+0x40);
- if(Beep_speed/100>0)
- WRITE_LCD1602_DAT(LCD1602_Table[Beep_speed%1000/100]);
- else
- WRITE_LCD1602_DAT(' ');
- if(Beep_speed/10>0)
- WRITE_LCD1602_DAT(LCD1602_Table[Beep_speed%100/10]);
- else
- WRITE_LCD1602_DAT(' ');
- WRITE_LCD1602_DAT(LCD1602_Table[Beep_speed%10]);
- if(dat>Beep_speed)
- {
- if(i<3)
- BEEP=0;
- else
- BEEP=1;
- LED1=0;
- LED2=1;
- }
- else
- {
- BEEP=1;
- LED1=1;
- LED2=0;
- }
-
- }
- void dis_Mileage()
- {
- WRITE_LCD1602_COM(0x80+0x40+2);
- if(Total_Dis/1000>0)
- WRITE_LCD1602_DAT(LCD1602_Table[Total_Dis%10000/1000]);
- else
- WRITE_LCD1602_DAT(' ');
- if(Total_Dis/100>0)
- WRITE_LCD1602_DAT(LCD1602_Table[Total_Dis%1000/100]);
- else
- WRITE_LCD1602_DAT(' ');
- WRITE_LCD1602_DAT(LCD1602_Table[Total_Dis%100/10]);
- WRITE_LCD1602_DAT('.');
- WRITE_LCD1602_DAT(LCD1602_Table[Total_Dis%10]);
- }
- #include<intrins.h>
- #define AT24C02_OP_READ 0xa1 // AT24C02器件地址以及读取操作
- #define AT24C02_OP_WRITE 0xa0 // AT24C02器件地址以及写入操作
- //#define AT24C02_MAX_ADDR 0xff // AT24C02最大地址
- //unsigned char code dis_code[]={0x7e,0xbd,0xdb,0x7e,0xdb,0xbd,0x7e,0xff};// 写入到AT24C02的数据串
- sbit AT24C02_SDA=P1^1;
- sbit AT24C02_SCL=P1^0;
- //sbit AT24C02_WP=P3^3; //写保护 “=0”读写 “=1” 只读
- /*****************延时子程序***********************/
- void Delay_1ms(unsigned int xms)
- {
- unsigned int i,j;
- for(i=xms;i>0;i--)
- for(j=122;j>0;j--);
- }
- /*****************24C02初始化子程序***********************/
- void Init_AT24C02()
- {
- AT24C02_SDA=1; //总线空闲时,因各设备都是集电极或漏极开路,上拉电阻使SDA和SCL线都保持高电平。
- // AT24C02_WP=1;
- AT24C02_SCL=1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- /*****************24C02起始信号子程序***********************/
- void AT24C02_Start()
- {
- AT24C02_SDA=1;
- _nop_();
- _nop_();
- AT24C02_SCL=1;
- _nop_();
- _nop_();
- AT24C02_SDA=0;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- AT24C02_SCL=0;
- }
- /*****************24C02停止信号子程序***********************/
- void AT24C02_Stop()
- {
- AT24C02_SDA=0;
- _nop_();
- _nop_();
- AT24C02_SCL=1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- AT24C02_SDA=1;
- _nop_();
- _nop_();
- }
- /*****************24C02应答子程序***********************/
- void AT24C02_ACK()
- {
- AT24C02_SDA=1; // 读取应答
- _nop_();
- _nop_();
- AT24C02_SCL=1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- while(AT24C02_SDA); //等待应答信号
- AT24C02_SCL=0;
- _nop_();
- _nop_();
- }
- /*****************读出24C02数据子程序***********************/
- unsigned char Read_AT24C02_DATA()
- {
- unsigned char i,read_data;
- for(i=0;i<8;i++)
- {
- AT24C02_SCL=1;
- _nop_();_nop_();_nop_();_nop_();
- read_data<<=1; //从高位到底位
- read_data|=(unsigned char)AT24C02_SDA;
- AT24C02_SCL=0;
- _nop_();_nop_();_nop_();_nop_();
- }
- return(read_data);
- }
- /*****************写入24C02数据子程序***********************/
- void Write_AT24C02_DATA(unsigned char write_data)
- {
- unsigned char i;
- for(i=0;i<8;i++) // 循环移入8个位
- {
- AT24C02_SDA=(bit)(write_data&0x80);
- _nop_();
- AT24C02_SCL=1;
- _nop_();
- _nop_();
- AT24C02_SCL=0;
- write_data<<=1;
- }
- }
- /*****************字节写入24C02数据子程序***********************/
- void Write_AT24C02_Byte(unsigned char addr, unsigned char write_data) // 在指定地址addr处写入数据write_data
- {
- AT24C02_Start(); //发起始命令
- Write_AT24C02_DATA(AT24C02_OP_WRITE); //从机地址写命令
- AT24C02_ACK();
- Write_AT24C02_DATA(addr); //发送AT24C02的字节地址
- AT24C02_ACK();
- Write_AT24C02_DATA(write_data); //发送数据到被寻址的存储单元
- AT24C02_ACK();
- AT24C02_Stop(); //停止信号
- Delay_1ms(10); //延时等待AT24C02内部数据的擦写
- }
- unsigned char Read_AT24C02_Current()
- // 在当前地址读取
- {
- unsigned char read_data;
- AT24C02_Start();
- Write_AT24C02_DATA(AT24C02_OP_READ);
- AT24C02_ACK();
- read_data = Read_AT24C02_DATA();
- AT24C02_Stop();
- return read_data;
- }
- unsigned char Read_AT24C02_Random(unsigned char addr)
- // 在指定地址读取
- {
- AT24C02_Start();
- Write_AT24C02_DATA(AT24C02_OP_WRITE);
- AT24C02_ACK();
- Write_AT24C02_DATA(addr);
- AT24C02_ACK();
- return(Read_AT24C02_Current());
- }
复制代码
|