YangHY 发表于 2026-2-14 18:55:03

数据的长度一般是8N1:

YangHY 发表于 2026-2-14 19:15:03

上面,左边配置的时候选8N1,右边是串口助手,选项也要是8N1 ,波特率什么的都要一样哦
实验用自动生成:
void Uart2_Isr(void) interrupt 8
{
        if (S2CON & 0x02)        //检测串口2发送中断
        {
                S2CON &= ~0x02;        //清除串口2发送中断请求位
        }
        if (S2CON & 0x01)        //检测串口2接收中断
        {
                S2CON &= ~0x01;        //清除串口2接收中断请求位
        }
}

void Uart2_Init(void)        //9600bps@22.1184MHz
{
        S2CON = 0x50;                //8位数据,可变波特率
        AUXR |= 0x04;                //定时器时钟1T模式
        T2L = 0xC0;                        //设置定时初始值
        T2H = 0xFD;                        //设置定时初始值
        AUXR |= 0x10;                //定时器2开始计时
        IE2 |= 0x01;                //使能串口2中断
}

YangHY 发表于 2026-2-14 19:20:42

我们新建一对文件:
uart.c 和uart,和 uart.h

.C文件内容如下:

#include "usart.h"
#include "io.h"


u8 Rec_Dat;                //接收缓冲区
u8 Rec_Num = 0;                //接收计数
bit B_TX2_Busy=0;
void Uart2_Isr(void) interrupt 8
{
        if (S2CON & 0x02)        //检测串口2发送中断
        {
                S2CON &= ~0x02;        //清除串口2发送中断请求位
                B_TX2_Busy = 0;
        }
        if (S2CON & 0x01)        //检测串口2接收中断
        {
                S2CON &= ~0x01;        //清除串口2接收中断请求位
               
                //S2BUF
                Rec_Dat = S2BUF;
        }
}


void Uart2_Init(void)        //9600bps@24.000MHz
{
       
        P_SW2 |= 0x01;                                                //UART2/USART2: RxD2(P4.6), TxD2
       
        S2CON = 0x50;                //8位数据,可变波特率
        AUXR |= 0x04;                //定时器时钟1T模式
        T2L = 0x8F;                        //设置定时初始值
        T2H = 0xFD;                        //设置定时初始值
        AUXR |= 0x10;                //定时器2开始计时
        IE2 |= 0x01;                //使能串口2中断
       
        Rec_Num = 0;
        B_TX2_Busy = 0;
}

void Uart2_SendStr( u8 *puts )                //串口数据发送函数
{
    for (; *puts != 0;puts++)   //遇到停止符0结束
    {
      S2BUF = *puts;
      B_TX2_Busy = 1;
      while(B_TX2_Busy);
    }       
}

//1.发送OPEN\r\n打开数码管,数码管显示“- - - -” 11 22 OPEN\r\n
//2.发送CLOSE\r\n打开数码管,数码管全部熄灭


void Usart2_RunTask(void)
{
        if( Rec_Num >= 6 )                //是否接收到了6位以上的数据
        {
                if(( Rec_Dat == '\n' ) && ( Rec_Dat == '\r' ) )        //末尾判断
                {
                        if( ( Rec_Dat == 'O' ) && ( Rec_Dat == 'P' ) && ( Rec_Dat == 'E' ) && ( Rec_Dat == 'N' ))
                        {
                                passward = 16;
                                passward = 16;
                                passward = 16;
                                passward = 16;
                                Uart2_SendStr( "打开成功!\r\n" );
                        }
                        else if( ( Rec_Dat == 'C' ) && ( Rec_Dat == 'L' ) && ( Rec_Dat == 'O' ) && ( Rec_Dat == 'S' ) && ( Rec_Dat == 'E' ))
                        {
                                passward = 17;
                                passward = 17;
                                passward = 17;
                                passward = 17;
                                Uart2_SendStr( "关闭成功!\r\n" );
                        }
                        Rec_Num = 0;
                }
        }
}


YangHY 发表于 2026-2-14 19:23:41

uart.h文件如下:

#ifndef __USART_H
#define __USART_H

#include "config.h"                        //调用头文件

       
void Uart2_Init(void);        //9600bps@24.000MHz
void Usart2_RunTask(void);


#endif

YangHY 发表于 2026-2-14 19:27:05

改引脚在功能脚切换:

YangHY 发表于 2026-2-14 19:32:39

实际我们要这2行代码:
        P_SW2 |= 0x01;                                                //UART2/USART2: RxD2(P4.2), TxD2(P4.3)
        CMOD &= ~0x60;                                                //CCP: ECI(P1.2), CCP0(P1.3), CCP1(P1.4), CCP2(P1.1)

