找回密码
 立即注册
查看: 75|回复: 5

AI8h8k64u进行测距问题?

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-06-08 08:46:56
已绑定手机

1

主题

3

回帖

19

积分

新手上路

积分
19
发表于 2025-6-7 18:23:46 来自手机 | 显示全部楼层 |阅读模式
使用8h单片机(开天斧)连接超声模块进行测距,只测了一下,然后就当机了,无论怎么移动超声模块都是第一次测距结果。把这个代码一点也不改动,刷到stc89c52上,可以正常测距,改变距离立刻有显示。请大家帮忙分析一下,可能哪里出了问题?
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:468
  • 最近打卡:2025-06-16 07:06:57
已绑定手机

79

主题

5131

回帖

9138

积分

超级版主

DebugLab

积分
9138
发表于 2025-6-7 22:33:42 | 显示全部楼层
IO模式和运行速度有区别
新手必读:
https://www.stcaimcu.com/thread-16535-1-1.html
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-06-08 08:46:56
已绑定手机

1

主题

3

回帖

19

积分

新手上路

积分
19
发表于 2025-6-8 08:46:56 | 显示全部楼层
请大家帮忙看下,是代码有什么问题吗?

此代码在STC89C52下运行完全正常,但是用开天斧时,只测了一次就卡住不动了,不知什么原因?

请高手赐教!

#include <stc8H.H>
#include <math.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

bit flag=0;

sbit DIO = P6^5;                //HC595串行数据口               
sbit RCLK  = P6^6;                               
sbit SCLK = P6^7;
                               
sbit LED2=P2^0;                //指示灯

sbit Trig=P2^4;
sbit Echo=P2^5;

unsigned char code DSP[] =
{// 0         1          2           3        4         5          6           7        8         9          A           b        C    d          E    F    -
        0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x8C,0xBF,0xC6,0xA1,0x86,0xFF,0xbf,
        0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10
// 0.   1.   2.   3.   4.   5.   6.   7.   8.   9.
};

uchar LED[4]={4,3,2,1};                           //显示缓存区

void Delay10us(void)        //@12.000MHz
{
        unsigned char data i;
        _nop_();
        _nop_();
        i = 30;
        while (--i);
}

float measure()
{   uint time = 0;
    float distance=0.0;
   
    // 发送10us高电平触发信号
    Trig = 1;
    Delay10us();
    Trig = 0;
   
    // 等待回波信号变高
    while(!Echo);
    // 开始计时
    TR1=1;
    while(Echo & !TF1);
    // 停止计时
        TR1=0;
    if(TF1){
          distance=0;
      TF1=0;
        }
        else{
            // 计算时间(us)
            time = TH1<<8|TL1;            
            // 计算距离(cm) 声速340m/s=0.034cm/us
            distance = time * 0.017; // 往返时间/2
    }  
        TH1 = 0;
        TL1 = 0;
    return distance;
}

void Timer0_Init(void)                //1毫秒@11.0592MHz
{
        AUXR &= 0x7F;                        //定时器时钟12T模式
        TMOD &= 0xF0;                        //设置定时器模式
        TL0 = 0x66;                                //设置定时初始值
        TH0 = 0xFC;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        ET0 = 1;                                //使能定时器0中断
        EA = 1;
}


void Snoic_Init(){
        AUXR &= 0xBF;                        //定时器时钟12T模式
        TMOD &= 0x0F;                        //设置定时器模式
        TMOD |= 0x10;                        //设置定时器模式
        TL1 = 0;                                //设置定时初始值
        TH1 = 0;                                //设置定时初始值
        TF1 = 0;                                //清除TF1标志
}


void LED_OUT(unsigned char X)
{
        unsigned char i;
        for(i=8;i>=1;i--)
        {
                X<<=1;
                DIO=CY;       
                SCLK = 0;
                SCLK = 1;
        }
}


