找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3138|回复: 5
收起左侧

如何把这个在AT89S51中正常运行的程序移植到STC15F204EA中

[复制链接]
ID:46999 发表于 2017-3-3 15:35 | 显示全部楼层 |阅读模式
如题。一个可预置5位计数器的程序。电路跟源程序如下。

预置计数器.JPG

  1. #include <AT89X51.H>#define uchar unsigned char
  2. #define uint unsigned int
  3. uchar code SEG7[10]={0x03,0x9f,0x25,0x0d,0x99,
  4.                 0x49,0x41,0x1f,0x01,0x09};
  5. uchar data cnt[5];//在data区定义5位长度的数组,用来存放计数值
  6. uchar data pre_cnt[5];//在data区定义5位长度的数组,用来存放预置值
  7. sbit drv=P3^4;//定义输出驱动端
  8. bit set_flag;//定义工作标志
  9. bit out_flag;//定义输出标志
  10. bit keydown_flag;//键按下标志
  11. /****************************/
  12. void delay(uint k)
  13. {
  14. uint i,j;
  15. for(i=0;i<k;i++){
  16. for(j=0;j<5;j++)
  17. {;}}
  18. }
  19. /**********************************************/
  20. void scan_key(void)          //扫描S1~S5键子程序开始
  21. {uchar i,m=0x08;         //定义两个字符型局部变量,并赋值0x01给m
  22. P3_6=0;P3_7=1;                //禁止发送给显示器,消隐有效
  23. for(i=0;i<5;i++)        //循环5次
  24. {
  25. SBUF=255-m;while(!TI);TI=0;         //依次发送数据使IC2的输出从右至左的列线为0
  26. if(!P3_5)pre_cnt[i]++;                 //若检测到P3.5为0,说明某列线送出0时与连接
  27.                              //该列线的按键被按下,数组中对应的存放单元加1
  28. m<<=1;                                                //m的取值使从右向左的下一条列线为0
  29. }                                                        //扫描S1~S5键子程序结束
  30. //------------------------
  31. for(i=0;i<5;i++)                              //循环5次        
  32. {if(pre_cnt[i]>9)pre_cnt[i]=0;}                  //对数组中的5个单元进行调整,其范围为0~9
  33. }
  34. /************************************/
  35. void dis_cnter(void)                                 //显示计数器值子程序开始
  36. {uchar i;                                                         //定义字符型局部变量i
  37. P3_7=1;P3_6=1;                                                 //消隐有效,允许显示
  38. for(i=0;i<5;i++)                                         //循环5次
  39. {SBUF=SEG7[cnt[i]];while(!TI);TI=0;}  //根据8个单元的计数值查表发送显示
  40. P3_7=0;                                                                  //关闭消隐,正常显示
  41. }                                                                          //显示计数器值子程序结束
  42. /**********************************************/
  43. void dis_pre_cnter(void)
  44. {uchar i;
  45. P3_7=1;P3_6=1;
  46. SBUF=SEG7[pre_cnt[0]]&0xfe;while(!TI);TI=0;
  47. //----------------------------------------
  48. for(i=1;i<5;i++)
  49. {SBUF=SEG7[pre_cnt[i]];while(!TI);TI=0;}
  50. P3_7=0;
  51. }
  52. /****************************************/
  53. void cnter(void)                                                 //计数转换子程序开始
  54. {uchar i;                                                                 //定义字符型局部变量i
  55. for(i=0;i<4;i++)                                                 //循环5次
  56. {if(cnt[i]>9){cnt[i]=0;cnt[i+1]++;}}         //若计数器某位值大于9,则该位回0,
  57. //------------------------------------         //而高位被进位加1
  58. if(cnt[4]>9){for(i=0;i<5;i++)cnt[i]=0;}// 若计数器最高位值大于9,则计数器全清0
  59. }                                                                           //计数转换子程序结束
  60. /***************************************************/
  61. void pt_cnt(void)                                           //输出控制子程序开始
  62. {
  63. 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]))        
  64.            //若计数值等于预置值
  65. out_flag=1;        
  66. //drv=1;                                                                           //输出标志置1
  67.         else out_flag=0;                                                          //否则输出标志置0
  68. //==========================
  69. if(out_flag)drv=0;                                                                 //若输出标志为1,输出端(P3.4)置0,驱动光耦U2
  70. else drv=1;                                                         //若输出标志为1,输出端(P3.4)置0,驱动光耦U2                                                                                 //否则输出端(P3.4)置1
  71. }                                                                                                 //输出控制子程序结束
  72. /********************************************/
  73. void main(void)                                                                        //主程序开始
  74. {        IE=0x84;                                                                   //开放CPU中断,开放外中断1的中断
  75.         IT1=1;                                                                           //置外中断1为边沿触发
  76.         while(1)                                                                   //无限循环
  77.         {P3_6=0;P3_7=1;                                                           //禁止发送给显示器,消隐有效
  78.         SBUF=0x00;while(!TI);TI=0;                                  //向IC2发送0x00,使IC2输出为全0
  79.         if((P3&0x24)!=0x24)keydown_flag=1;                  //检测P3.2、P3.5是否为高电平。
  80.                                                                                           //若不为高电平,说明有键按下,键被按下标志置1
  81.         else keydown_flag=0;                                          //否则,键被按下标志置0
  82.         //--------------------------
  83.         SBUF=0xfe;while(!TI);TI=0;                                 //向IC2发送0xfe
  84.         if(!P3_2)set_flag=!set_flag;                         //若P3.2为0,说明S9键按下,标志set_flag取反
  85.         //=============================================
  86.         if(!set_flag){cnter();dis_cnter();
  87.         pt_cnt();delay(100);}                       //若标志set_flag为0,调用计数、显示计数、输出控制的子程序
  88.         else {scan_key();dis_pre_cnter();delay(10);}//否则标志set_flag为1,调用扫描S1~S8键、显示预置值的子程序
  89.         //=============================================
  90.         if(keydown_flag)delay(300);         //因有键按下,调用延时300mS子程序,
  91.         }                                                         //以免调整键值的速度过快
  92. }                                                                 //主程序结束
  93. /************************************************/
  94. void extern_int1(void) interrupt 2 using 1
  95. {
  96. cnt[0]++;
  97. }
