切换到宽版
  • 1493阅读
  • 10回复

[C51]小弟求大侠写个模拟程序,投影机RS232串口开机关机程序? [复制链接]

上一主题 下一主题
离线chenhuimzk
 

发帖
426
M币
17
专家
1
粉丝
12
— 本帖被 發騷友 从 汽车拆客 移动到本区(2018-01-12) —
吃灰很久的爱普生CB-X22投影机,最近有时间安装起来,打算用232串口开机和关机 。因为牵扯到投影机是隐藏式的,用的无线要控制打开门的,所以现在需要一个 232模拟器,实现投影机开机和关机。投影机移动到位后,给一个电平到单片机,单片机模拟信号投影机开机,在给一个电平给关机IO,投影机关机。单片机 stc15f104w

麻烦大侠帮小弟写下程序。








    功能就是;给开机IO电平,投影机就开机,给关机IO电平,就关机。



本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
离线elecfun

发帖
1331
M币
164
专家
12
粉丝
85
只看该作者 1楼 发表于: 01-12
用STC的工具生产的串口代码,不处理串口接收的数据,没验证过你自己测试下。
P3.1接电平转换电平后到投影仪的RS232,P3.2接开机控制上升沿有效,P3.3接关机控制上升沿有效




/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC15F4K60S4 系列 定时器1用作串口1的波特率发生器举例------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966-------------------------*/
/* --- Web: www.STCMCU.com --------------------------------------------*/
/* --- Web: www.GXWMCU.com --------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了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 9600             //串口波特率

#define NONE_PARITY     0       //无校验
#define ODD_PARITY      1       //奇校验
#define EVEN_PARITY     2       //偶校验
#define MARK_PARITY     3       //标记校验
#define SPACE_PARITY    4       //空白校验

#define PARITYBIT NONE_PARITY   //定义校验位

sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P4M1 = 0xb3;
sfr P4M0 = 0xb4;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
sfr P6M1 = 0xCB;
sfr P6M0 = 0xCC;
sfr P7M1 = 0xE1;
sfr P7M0 = 0xE2;

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;

#define PORT_KEY    P3
#define KEY_ON      0x04    //按键ON
#define KEY_OFF     0x08    //按键OFF
#define KEY_MASK    (PORT_KEY |= (KEY_ON | KEY_OFF))
unsigned char KeyShort;     //按键触发
unsigned char KeyLong;      //长按值
char code CMD_ON[]={0x50,0x57,0x52,0x20,0x4F,0x4E,0x0D,0x00};
char code CMD_OFF[]={0x50,0x57,0x52,0x20,0x4F,0x46,0x46,0x0D,0x00};

bit busy;

void SendData(BYTE dat);
void SendString(char *s);

void Delay(unsigned int t)
{
    unsigned int a,b;
    for (a=0; a<t; a++)
        for (b=0; b<500; b++)
            ;
}

//读按键值
void KeyRead( void )
{
    unsigned char ReadData = PORT_KEY ^ 0xFF;         //读端口值,并取反
    ReadData &= (KEY_ON | KEY_OFF);                //只取有效按键值
    KeyShort =  ReadData & (ReadData ^ KeyLong);    //只在第一次按下时为按键值,以后为0
    KeyLong  =  ReadData;                           //长按、短按都为按键值
}

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

    ACC = P_SW1;
    ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=0
    P_SW1 = ACC;                //(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;

    while(1)
    {
        KEY_MASK;
        KeyRead();
        if (KeyShort & KEY_ON)       //ON
        {
            SendString(CMD_ON);
        }
        if (KeyShort & KEY_OFF)      //OFF
        {
            SendString(CMD_OFF);
        }
        Delay(100);
    }
}

/*----------------------------
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来设置校验位
    {
#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条打赏专家+1
离线chenhuimzk

发帖
426
M币
17
专家
1
粉丝
12
只看该作者 2楼 发表于: 01-12
回 elecfun 的帖子
elecfun:用STC的工具生产的串口代码,不处理串口接收的数据,没验证过你自己测试下。
P3.1接电平转换电平后到投影仪的RS232,P3.2接开机控制上升沿有效,P3.3接关机控制上升沿有效
[table][tr][td]
....... (2018-01-12 13:41) 回 elecfun 的帖子

先感谢大侠,投影机232本来是需要3个线,RXD ,TXD , 地。

那么我单片机p3.1口出来后接投影机哪个上?RXD 或TXD?

实在不是不懂 只有在请教大侠了
离线ahyu99

发帖
2454
M币
5628
专家
5
粉丝
38
只看该作者 3楼 发表于: 01-12
你这个需要232芯片转换的。投影机上是RS-232接口,电平副值和你的单片机的TTL不同,所以需要MAX232之类的芯片转换才可以。
离线elecfun

发帖
1331
M币
164
专家
12
粉丝
85
只看该作者 4楼 发表于: 01-12
回 chenhuimzk 的帖子
chenhuimzk:
先感谢大侠,投影机232本来是需要3个线,RXD ,TXD , 地。
那么我单片机p3.1口出来后接投影机哪个上?RXD 或TXD?
....... 回 chenhuimzk 的帖子

单片机出来的是TTL电平,投影仪的是RS232电平,两个电平不一致,不能直接连接,需要用转换电路。
可以用MAX232这样的芯片,或者 简单点用下图,LINUX_TX接单片机的P3.1,TX_OUT接投影仪的RXD。3.3V_PD跟5V_PD接一起,都接单片机5V就行


本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
离线chenhuimzk

发帖
426
M币
17
专家
1
粉丝
12
只看该作者 5楼 发表于: 01-13


按照这个电路,做出来,应该可以吧?

串口哪里只要一根线?不需要地?
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
离线chenhuimzk

发帖
426
M币
17
专家
1
粉丝
12
只看该作者 6楼 发表于: 01-13
回 elecfun 的帖子
elecfun:单片机出来的是TTL电平,投影仪的是RS232电平,两个电平不一致,不能直接连接,需要用转换电路。
可以用MAX232这样的芯片,或者 简单点用下图,LINUX_TX接单片机的P3.1,TX_OUT接投影仪的RXD。3.3V_PD跟5V_PD接一起,都接单片机5V就行
[图片]
....... (2018-01-12 17:29) 回 elecfun 的帖子

按照这个电路,做出来,应该可以吧?

串口哪里只要一根线?
离线sayno_86

发帖
570
M币
4528
专家
18
粉丝
101
只看该作者 7楼 发表于: 01-13
elecfun 用STC的工具生产的串口代码,不处理串口接收的数据,没验证过你自己测试下。<br>P3.1接电平转换电平后到投影仪的RS232,P3.2接开机控制上升沿有效,P3.3接关机控制上升沿有效<br> <br><br><table class="read_form" style="width:100%;border-color:#d5e6ed" cellspacing="0" cellpadding="0"><tbody><tr><td style="border-color:#d5e6ed"><br></td><td style="border-color:#d5e6ed"><br><span style="color:#008000 ">/*---------------------------------------------------------------------*/</span><br><span style="color:#008000 ">/* --- STC MCU Limited ------------------------------------------------*/</span><br><span style="color:#008000 ">/* --- STC15F4K60S4 系列 定时器1用作串口1的波特率发生器举例------------*/</span><br><span style="color:#008000 ">/* --- Mobile: (86)13922805190 ----------------------------------------*/</span><br><span style="color:#008000 ">/* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/</span><br><span style="color:#008000 ">/* --- Tel: 86-0513-55012928,55012929,55012966-------------------------*/</span><br><span style="color:#008000 ">/* --- Web: www.STCMCU.com --------------------------------------------*/</span><br><span style="color:#008000 ">/* --- Web: www.GXWMCU.com --------------------------------------------*/</span><br><span style="color:#008000 ">/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序        */</span><br><span style="color:#008000 ">/* 如果要在文章中应用此代码,请在文章中注明使用了STC的资料及程序        */</span><br><span style="color:#008000 ">/*---------------------------------------------------------------------*/</span><br><br><span style="color:#008000 ">//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译<br>//若无特别说明,工作频率一般为11.0592MHz<br></span><br><br><span style="color:#0000ff ">#include</span> <span style="color:#800000 ">"reg51.h"</span><br><span style="color:#0000ff ">#include</span> <span style="color:#800000 ">"intrins.h"</span><br><br><span style="color:#0000ff ">typedef</span> <span style="color:#8000ff ">unsigned</span> <span style="color:#8000ff ">char</span> BYTE;<br><span style="color:#0000ff ">typedef</span> <span style="color:#8000ff ">unsigned</span> <span style="color:#8000ff ">int</span> WORD;<br><br><span style="color:#0000ff ">#define</span> FOSC 11059200L          <span style="color:#008000 ">//系统频率<br></span><span style="color:#0000ff ">#define</span> BAUD <span style="color:#ff0000 ">9600</span>             <span style="color:#008000 ">//串口波特率<br></span><br><span style="color:#0000ff ">#define</span> NONE_PARITY     <span style="color:#ff0000 ">0</span>       <span style="color:#008000 ">//无校验<br></span><span style="color:#0000ff ">#define</span> ODD_PARITY      <span style="color:#ff0000 ">1</span>       <span style="color:#008000 ">//奇校验<br></span><span style="color:#0000ff ">#define</span> EVEN_PARITY     <span style="color:#ff0000 ">2</span>       <span style="color:#008000 ">//偶校验<br></span><span style="color:#0000ff ">#define</span> MARK_PARITY     <span style="color:#ff0000 ">3</span>       <span style="color:#008000 ">//标记校验<br></span><span style="color:#0000ff ">#define</span> SPACE_PARITY    <span style="color:#ff0000 ">4</span>       <span style="color:#008000 ">//空白校验<br></span><br><span style="color:#0000ff ">#define</span> PARITYBIT NONE_PARITY   <span style="color:#008000 ">//定义校验位<br></span><br>sfr P0M1 = 0x93;<br>sfr P0M0 = 0x94;<br>sfr P1M1 = 0x91;<br>sfr P1M0 = 0x92;<br>sfr P2M1 = 0x95;<br>sfr P2M0 = 0x96;<br>sfr P3M1 = 0xb1;<br>sfr P3M0 = 0xb2;<br>sfr P4M1 = 0xb3;<br>sfr P4M0 = 0xb4;<br>sfr P5M1 = 0xC9;<br>sfr P5M0 = 0xCA;<br>sfr P6M1 = 0xCB;<br>sfr P6M0 = 0xCC;<br>sfr P7M1 = 0xE1;<br>sfr P7M0 = 0xE2;<br><br>sfr AUXR  = 0x8e;               <span style="color:#008000 ">//辅助寄存器<br></span><br>sfr P_SW1   = 0xA2;             <span style="color:#008000 ">//外设功能切换寄存器1<br></span><br><span style="color:#0000ff ">#define</span> S1_S0 0x40              <span style="color:#008000 ">//P_SW1.6<br></span><span style="color:#0000ff ">#define</span> S1_S1 0x80              <span style="color:#008000 ">//P_SW1.7<br></span><br><span style="color:#008000 ">//sbit P22 = P2^2;<br></span><br><span style="color:#0000ff ">#define</span> PORT_KEY    P3<br><span style="color:#0000ff ">#define</span> KEY_ON      0x04    <span style="color:#008000 ">//按键ON<br></span><span style="color:#0000ff ">#define</span> KEY_OFF     0x08    <span style="color:#008000 ">//按键OFF<br></span><span style="color:#0000ff ">#define</span> KEY_MASK    (PORT_KEY |= (KEY_ON | KEY_OFF))<br><span style="color:#8000ff ">unsigned</span> <span style="color:#8000ff ">char</span> KeyShort;     <span style="color:#008000 ">//按键触发<br></span><span style="color:#8000ff ">unsigned</span> <span style="color:#8000ff ">char</span> KeyLong;      <span style="color:#008000 ">//长按值<br></span><span style="color:#8000ff ">char</span> code CMD_ON[]={0x50,0x57,0x52,0x20,0x4F,0x4E,0x0D,0x00};<br><span style="color:#8000ff ">char</span> code CMD_OFF[]={0x50,0x57,0x52,0x20,0x4F,0x46,0x46,0x0D,0x00};<br><br>bit busy;<br><br><span style="color:#8000ff ">void</span> SendData(BYTE dat);<br><span style="color:#8000ff ">void</span> SendString(<span style="color:#8000ff ">char</span> *s);<br><br><span style="color:#8000ff ">void</span> Delay(<span style="color:#8000ff ">unsigned</span> <span style="color:#8000ff ">int</span> t)<br>{<br>    <span style="color:#8000ff ">unsigned</span> <span style="color:#8000ff ">int</span> a,b;<br>    <span style="color:#0000ff ">for</span> (a=<span style="color:#ff0000 ">0</span>; a<t; a++)<br>        <span style="color:#0000ff ">for</span> (b=<span style="color:#ff0000 ">0</span>; b<<span style="color:#ff0000 ">500</span>; b++)<br>            ;<br>}<br><br><span style="color:#008000 ">//读按键值<br></span><span style="color:#8000ff ">void</span> KeyRead( <span style="color:#8000ff ">void</span> )<br>{<br>    <span style="color:#8000ff ">unsigned</span> <span style="color:#8000ff ">char</span> ReadData = PORT_KEY ^ 0xFF;         <span style="color:#008000 ">//读端口值,并取反<br></span>    ReadData &= (KEY_ON | KEY_OFF);                <span style="color:#008000 ">//只取有效按键值<br></span>    KeyShort =  ReadData & (ReadData ^ KeyLong);    <span style="color:#008000 ">//只在第一次按下时为按键值,以后为0<br></span>    KeyLong  =  ReadData;                           <span style="color:#008000 ">//长按、短按都为按键值<br></span>}<br><br><span style="color:#8000ff ">void</span> main()<br>{<br>    P0M0 = 0x00;<br>    P0M1 = 0x00;<br>    P1M0 = 0x00;<br>    P1M1 = 0x00;<br>    P2M0 = 0x00;<br>    P2M1 = 0x00;<br>    P3M0 = 0x00;<br>    P3M1 = 0x00;<br>    P4M0 = 0x00;<br>    P4M1 = 0x00;<br>    P5M0 = 0x00;<br>    P5M1 = 0x00;<br>    P6M0 = 0x00;<br>    P6M1 = 0x00;<br>    P7M0 = 0x00;<br>    P7M1 = 0x00;<br><br>    ACC = P_SW1;<br>    ACC &= ~(S1_S0 | S1_S1);    <span style="color:#008000 ">//S1_S0=0 S1_S1=0<br></span>    P_SW1 = ACC;                <span style="color:#008000 ">//(P3.0/RxD, P3.1/TxD)<br></span>    <br><span style="color:#008000 ">//  ACC = P_SW1;<br>//  ACC &= ~(S1_S0 | S1_S1);    //S1_S0=1 S1_S1=0<br>//  ACC |= S1_S0;               //(P3.6/RxD_2, P3.7/TxD_2)<br>//  P_SW1 = ACC;  <br>//  <br>//  ACC = P_SW1;<br>//  ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=1<br>//  ACC |= S1_S1;               //(P1.6/RxD_3, P1.7/TxD_3)<br>//  P_SW1 = ACC;  <br></span><br><span style="color:#0000ff ">#if</span> (PARITYBIT == NONE_PARITY)<br>    SCON = 0x50;                <span style="color:#008000 ">//8位可变波特率<br></span><span style="color:#0000ff ">#elif</span> (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)<br>    SCON = 0xda;                <span style="color:#008000 ">//9位可变波特率,校验位初始为1<br></span><span style="color:#0000ff ">#elif</span> (PARITYBIT == SPACE_PARITY)<br>    SCON = 0xd2;                <span style="color:#008000 ">//9位可变波特率,校验位初始为0<br></span><span style="color:#0000ff ">#endif</span><br><br>    AUXR = 0x40;                <span style="color:#008000 ">//定时器1为1T模式<br></span>    TMOD = 0x20;                <span style="color:#008000 ">//定时器1为模式2(8位自动重载)<br></span>    TL1 = (<span style="color:#ff0000 ">256</span> - (FOSC/<span style="color:#ff0000 ">32</span>/BAUD));   <span style="color:#008000 ">//设置波特率重装值<br></span>    TH1 = (<span style="color:#ff0000 ">256</span> - (FOSC/<span style="color:#ff0000 ">32</span>/BAUD));<br>    TR1 = <span style="color:#ff0000 ">1</span>;                    <span style="color:#008000 ">//定时器1开始工作<br></span>    ES = <span style="color:#ff0000 ">1</span>;                     <span style="color:#008000 ">//使能串口中断<br></span>    EA = <span style="color:#ff0000 ">1</span>;<br><br>    <span style="color:#0000ff ">while</span>(<span style="color:#ff0000 ">1</span>)<br>    {<br>        KEY_MASK;<br>        KeyRead();<br>        <span style="color:#0000ff ">if</span> (KeyShort & KEY_ON)       <span style="color:#008000 ">//ON<br></span>        {<br>            SendString(CMD_ON);<br>        }<br>        <span style="color:#0000ff ">if</span> (KeyShort & KEY_OFF)      <span style="color:#008000 ">//OFF<br></span>        {<br>            SendString(CMD_OFF);<br>        }<br>        Delay(<span style="color:#ff0000 ">100</span>);<br>    }<br>}<br><br><span style="color:#008000 ">/*----------------------------<br>UART 中断服务程序<br>-----------------------------*/</span><br><span style="color:#8000ff ">void</span> Uart() interrupt <span style="color:#ff0000 ">4</span> <span style="color:#0000ff ">using</span> <span style="color:#ff0000 ">1</span><br>{<br>    <span style="color:#0000ff ">if</span> (RI)<br>    {<br>        RI = <span style="color:#ff0000 ">0</span>;                 <span style="color:#008000 ">//清除RI位</span>        <span style="color:#008000 ">//P0 = SBUF;              //P0显示串口数据</span><span style="color:#008000 "><br></span>        <span style="color:#008000 ">//P22 = RB8;              //P2.2显示校验位<br></span>    }<br>    <span style="color:#0000ff ">if</span> (TI)<br>    {<br>        TI = <span style="color:#ff0000 ">0</span>;                 <span style="color:#008000 ">//清除TI位<br></span>        busy = <span style="color:#ff0000 ">0</span>;               <span style="color:#008000 ">//清忙标志<br></span>    }<br>}<br><br><span style="color:#008000 ">/*----------------------------<br>发送串口数据<br>----------------------------*/</span><br><span style="color:#8000ff ">void</span> SendData(BYTE dat)<br>{<br>    <span style="color:#0000ff ">while</span> (busy);               <span style="color:#008000 ">//等待前面的数据发送完成<br></span>    ACC = dat;                  <span style="color:#008000 ">//获取校验位P (PSW.0)<br></span>    <span style="color:#0000ff ">if</span> (P)                      <span style="color:#008000 ">//根据P来设置校验位<br></span>    {<br><span style="color:#0000ff ">#if</span> (PARITYBIT == ODD_PARITY)<br>        TB8 = <span style="color:#ff0000 ">0</span>;                <span style="color:#008000 ">//设置校验位为0<br></span><span style="color:#0000ff ">#elif</span> (PARITYBIT == EVEN_PARITY)<br>        TB8 = <span style="color:#ff0000 ">1</span>;                <span style="color:#008000 ">//设置校验位为1<br></span><span style="color:#0000ff ">#endif</span><br>    }<br>    <span style="color:#0000ff ">else</span><br>    {<br><span style="color:#0000ff ">#if</span> (PARITYBIT == ODD_PARITY)<br>        TB8 = <span style="color:#ff0000 ">1</span>;                <span style="color:#008000 ">//设置校验位为1<br></span><span style="color:#0000ff ">#elif</span> (PARITYBIT == EVEN_PARITY)<br>        TB8 = <span style="color:#ff0000 ">0</span>;                <span style="color:#008000 ">//设置校验位为0<br></span><span style="color:#0000ff ">#endif</span><br>    }<br>    busy = <span style="color:#ff0000 ">1</span>;<br>    SBUF = ACC;                 <span style="color:#008000 ">//写数据到UART数据寄存器<br></span>}<br><br><span style="color:#008000 ">/*----------------------------<br>发送字符串<br>----------------------------*/</span><br><span style="color:#8000ff ">void</span> SendString(<span style="color:#8000ff ">char</span> *s)<br>{<br>    <span style="color:#0000ff ">while</span> (*s)                  <span style="color:#008000 ">//检测字符串结束标志<br></span>    {<br>        SendData(*s++);         <span style="color:#008000 ">//发送当前字符<br></span>    }<br>}<br><br></td></tr></tbody></table>
      
