信明元 发表于 2024-2-2 16:05

求助贴,求大佬帮忙看看51的代码,一直解决不了串口和定时的冲突

#include <REGX52.H>

//蓝牙来控制舵机完成开关灯的操作。
#define uchar unsigned char
#define uint unsigned int
       
sbit SG90 = P2^0;// 定义舵机接口

uchar compare=0;//PWM比较参数
uchar count=0;                 //计数
uchar received_data=0; //蓝牙串口接收的数据

void Delay(uchar n)//定时1ms的函数
{
        uchar i,j;
        while(n--)
        {
                i=2;j=239;
        do{
                        while(j--);
        }while(i--);
        }
       
}       
void InitTimer0()        //250us,分成80个周期
{
    TMOD &=0xf0;
        TMOD|=0x01;
        TH0 = (65536-250) / 256;// 高字节设置
    TL0 = (65536-250) % 256;// 低字节设置
        TR0 = 1;// 启动定时器
    ET0 = 1;// 启用定时器中断
    EA = 1;   // 开启全局中断
       
       
}

void Serial_Init()// 串口初始化函数
{
   
    TMOD &= 0x0f;
        TMOD |= 0x20;// 设置定时器T1为模式2 (8位自动重装载)
    TH1 = 0xfd;//9600波特率
    TL1 = 0xfd;
    TR1 = 1;// 启动定时器T1

        SCON = 0x50;// 设置串口模式1,可变波特率,允许接收和发送       
    ES = 1;// 开启串口中断
        EA = 1;   // 开启全局中断
}

/*
分为80个小的间隔,周期为20ms
delay函数用于等待舵机完成角度转换
5对应大概62度左右
6对应90度
7对应大概112度左右
先让它从90->62->90,90->112->10;
*/
void Service_Serial() interrupt 4 // 串口中断服务函数,处理蓝牙模块发送的数据
{
    if (RI==1) {
      RI = 0;
      received_data = SBUF;
      switch(received_data)
                {
                        case ('1'):
                compare=5;                       
                Delay(500);                       
                compare=6;                               
                Delay(500);
                        break;
                       
                        case ('2'):
      compare=7;
                Delay(500);
                compare=6;
                Delay(500);
                        break;
                default:
                compare=5;
                Delay(500);
                compare=6;
                Delay(500);
                break;
                       
      }
    }
}

void Service_Timer0() interrupt 1
{
        TH0 = (65536-250) / 256;// 高字节设置
    TL0 = (65536-250) % 256;// 低字节设置
        count++;
        if(count<=compare)
        {
                SG90=1;
        }
        else
        {
                SG90=0;
                if(count>=80)
        {
                count=0;
        }
        }
       
       
}
void main()   
{
        InitTimer0();
        Serial_Init();
        compare=6; //初始化舵机在90度位置
        Delay(1000);// 延时一秒调整
        while(1)
        {
               
        }
       
}

LcwSwust 发表于 2024-2-3 11:24

串口中断里delay,使定时中断无法响应,中断嵌套了解一下。
建议加一句PT0=1;
或者在串口中断里收到数据置标志,主循环根据标志来处理指令。

njhill 发表于 2024-2-3 16:29

设置两个中断优先级高低。

linxi6414 发表于 2024-2-4 13:51

居然在中断里有delay?

steelen 发表于 2024-2-22 14:10

NB了你,居然在中断里有delay?
呵呵

梦幻泡影 发表于 2024-3-4 11:49

您可真是狠人呐,在中断服务里面使用delay,多少都不够翻车的。用变量来计数,再用标志位来判定就可以实现延时了,一定不能阻塞。
页: [1]
查看完整版本: 求助贴,求大佬帮忙看看51的代码,一直解决不了串口和定时的冲突