复制代码

现在如果直接用以上编译出来的程序的话,上电没显示。请教坛内大神。这程序还要修改什么地方才可以移植到如上图的应用中。谢了!


回复

使用道具 举报

ID:46999 发表于 2017-3-3 18:59 | 显示全部楼层
想吃小红帽的狼 发表于 2017-3-3 18:31
只要把15单片机IO口配置成普通IO,然后下载的时候,将晶振频率选择12MHz就可以

感谢!原程序是6M的晶振
回复

使用道具 举报

ID:46999 发表于 2017-3-3 18:57 | 显示全部楼层
本帖最后由 维超 于 2017-3-3 19:37 编辑
wosiyabo 发表于 2017-3-3 16:59
我把IO脚配置了一下,你再试试
#include "reg51.h"
//#include "intrins.h"

非常感谢你的帮助。下载试了还是一样的。数码管关断状态,没显示

数码管关断状态

数码管关断状态

回复

使用道具 举报

ID:164339 发表于 2017-3-3 18:31 | 显示全部楼层
只要把15单片机IO口配置成普通IO,然后下载的时候,将晶振频率选择12MHz就可以
回复

使用道具 举报

ID:46999 发表于 2017-3-3 18:02 | 显示全部楼层
wosiyabo 发表于 2017-3-3 16:59
我把IO脚配置了一下,你再试试
#include "reg51.h"
//#include "intrins.h"

感谢,晚上试下。
回复

使用道具 举报

ID:146949 发表于 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 收起 理由
perfect123 + 15 很给力!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表