void Display()
{
        uchar i;
        for(i=0;i<4;i++){
            LED_OUT(DSP[LED[i]]);                       
            LED_OUT(pow(2,i));               
              RCLK = 0;
            RCLK = 1;
        }  
}


void main (void)
{
        int dist;
    P0M0 = 0x00; P0M1 = 0x00;
    P1M0 = 0x00; P1M1 = 0x00;
    P2M0 = 0x10; P2M1 = 0x20;
    P3M0 = 0x00; P3M1 = 0x00;
    P4M0 = 0x00; P4M1 = 0x00;
    P5M0 = 0x00; P5M1 = 0x00;
    P6M0 = 0x00; P6M1 = 0x00;
    P7M0 = 0x00; P7M1 = 0x00;

        Timer0_Init();
        Snoic_Init();
        while(1)
        {
         if(flag)   //每50毫秒测距一次
          {
            flag=0;
                dist =(int)(measure()*10);
          
                 LED[3]=dist/1000;
                 LED[2]=dist%1000/100;
                 LED[1]=dist%100/10+17;
                 LED[0]=dist%10;
                 LED2=~LED2;                 //LED2
          }       
        }
}

void Timer0_Isr(void) interrupt 1
{
        static uchar k;
        k++;
        if(k%3==0){             
          Display();         //3毫秒刷新显示
        }
        if(k%50==0)                 //50毫秒测距一次
          flag=1;
        k%=150;
}
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-06-08 08:46:56
已绑定手机

1

主题

3

回帖

19

积分

新手上路

积分
19
发表于 2025-6-8 08:47:34 | 显示全部楼层
Debu*** 发表于 2025-6-7 22:33
IO模式和运行速度有区别
新手必读:
https://www.stcaimcu.com/thread-16535-1-1.html

请帮忙看下代码,这里有什么潜在的问题吗?
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-06-08 08:46:56
已绑定手机

1

主题

3

回帖

19

积分

新手上路

积分
19
发表于 2025-6-8 13:05:03 | 显示全部楼层
这个问题困扰了很长时间,今天终于解决了,主要原因是在定时器0的中断里调用了显示子函数Display(),是他造成的当机。我把这个子程序放在主循环里就好了。但是不知道为什么在STC89C52中,即使在中断中调用了显示子函数仍能正确执行程序!请大家伙帮忙看看是什么具体原因!

点评

可能是有意外的进位操作CY被修改了,具体需要查看生成的汇编代码 以下是之前写的语音播报超声波测距程序供参考 超声波测距受温度影响,加入温度补偿更精确 excel超声波测距计算:  详情 回复 发表于 6 天前
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:468
  • 最近打卡:2025-06-16 07:06:57
已绑定手机

79

主题

5131

回帖

9138

积分

超级版主

DebugLab

积分
9138
发表于 6 天前 | 显示全部楼层
lnjzbra*** 发表于 2025-6-8 13:05
这个问题困扰了很长时间,今天终于解决了,主要原因是在定时器0的中断里调用了显示子函数Display(),是他造 ...

