找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1932|回复: 8
收起左侧

请教STC15单片机串口4的发送数据的程序问题

[复制链接]
ID:899981 发表于 2022-6-27 15:04 | 显示全部楼层 |阅读模式
如题,只发一次就不发了。单片机代码如下:

void serial_port4_initial(){

        S4CON = 0x10;                //8位数据,可变波特率
        S4CON |= 0x40;                //串口4选择定时器4为波特率发生器
        T4T3M &= 0xDF;                //定时器时钟12T模式
        T4L = 0xDD;                //设置定时初始值
        T4H = 0xFF;                //设置定时初始值
        T4T3M |= 0x80;                //定时器4开始计时

        IE2 |= 0x10;         //ES4 = 1;
        P_SW2=0x04;         //串口2、3、4的位置
        EA = 1;

}


void send_UART4(uchar dat)
{
         uchar temp = 0;
        

        S4CON = S4CON & 0xfd;  //S4TI = 0;

                S4BUF = dat;
                do
                {
                        temp = S4CON;
                        temp = temp & 0x02;                //temp=S2TI
                }while(temp == 0);
                S4CON = S4CON & 0xfd;            //S4TI = 0;
        

}

主函数:
serial_port4_initial();
        while(1)
        {        


                delayms(500);
        
                send_UART4(0X28);
               
        }        
意思是500毫秒发一次,结果发一次就不发了。  
回复

使用道具 举报

ID:913577 发表于 2022-6-27 16:34 | 显示全部楼层
看下delayms函数,可能是这个函数的问题
回复

使用道具 举报

ID:899981 发表于 2022-6-27 17:37 | 显示全部楼层
mornbin 发表于 2022-6-27 16:34
看下delayms函数,可能是这个函数的问题

谢谢,是这里问题:
void Usart4() interrupt 18
{
        UART4_INT_DISABLE();       
        if(RI4)
        {
                CLR_RI4();                               //清除RI位
               
        }
        void Usart4() interrupt 18
{
        UART4_INT_DISABLE();       
        if(RI4)
        {
                CLR_RI4();                               //清除RI位
               
        }
        UART4_INT_ENABLE();       
}       
}要把这个加上,但现在是报警告,UART4_INT_ENABLE();UART4_INT_DISABLE();        这两个警告不管能发,然后定义这两个就不能发。 //#define                UART4_INT_DISABLE()                IE2 &= ~(1<<4)        //允许串口3中断
回复

使用道具 举报

ID:161164 发表于 2022-6-27 17:49 | 显示全部楼层
定义运算,要加";"号于结尾
#define  UART4_INT_DISABLE() IE2 &= ~(1<<4);        //允许串口3中断
回复

使用道具 举报

ID:899981 发表于 2022-6-27 18:52 | 显示全部楼层
lkc8210 发表于 2022-6-27 17:49
定义运算,要加";"号于结尾
#define  UART4_INT_DISABLE() IE2 &= ~(1

谢谢,加不加这个好像不影响。
回复

使用道具 举报

ID:401564 发表于 2022-6-27 20:29 | 显示全部楼层
既然串口用了中断,就不用再在发送函数中等待发送完成
因为,一旦发送完成,优先是进入中断的,我不知道中断触发后,不清除中断标志位(S4TI),程序会不会是一直卡在中断中
个人感觉就是因为S4TI没有清除,而你又开了中断,所以,程序是发送一次之后,中断触发了,就一直卡在中断中出不来了
推荐增加一个中断标志位,然后在中断触发后清除
while(busy);busy=1;S4BUF = dat;


busy在串口中断触发后,在中断中清除,并清除S4TI
这样可以提高中断的效率
回复

使用道具 举报

ID:899981 发表于 2022-6-28 10:09 | 显示全部楼层
本帖最后由 ZHAOBAO511 于 2022-6-28 10:16 编辑
Y_G_G 发表于 2022-6-27 20:29
既然串口用了中断,就不用再在发送函数中等待发送完成
因为,一旦发送完成,优先是进入中断的,我不知道中断触 ...

谢谢,您这个方法可以,已正常运行,谢谢。
回复

使用道具 举报

ID:1080312 发表于 2023-5-28 00:06 | 显示全部楼层
mornbin 发表于 2022-6-27 16:34
看下delayms函数,可能是这个函数的问题

能帮我看看吗?我用的是串口3进行数据收发。但串口3只能发,外面的数据读进不了单片机中。
void UART3_Init()
{       
    P_SW2 &= ~S3_S0;                  //切换到 P0.0\P0.1
        S3CON = 0x10;                //8位数据,可变波特率;允许接收
        //S3CON &= 0xBF;                //串口3选择定时器2为波特率发生器
        T2L = 0xE0;                   //设置定时初始值
        T2H = 0xFE;                   //设置定时初始值
    AUXR = 0x14;       //T2为1T模式, 并启动定时器2
    IE2 = 0x08;         //使能串口3中断
    EA = 1;
}

void uart3_inte() interrupt 17
{
   unsigned char num=0;
    //接收
   if(S3CON & 0x02)                   //发送中断标志S3TI=1
   {
      S3CON &=0xFD;;           //发送中断标志清零S3TI=0
     
          if (S3CON & 0x01)
      {
        S3CON &=0xFE;        //清除S3TI位
                //R_table[count]=S3BUF;    //busy=0;
                num = S3BUF;
                num++;
                S3BUF = num;                                //返回数值
      }           
   }
}
回复

使用道具 举报

ID:1080312 发表于 2023-5-28 00:09 | 显示全部楼层
lkc8210 发表于 2022-6-27 17:49
定义运算,要加";"号于结尾
#define  UART4_INT_DISABLE() IE2 &= ~(1

大佬,我这个用串口3收发数据,但现在只能收,发的单片机读不进去。现在不知道啥原因?求教
void UART3_Init()
{       
    P_SW2 &= ~S3_S0;                  //切换到 P0.0\P0.1
        S3CON = 0x10;                //8位数据,可变波特率;允许接收
        //S3CON &= 0xBF;                //串口3选择定时器2为波特率发生器
        T2L = 0xE0;                   //设置定时初始值
        T2H = 0xFE;                   //设置定时初始值
    AUXR = 0x14;       //T2为1T模式, 并启动定时器2
    IE2 = 0x08;         //使能串口3中断
    EA = 1;
}

void uart3_inte() interrupt 17
{
   unsigned char num=0;
    //接收
   if(S3CON & 0x02)                   //发送中断标志S3TI=1
   {
      S3CON &=0xFD;;           //发送中断标志清零S3TI=0
     
          if (S3CON & 0x01)
      {
        S3CON &=0xFE;        //清除S3TI位
                //R_table[count]=S3BUF;    //busy=0;
                num = S3BUF;
                num++;
                S3BUF = num;                                //返回数值
      }           
   }
}
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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