STC15F104W哪来的串口?别人要的是模拟!
离线chenhuimzk

发帖
426
M币
17
专家
1
粉丝
12
只看该作者 8楼 发表于: 01-13
回 sayno_86 的帖子
sayno_86:STC15F104W哪来的串口?别人要的是模拟! (2018-01-13 16:04) 回 sayno_86 的帖子

楼上的 不对吗   那怎么做呢  求教
离线elecfunwb

发帖
960
M币
3364
专家
8
粉丝
11
只看该作者 9楼 发表于: 01-16
之前的账号估计被盗了,登陆不上。
确实没注意这个型号没有硬串口,只能模拟。
下面的代码我在STC15F104E上验证过,可以正常发送,下载的时候注意选择时钟频率为11.0592MHZ



//http://bbs.mydigit.cn/read.php?tid=2327620

/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC15F104W 系列 读取程序区ID号并用软件模拟串口输出显示举例------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-755-82905966 -------------------------------------------*/
/* --- Tel: 86-755-82948412 -------------------------------------------*/
/* --- Web: www.STCMCU.com --------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了宏晶科技的资料及程序   */
/* 如果要在文章中应用此代码,请在文章中注明使用了宏晶科技的资料及程序   */
/*---------------------------------------------------------------------*/

//本示例在Keil开发环境下请选择Intel的8052芯片型号进行编译
//假定测试芯片的工作频率为18.432MHz

