想吃小红帽的狼 发表于 2017-3-3 18:31 感谢!原程序是6M的晶振 |
| 只要把15单片机IO口配置成普通IO,然后下载的时候,将晶振频率选择12MHz就可以 |
wosiyabo 发表于 2017-3-3 16:59 感谢,晚上试下。 |
|
我把IO脚配置了一下,你再试试 #include "reg51.h" //#include "intrins.h" #define uchar unsigned char #define uint unsigned int sfr P0M0 = 0x94; //0000,0000 端口0模式寄存器0 sfr P0M1 = 0x93; //0000,0000 端口0模式寄存器1 sfr P1M0 = 0x92; //0000,0000 端口1模式寄存器0 sfr P1M1 = 0x91; //0000,0000 端口1模式寄存器1 sfr P2M0 = 0x96; //0000,0000 端口2模式寄存器0 sfr P2M1 = 0x95; //0000,0000 端口2模式寄存器1 sfr P3M0 = 0xB2; //0000,0000 端口3模式寄存器0 sfr P3M1 = 0xB1; //0000,0000 端口3模式寄存器1 uchar code SEG7[10]={0x03,0x9f,0x25,0x0d,0x99, 0x49,0x41,0x1f,0x01,0x09}; uchar data cnt[5];//在data区定义5位长度的数组,用来存放计数值 uchar data pre_cnt[5];//在data区定义5位长度的数组,用来存放预置值 sbit P3_7=P3^7; sbit P3_6=P3^6; sbit P3_5=P3^5; //sbit P3_4=P3^4; sbit P3_3=P3^3; sbit P3_2=P3^2; sbit P3_1=P3^1; sbit P3_0=P3^0; sbit drv=P3^4;//定义输出驱动端 bit set_flag;//定义工作标志 bit out_flag;//定义输出标志 bit keydown_flag;//键按下标志 /****************************/ void delay(uint k) { uint i,j; for(i=0;i<k;i++){ for(j=0;j<5;j++) {;}} } /**********************************************/ void scan_key(void) //扫描S1~S5键子程序开始 {uchar i,m=0x08; //定义两个字符型局部变量,并赋值0x01给m P3_6=0;P3_7=1; //禁止发送给显示器,消隐有效 for(i=0;i<5;i++) //循环5次 { SBUF=255-m;while(!TI);TI=0; //依次发送数据使IC2的输出从右至左的列线为0 if(!P3_5)pre_cnt[i]++; //若检测到P3.5为0,说明某列线送出0时与连接 //该列线的按键被按下,数组中对应的存放单元加1 m<<=1; //m的取值使从右向左的下一条列线为0 } //扫描S1~S5键子程序结束 //------------------------ for(i=0;i<5;i++) //循环5次 {if(pre_cnt[i]>9)pre_cnt[i]=0;} //对数组中的5个单元进行调整,其范围为0~9 } /************************************/ void dis_cnter(void) //显示计数器值子程序开始 {uchar i; //定义字符型局部变量i P3_7=1;P3_6=1; //消隐有效,允许显示 for(i=0;i<5;i++) //循环5次 {SBUF=SEG7[cnt[i]];while(!TI);TI=0;} //根据8个单元的计数值查表发送显示 P3_7=0; //关闭消隐,正常显示 } //显示计数器值子程序结束 /**********************************************/ void dis_pre_cnter(void) {uchar i; P3_7=1;P3_6=1; SBUF=SEG7[pre_cnt[0]]&0xfe;while(!TI);TI=0; //---------------------------------------- for(i=1;i<5;i++) {SBUF=SEG7[pre_cnt[i]];while(!TI);TI=0;} P3_7=0; } /****************************************/ void cnter(void) //计数转换子程序开始 {uchar i; //定义字符型局部变量i for(i=0;i<4;i++) //循环5次 {if(cnt[i]>9){cnt[i]=0;cnt[i+1]++;}} //若计数器某位值大于9,则该位回0, //------------------------------------ //而高位被进位加1 if(cnt[4]>9){for(i=0;i<5;i++)cnt[i]=0;}// 若计数器最高位值大于9,则计数器全清0 } //计数转换子程序结束 /***************************************************/ void pt_cnt(void) //输出控制子程序开始 { if((cnt[0]==pre_cnt[0])&&(cnt[1]==pre_cnt[1])&&(cnt[2]==pre_cnt[2])&&(cnt[3]==pre_cnt[3])&&(cnt[4]==pre_cnt[4])) //若计数值等于预置值 out_flag=1; //drv=1; //输出标志置1 else out_flag=0; //否则输出标志置0 //========================== if(out_flag)drv=0; //若输出标志为1,输出端(P3.4)置0,驱动光耦U2 else drv=1; //若输出标志为1,输出端(P3.4)置0,驱动光耦U2 //否则输出端(P3.4)置1 } //输出控制子程序结束 /********************************************/ void main(void) //主程序开始 { P0M0 = P0M1 = 0x00;//IO脚配置,按普通51输入输出方式 P1M0 = P1M1 = 0x00; P2M0 = P2M1 = 0x00; P3M0 = P3M1 = 0x00; IE=0x84; //开放CPU中断,开放外中断1的中断 IT1=1; //置外中断1为边沿触发 while(1) //无限循环 {P3_6=0;P3_7=1; //禁止发送给显示器,消隐有效 SBUF=0x00;while(!TI);TI=0; //向IC2发送0x00,使IC2输出为全0 if((P3&0x24)!=0x24)keydown_flag=1; //检测P3.2、P3.5是否为高电平。 //若不为高电平,说明有键按下,键被按下标志置1 else keydown_flag=0; //否则,键被按下标志置0 //-------------------------- SBUF=0xfe;while(!TI);TI=0; //向IC2发送0xfe if(!P3_2)set_flag=!set_flag; //若P3.2为0,说明S9键按下,标志set_flag取反 //============================================= if(!set_flag){cnter();dis_cnter(); pt_cnt();delay(100);} //若标志set_flag为0,调用计数、显示计数、输出控制的子程序 else {scan_key();dis_pre_cnter();delay(10);}//否则标志set_flag为1,调用扫描S1~S8键、显示预置值的子程序 //============================================= if(keydown_flag)delay(300); //因有键按下,调用延时300mS子程序, } //以免调整键值的速度过快 } //主程序结束 /************************************************/ void extern_int1(void) interrupt 2 using 1 { cnt[0]++; } |
| 参与人数 1 | 黑币 +15 | 收起 理由 |
|---|---|---|
|
| + 15 | 很给力! |