微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 求助!请大神指导~~~~

求助!请大神指导~~~~

时间:10-02 整理:3721RD 点击:
* 利用单片机计算出1!+2!+3!+……+9!的结果。
程序:
#include <reg51.h>
#define INT8U        unsigned char
#define INT16U        unsigned int
code INT8U SEG_CODE[] = {0x3f,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//段码
code INT8U SEG_WEI[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位码
void delay_ms(INT16U x)
{
        INT8U t; while(x--) for(t = 0; t < 120; t++);
}//延时子程序
sbit d=P1^0;//位定义(控制段码信号的"门")
sbit w=P1^1; //位定义(控制位码信号的"门")
/*unsigned int*/long sum()
{
unsigned int i , j=1 ;
long s=0 ;
for(i=1;i<=9;i++)
{
  j*=i;
  s+=j;
}
  return s ;
}//求和子函数
void main()
{
unsigned int he;
he=sum();//在主函数中调用求和子函数
        while(1)
        {
                P0=0xff;
                w=1;
                P0=SEG_WEI[7];
                w=0;
                d=1;
                P0=SEG_CODE[he%10];
                d=0;
                delay_ms(5);//显示完个位
                P0=0xff;
                w=1;
                P0=SEG_WEI[6];
                w=0;
                d=1;
                P0=SEG_CODE[(he/10)%10];
                d=0;
                delay_ms(5);//显示完十位
                P0=0xff;
                w=1;
                P0=SEG_WEI[5];
                w=0;
                d=1;
                P0=SEG_CODE[(he/100)%10];
                d=0;
                delay_ms(5);//显示完百位
                P0=0xff;
                w=1;
                P0=SEG_WEI[4];
                w=0;
                d=1;
                P0=SEG_CODE[(he/1000)%10];
                d=0;
                delay_ms(5);//显示完千位
                P0=0xff;
                w=1;
                P0=SEG_WEI[3];
                w=0;
                d=1;
                P0=SEG_CODE[(he/10000)%10];
                d=0;
                delay_ms(5);//显示完万位
               
                P0=0xff;
                w=1;
                P0=SEG_WEI[2];
                w=0;
                d=1;
                P0=SEG_CODE[(he/100000)%10];
                d=0;
                delay_ms(5);//显示完十万位
                P0=0xff;
                w=1;
                P0=SEG_WEI[1];
                w=0;
                d=1;
                P0=SEG_CODE[(he/1000000)%10];
                d=0;
                delay_ms(5);//显示完百万位
                P0=0xff;
                w=1;
                P0=SEG_WEI[0];
                w=0;
                d=1;
                P0=SEG_CODE[he/10000000];
                d=0;
                delay_ms(5);//显示完千万位

                }
}

但是在proteus中仿真却出现这样的结果:

   
有两个问题:
1.为什么我在调试1!+2!+...+8!时结果都是正确的,而多一个9!时却发生这样的结果?
2.百万位和十万位一直都是8,怎样修改主函数才能得到没有问题的程序?
因为积分只有一分,所以希望大神不要见怪~~~~

keil C51中unsigned int类型是16位,最大值为65535。unsigned long为32位。long型变量与int型变量相乘是被当成int × int还是long×long,这个需要实际测试一下,这会影响计算结果。局部变量he是unsigned int型,1! + ... + 8! = 46233,< 65535可以准确表示。但+9!之后,结果是409113 > 65535,则高16位丢失,则he=15897,这与你显示的后5位一致。至于前面两个8,可能是除法运算错误导致的,这个我没验证过。
想要正确的结果,最简单的办法是把所有的变量,包括局部变量和全局变量,全部改为unsigned long类型。

将变量he改为long型试试

好像大部分的8位和16位单片机的编译器整型都是16位的。我也经常不小心弄错数据类型,特别是运算之后。如果有在线调试的功能,设置断点或单步运行,查看变量的值,一般来说会很快定位问题。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top