#include "reg51.h"

//-----------------------------------------
//define baudrate const
//BAUD=256 - FOSC/3/BAUDRATE/M (1T:M=1; 12T:M=12)
//NOTE: (FOSC/3/BAUDRATE) 必须大于98(建议大于 110)

//#define BAUD  0xF400                  // 1200bps @ 11.0592MHz
//#define BAUD  0xFA00                  // 2400bps @ 11.0592MHz
//#define BAUD  0xFD00                  // 4800bps @ 11.0592MHz
#define BAUD    0xFE80                  // 9600bps @ 11.0592MHz
//#define BAUD  0xFF40                  //19200bps @ 11.0592MHz
//#define BAUD  0xFFA0                  //38400bps @ 11.0592MHz
//#define BAUD  0xEC00                  // 1200bps @ 18.432MHz
//#define BAUD  0xF600                  // 2400bps @ 18.432MHz
//#define BAUD  0xFB00                  // 4800bps @ 18.432MHz
//#define BAUD  0xFD80                  // 9600bps @ 18.432MHz
//#define BAUD  0xFEC0                  //19200bps @ 18.432MHz

//#define BAUD  0xFF60                  //38400bps @ 18.432MHz

//#define BAUD  0xE800                  // 1200bps @ 22.1184MHz
//#define BAUD  0xF400                  // 2400bps @ 22.1184MHz
//#define BAUD  0xFA00                  // 4800bps @ 22.1184MHz
//#define BAUD  0xFD00                  // 9600bps @ 22.1184MHz
//#define BAUD  0xFE80                  //19200bps @ 22.1184MHz
//#define BAUD  0xFF40                  //38400bps @ 22.1184MHz
//#define BAUD  0xFF80                  //57600bps @ 22.1184MHz