可能是有意外的进位操作CY被修改了,具体需要查看生成的汇编代码
以下是之前写的语音播报超声波测距程序供参考
  1. #include <STC8.H>
  2. #include <intrins.h>
  3. #define         TRIG        P30
  4. #define         ECHO        P31
  5. #define         BUSY        P32
  6. #define                DATA        P33
  7. #define                RST                P54
  8. #define                KEY                P55
  9. #define                BANDGAP        1188UL
  10. //                1                2                3                4                5                6                7                8
  11. //                无                一                二                三                四                五                六                七
  12. //                9                10                11                12                13                14                15                16
  13. //                八                九                十                百                点                当前        设置        距离
  14. //                17                18                19                20                21                22                23                24
  15. //                电压        电流        水位        温度        重量        单价        总价        厘米
  16. //                25                26                27                28                29                30                31                32
  17. //                米                伏                安                度                千克        元                零                滴
  18. bit Error;
  19. unsigned int Distance,Voltage;
  20. unsigned char Lenth,Play_Pointer,Buff_Pointer;
  21. unsigned char Number[10]={31,2,3,4,5,6,7,8,9,10};
  22. unsigned char Buff[16];
  23. unsigned int Integer,Decimal;
  24. /*----------------------------延时10us@STC-Y6@6MHz----------------------------*/
  25. void Delay_10us(void)
  26. {
  27.         unsigned char i;
  28.         i=18;
  29.         while(--i);
  30. }
  31. /*----------------------------延时x10us----------------------------*/
  32. void Delay_x10us(unsigned char x)
  33. {
  34.         while(x--)
  35.                 Delay_10us();
  36. }
  37. void Send(unsigned char x)
  38. {
  39.         unsigned char i;
  40.         RST=1;
  41.         Delay_x10us(10);
  42.         RST=0;
  43.         Delay_x10us(10);
  44.         for(i=0;i<x;i++)
  45.         {
  46.                 DATA=1;
  47.                 Delay_x10us(10);
  48.                 DATA=0;
  49.                 Delay_x10us(10);
  50.         }
  51.         Delay_x10us(10);
  52. }
  53. void Speak_Function(unsigned char x)
  54. {
  55.         Buff[Buff_Pointer]=x;
  56.         Buff_Pointer++;
  57. }
  58. void Speak_Number(unsigned char x)
  59. {
  60.         unsigned char integer_2,integer_1,integer_0,decimal_1,decimal_2,decimal_3;
  61.         integer_2=(unsigned char)(Integer%1000/100);
  62.         integer_1=(unsigned char)(Integer%100/10);
  63.         integer_0=(unsigned char)(Integer%10);
  64.         decimal_1=(unsigned char)(Decimal%1000/100);
  65.         decimal_2=(unsigned char)(Decimal%100/10);
  66.         decimal_3=(unsigned char)(Decimal%10);
  67.         if(integer_2>0)
  68.         {
  69.                 Speak_Function(Number[integer_2]);
  70.                 Speak_Function(12);
  71.                 if(integer_1==0)
  72.                 {
  73.                         if(integer_0!=0)
  74.                         {
  75.                                 Speak_Function(Number[integer_1]);
  76.                         }
  77.                 }
  78.                 else
  79.                 {
  80.                         Speak_Function(Number[integer_1]);
  81.                 }
  82.         }
  83.         else
  84.         {
  85.                 if(integer_1>1)
  86.                 {
  87.                         Speak_Function(Number[integer_1]);
  88.                 }
  89.         }
  90.         if(integer_1>0)
  91.         {
  92.                 Speak_Function(11);
  93.         }
  94.         if(integer_0==0)
  95.         {
  96.                 if(integer_2==0&&integer_1==0)
  97.                 {
  98.                         Speak_Function(Number[integer_0]);
  99.                 }
  100.         }
  101.         else
  102.         {
  103.                 Speak_Function(Number[integer_0]);
  104.         }
  105.         switch(x)
  106.         {
  107.                 case 1:
  108.                         Speak_Function(13);
  109.                         Speak_Function(Number[decimal_1]);
  110.                 break;
  111.                 case 2:
  112.                         Speak_Function(13);
  113.                         Speak_Function(Number[decimal_1]);
  114.                         Speak_Function(Number[decimal_2]);
  115.                 break;
  116.                 case 3:
  117.                         Speak_Function(13);
  118.                         Speak_Function(Number[decimal_1]);
  119.                         Speak_Function(Number[decimal_2]);
  120.                         Speak_Function(Number[decimal_3]);
  121.                 break;
  122.                 default:
  123.                 break;
  124.         }
  125. }
  126. void Speak(void)
  127. {
  128.         if(BUSY&&Lenth>0)
  129.         {
  130.                 Send(Buff[Play_Pointer]);
  131.                 Play_Pointer++;
  132.                 if(Play_Pointer==Lenth)
  133.                 {
  134.                         Play_Pointer=0;
  135.                         Lenth=0;
  136.                 }
  137.         }
  138. }
  139. void Speak_Distance(unsigned int temp)
  140. {
  141.         Buff_Pointer=0;
  142.         Integer=temp/10;
  143.         Decimal=temp%10*100;
  144.         Speak_Function(32);
  145.         Speak_Function(14);
  146.         Speak_Function(16);
  147.         Speak_Number(1);
  148.         Speak_Function(24);
  149.         Lenth=Buff_Pointer;
  150. }
  151. void Speak_Voltage(unsigned int temp)
  152. {
  153.         Buff_Pointer=0;
  154.         Integer=temp/1000;
  155.         Decimal=temp%1000;
  156.         Speak_Function(32);
  157.         Speak_Function(14);
  158.         Speak_Function(17);
  159.         Speak_Number(3);
  160.         Speak_Function(26);
  161.         Lenth=Buff_Pointer;
  162. }
  163. void Trig(void)
  164. {
  165.         TRIG=1;
  166.         Delay_x10us(100);
  167.         TRIG=0;
  168. }
  169. void Init(void)
  170. {
  171.         AUXR&=0x7F;                //设置定时器0时钟12T模式
  172.         TMOD=0x08;                //设置定时器模式:定时器0受INT0控制,16位自动重载模式
  173.         TF0=0;                        //清除定时器0中断标志
  174.         TH0=0;                        //初始化定时器0
  175.         TL0=0;                        //初始化定时器0
  176.         ET0=1;                        //打开定时器0中断
  177.         EA=1;                        //打开总中断
  178.         P3M0=0x00;                //初始化GPIO模式
  179.         P3M1=0x00;                //初始化GPIO模式
  180.         P5M0=0x00;                //初始化GPIO模式
  181.         P5M1=0x00;                //初始化GPIO模式
  182.         DATA=0;                        //初始化GPIO
  183.         RST=0;                        //初始化GPIO
  184.         TRIG=0;                        //初始化GPIO
  185.         Integer=0;                //初始化变量
  186.         Decimal=0;                //初始化变量
  187.         Error=0;                //初始化变量
  188.         ADCCFG=ADC_RESFMT;                //设置ADC转换结果右对齐,设置ADC时钟
  189.         ADC_CONTR=ADC_POWER|15;        //使能ADC
  190.         Delay_x10us(100);
  191.         ADC_CONTR|=ADC_START;        //启动ADC
  192.         while(!(ADC_CONTR&ADC_FLAG));
  193.         Voltage=ADC_RES<<8|ADC_RESL;
  194.         Voltage=BANDGAP*1024UL/Voltage;
  195.         Speak_Voltage(Voltage);
  196.         ADC_CONTR=0x00;
  197. }
  198. void main(void)
  199. {
  200.         Init();
  201.         while(1)
  202.         {
  203.                 if(!KEY&&!Lenth)
  204.                 {
  205.                         Error=0;
  206.                         TH0=0;
  207.                         TL0=0;
  208.                         Trig();
  209.                         while(!ECHO);
  210.                         TR0=1;
  211.                         while(ECHO);
  212.                         TR0=0;
  213.                         if(Error)
  214.                                 Distance=0;
  215.                         else
  216.                         {
  217.                                 Distance=TH0;
  218.                                 Distance<<=8;
  219.                                 Distance|=TL0;
  220.                                 Distance*=0.34645;
  221.                         }
  222.                         Speak_Distance(Distance);
  223.                 }
  224.                 Speak();
  225.         }
  226. }
  227. void Timer0_ISR(void) interrupt 1
  228. {
  229.         TR0=0;
  230.         TH0=0;
  231.         TL0=0;
  232.         Error=1;
  233. }
复制代码
超声波测距受温度影响,加入温度补偿更精确
excel超声波测距计算:

超声波测距计算.xlsx (9.48 KB, 下载次数: 0)


DebugLab
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-6-16 16:17 , Processed in 0.241978 second(s), 80 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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