微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 请大神帮忙看下这个程序

请大神帮忙看下这个程序

时间:10-02 整理:3721RD 点击:

/*---------------------------------------------------------------------*/

/* --- STC MCU Limited ------------------------------------------------*/

/* --- STC15F4K60S4 系列 定时器1用作串口1的波特率发生器举例------------*/

/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序        */

/* 如果要在文章中应用此代码,请在文章中注明使用了STC的资料及程序        */

/*---------------------------------------------------------------------*/


//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译

//若无特别说明,工作频率一般为11.0592MHz


#include "reg51.h"

#include "intrins.h"


typedef unsigned char BYTE;

typedef unsigned int WORD;


#define FOSC 11059200L          //系统频率

#define BAUD 115200             //串口波特率


#define NONE_PARITY     0       //无校验

#define ODD_PARITY      1       //奇校验

#define EVEN_PARITY     2       //偶校验

#define MARK_PARITY     3       //标记校验

#define SPACE_PARITY    4       //空白校验


#define PARITYBIT EVEN_PARITY   //定义校验位


sfr AUXR  = 0x8e;               //辅助寄存器


sfr P_SW1   = 0xA2;             //外设功能切换寄存器1


#define S1_S0 0x40              //P_SW1.6

#define S1_S1 0x80              //P_SW1.7


sbit P22 = P2^2;


bit busy;


void SendData(BYTE dat);

void SendString(char *s);


void main()

{

    ACC = P_SW1;//0xA2

    ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=0

    P_SW1 = ACC;  //0x22              //(P3.0/RxD, P3.1/TxD)


//  ACC = P_SW1;

//  ACC &= ~(S1_S0 | S1_S1);    //S1_S0=1 S1_S1=0

//  ACC |= S1_S0;               //(P3.6/RxD_2, P3.7/TxD_2)

//  P_SW1 = ACC;  

//  

//  ACC = P_SW1;

//  ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=1

//  ACC |= S1_S1;               //(P1.6/RxD_3, P1.7/TxD_3)

//  P_SW1 = ACC;  


#if (PARITYBIT == NONE_PARITY)

    SCON = 0x50;                //8位可变波特率

#elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)

    SCON = 0xda;                //9位可变波特率,校验位初始为1

#elif (PARITYBIT == SPACE_PARITY)

    SCON = 0xd2;                //9位可变波特率,校验位初始为0

#endif


    AUXR = 0x40;                //定时器1为1T模式

    TMOD = 0x20;                //定时器1为模式2(8位自动重载)

    TL1 = (256 - (FOSC/32/BAUD));   //设置波特率重装值

    TH1 = (256 - (FOSC/32/BAUD));

    TR1 = 1;                    //定时器1开始工作

    ES = 1;                     //使能串口中断

    EA = 1;


    SendString("STC15F2K60S2\r\nUart Test !\r\n");

    while(1);

}


/*----------------------------

UART 中断服务程序

-----------------------------*/

void Uart() interrupt 4 using 1

{

    if (RI)

    {

        RI = 0;                 //清除RI位

        P0 = SBUF;              //P0显示串口数据

        P22 = RB8;              //P2.2显示校验位

    }

    if (TI)

    {

        TI = 0;                 //清除TI位

        busy = 0;               //清忙标志

    }

}


/*----------------------------

发送串口数据

----------------------------*/

void SendData(BYTE dat)

{

    while (busy);               //等待前面的数据发送完成

    ACC = dat;                  //获取校验位P (PSW.0)

    if (P)   //P是PSW的奇偶标志位   //根据P来设置校验位

    {

#if (PARITYBIT == ODD_PARITY)

        TB8 = 0;                //设置校验位为0

#elif (PARITYBIT == EVEN_PARITY)

        TB8 = 1;                //设置校验位为1

#endif

    }

    else

    {

#if (PARITYBIT == ODD_PARITY)

        TB8 = 1;                //设置校验位为1

#elif (PARITYBIT == EVEN_PARITY)

        TB8 = 0;                //设置校验位为0

#endif

    }

    busy = 1;

    SBUF = ACC;                 //写数据到UART数据寄存器

}


/*----------------------------

发送字符串

----------------------------*/

void SendString(char *s)

{

    while (*s)                  //检测字符串结束标志

    {

        SendData(*s++);         //发送当前字符

    }

}

有几个问题不太懂,

问题1,   #define NONE_PARITY     0       //无校验

#define ODD_PARITY      1       //奇校验

#define EVEN_PARITY     2       //偶校验

#define MARK_PARITY     3       //标记校验

#define SPACE_PARITY    4       //空白校验


#define PARITYBIT EVEN_PARITY   //定义校验位


这一块感觉比较陌生  不知道怎么去理解?


问题2,

sfr AUXR  = 0x8e;               //辅助寄存器


sfr P_SW1   = 0xA2;             //外设功能切换寄存器1


#define S1_S0 0x40              //P_SW1.6

#define S1_S1 0x80              //P_SW1.7

这里又定义了两个特殊功能寄存器,AUXR  P_SW1  首先我不明白为什么要定义这两个寄存器,他们有什么作用?因为我在书上没有找到这两个寄存器!  再者  51单片机的21个特殊功能寄存器不是连地址都确定了吗,这种特殊功能寄存器还能自定义吗?

其次,后面的 S1_S0 0x40  P-sw1.6代表的又是什么?  包括S1_S1 0x80  //P_SW1.7代表的又是什么?


问题3,

  ACC = P_SW1;//0xA2

    ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=0

    P_SW1 = ACC;  //0x22              //(P3.0/RxD, P3.1/TxD)

    刚进入主函数时的这几句该怎么理解  其作用是什么?


问题4,

#if (PARITYBIT == NONE_PARITY)

    SCON = 0x50;                //8位可变波特率

#elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)

    SCON = 0xda;                //9位可变波特率,校验位初始为1

#elif (PARITYBIT == SPACE_PARITY)

    SCON = 0xd2;                //9位可变波特率,校验位初始为0

#endif

根据前面的宏定义  NONE_PARITY  代表0 ,ODD_PARITY  代表1 ,EVEN_PARITY  代表2 (好像 PARITYBIT也是2), MARK_PARITY代表3  ,SPACE_PARITY代表4,各代表的数据均已明确,那么#if (PARITYBIT == NONE_PARITY)  ,#elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)  ,#elif (PARITYBIT == SPACE_PARITY)这些条件判断语句又有什么意义呢?


暂时只发现这些问题,这些问题已经困扰我很多天了  ,真心希望 知道的高手能帮忙解答一下 ,先谢谢了 !(那种求知却又不知的痛苦相信很多人都体会过)



#if语句是预处理,if后面的语句成立,编译器便对该条件下的语句进行编译,否则忽略掉。

哦  谢谢  有些问题 我也慢慢弄明白了

小编在吗?我现在也发现了这个问题,也想问你提出的同样问题,可以求教一下吗,帅哥可以留个联系方式吗?或者留下我的。我的qq号915012508,在此谢过了

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

网站地图

Top