#define ID_ADDR_RAM 0x71                //STC104W系列ID号的存放在RAM区的地址
#define ID_ADDR_ROM 0x0ff9              //STC104W系列ID号的存放在ROM区的地址

sfr AUXR=0x8E;
sbit RXB=P3^0;                          //定义串口 TX/RX 引脚
sbit TXB=P3^1;

typedef bit BOOL;
typedef unsigned char BYTE;
typedef unsigned int WORD;

BYTE TBUF,RBUF;
BYTE TDAT,RDAT;
BYTE TCNT,RCNT;
BYTE TBIT,RBIT;
BOOL TING,RING;
BOOL TEND,REND;

void UART_INIT();
void UART_SEND(BYTE dat);

BYTE t, r;
BYTE buf[16];


#define PORT_KEY    P3
#define KEY_ON      0x04    //按键ON
#define KEY_OFF     0x08    //按键OFF
#define KEY_MASK    (PORT_KEY |= (KEY_ON | KEY_OFF))
unsigned char KeyShort;     //按键触发
unsigned char KeyLong;      //长按值
char code CMD_ON[]={0x50,0x57,0x52,0x20,0x4F,0x4E,0x0D};
char code CMD_OFF[]={0x50,0x57,0x52,0x20,0x4F,0x46,0x46,0x0D};