目的是选P42 P43

记得在主函数调用:

void main(void)
{
        Sys_init();                                                                                //系统初始化
        usb_init();                                     //USB CDC 接口配置

    IE2 |= 0x80;                                    //使能USB中断
        Timer0_Init();                                                                        //定时器初始化
//        Init_595();
//        INT1_Init();                                                                        //外部中断1初始化
//        P3_IO_Init();                                                                        //IO中断初始化
//        P4_IO_Init();
       
        //TIM1_Count_Init();
        Timer1_Init();
        Uart2_Init();                                                                        //串口2初始化
       
    EA = 1;                                                                                        //IE |= 0X80;
       
        P40 = 0;
       
        while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置
//        WDT_CONTR = 0X24;
       
        while(1)
        {
               
      if (bUsbOutReady)                                                        //如果接收到了数据
      {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
                       
            usb_OUT_done();                                                        //
      }
                Task_Pro_Handler_Callback();                                //执行功能函数
               


        }
}

YangHY 发表于 2026-2-14 19:34:58

我们的认务是:

YangHY 发表于 2026-2-14 19:37:02

函数如下:
先建变量:

u8 Rec_Dat;                //接收缓冲区
u8 Rec_Num = 0;                //接收计数
bit B_TX2_Busy=0;

//1.发送OPEN\r\n打开数码管,数码管显示“- - - -” 11 22 OPEN\r\n
//2.发送CLOSE\r\n打开数码管,数码管全部熄灭


void Usart2_RunTask(void)
{
        if( Rec_Num >= 6 )                //是否接收到了6位以上的数据
        {
                if(( Rec_Dat == '\n' ) && ( Rec_Dat == '\r' ) )        //末尾判断
                {
                        if( ( Rec_Dat == 'O' ) && ( Rec_Dat == 'P' ) && ( Rec_Dat == 'E' ) && ( Rec_Dat == 'N' ))
                        {
                                passward = 16;
                                passward = 16;
                                passward = 16;
                                passward = 16;
                                Uart2_SendStr( "打开成功!\r\n" );
                        }
                        else if( ( Rec_Dat == 'C' ) && ( Rec_Dat == 'L' ) && ( Rec_Dat == 'O' ) && ( Rec_Dat == 'S' ) && ( Rec_Dat == 'E' ))
                        {
                                passward = 17;
                                passward = 17;
                                passward = 17;
                                passward = 17;
                                Uart2_SendStr( "关闭成功!\r\n" );
                        }
                        Rec_Num = 0;
                }
        }
}

YangHY 发表于 2026-2-14 19:40:08

单片机接受完一个字符后会触发中断:
我们在中断服务函数把刚接收到是字符保存起来:

oid Uart2_Isr(void) interrupt 8
{
        if (S2CON & 0x02)        //检测串口2发送中断
        {
                S2CON &= ~0x02;        //清除串口2发送中断请求位
                B_TX2_Busy = 0;
        }
        if (S2CON & 0x01)        //检测串口2接收中断
        {
                S2CON &= ~0x01;        //清除串口2接收中断请求位
               
                //S2BUF
                Rec_Dat = S2BUF;
        }
}

YangHY 发表于 2026-2-14 19:44:32

接着在处理接受的的数据时:

先判断长度是否>6,再看是否是结束“\r\n"?

void Usart2_RunTask(void)
{
        if( Rec_Num >= 6 )                //是否接收到了6位以上的数据
        {
                if(( Rec_Dat == '\n' ) && ( Rec_Dat == '\r' ) )        //末尾判断
                {
                        if( ( Rec_Dat == 'O' ) && ( Rec_Dat == 'P' ) && ( Rec_Dat == 'E' ) && ( Rec_Dat == 'N' ))
                        {
                                passward = 16;
                                passward = 16;
                                passward = 16;
                                passward = 16;
                                Uart2_SendStr( "打开成功!\r\n" );
                        }
                        else if( ( Rec_Dat == 'C' ) && ( Rec_Dat == 'L' ) && ( Rec_Dat == 'O' ) && ( Rec_Dat == 'S' ) && ( Rec_Dat == 'E' ))
                        {
                                passward = 17;
                                passward = 17;
                                passward = 17;
                                passward = 17;
                                Uart2_SendStr( "关闭成功!\r\n" );
                        }
                        Rec_Num = 0;
                }
        }
}


页: 89 90 91 92 93 94 95 96 97 98 [99] 100 101 102 103 104
查看完整版本: 第一课 序言《AI8051U的特点》