void Delay(unsigned int t)
{
    unsigned int a,b;
    for (a=0; a<t; a++)
        for (b=0; b<500; b++)
            ;
}

//读按键值
void KeyRead( void )
{
    unsigned char ReadData = PORT_KEY ^ 0xFF;         //读端口值,并取反
    ReadData &= (KEY_ON | KEY_OFF);                //只取有效按键值
    KeyShort =  ReadData & (ReadData ^ KeyLong);    //只在第一次按下时为按键值,以后为0
    KeyLong  =  ReadData;                           //长按、短按都为按键值
}

void main()
{
    BYTE idata *iptr;
    BYTE code *cptr;
    BYTE i;
    
    TMOD=0x00;                        //定时器0在16位自动重装模式
    AUXR=0x80;                        //定时器0在1T模式
    TL0=BAUD;
    TH0=BAUD>>8;                      //初始化定时器0并设定重装值
    TR0=1;                            //定时器0开始运行
    ET0=1;                            //使能定时器0中断
    PT0=1;                            //提高定时器0的优先级
    EA=1;                             //打开中断开关

    UART_INIT();

    // iptr=ID_ADDR_RAM;                 //从RAM区读取ID号
    // for (i=0; i<7; i++)               //读7个字节
    // {
        // UART_SEND(*iptr++);           //发送ID到串口
    // }
    

    // cptr=ID_ADDR_ROM;                 //从程序区读取ID号
    // for (i=0; i<7; i++)               //读7个字节
    // {
        // UART_SEND(*cptr++);           //发送ID到串口
    // }

    while (1)
    {
        KEY_MASK;
        KeyRead();
        if (KeyShort & KEY_ON)       //ON
        {
            for (i=0; i<7; i++)
            {
                UART_SEND(CMD_ON[ i ]);
            }
        }
        if (KeyShort & KEY_OFF)      //OFF
        {
            for (i=0; i<8; i++)
            {
                UART_SEND(CMD_OFF[ i ]);
            }
        }
        Delay(100);
    }
}

//-----------------------------------------
//Timer interrupt routine for UART

void tm0() interrupt 1 using 1
{
    if (RING)
    {
        if (--RCNT == 0)
        {
            RCNT=3;                   //重置发送波特率计数器
            if (--RBIT == 0)
            {
                RBUF=RDAT;            //保存数据到RBUF
                RING=0;               //停止接收
                REND=1;               //设置接收完成标志
            }
            else
            {
                RDAT >>= 1;
                if (RXB) RDAT |= 0x80;  //移位RX数据到RX缓冲
            }
        }
    }
    else if (!RXB)
    {
        RING=1;                       //设置开始接收标志
        RCNT=4;                       //初始化接收波特率计计数器
        RBIT=9;                       //初始化接收位数(8数据位+1停止位)
    }

    if (--TCNT == 0)
    {
        TCNT=3;                       //重置发送波特率计数器
        if (TING)                     //判断是否发送
        {
            if (TBIT == 0)
            {
                TXB=0;                //发送开始位
                TDAT=TBUF;            //从TBUF加载数据到TDAT
                TBIT=9;               //初始化发送位数(8数据位+1停止位)
            }
            else
            {
                TDAT >>= 1;           //移位数据到CY
                if (--TBIT == 0)
                {
                    TXB=1;
                    TING=0;           //停止发送
                    TEND=1;           //设置发送完成标志
                }
                else
                {
                    TXB=CY;           //写CY到TX脚
                }
            }
        }
    }
}

//-----------------------------------------
//初始化UART模块变量
void UART_INIT()
{
    TING=0;
    RING=0;
    TEND=1;
    REND=0;
    TCNT=0;
    RCNT=0;
}

//-----------------------------------------
//发送串口数据
void UART_SEND(BYTE dat)
{
    while (!TEND);
    TEND=0;
    TBUF=dat;
    TING=1;
}

[ 此帖被elecfunwb在2018-01-16 12:00重新编辑 ]