如何实现单片机通过串口定时发送所有IO管脚上的数值

2019-07-14 19:18发布

求助各位老师:
     做实验需要,我现在有20对红外对射管用来监测小鼠的活动的(分成4组,每只小鼠用到5对红外对射管),工作时每对都会产生0或5V的数字信号,我将他们依次连接在51单片机(晶振11.989120M)上的P0/P1/P2管脚上。
     现在我想每50ms(采样率为20Hz)将这些IO口上的实际值依次采集,然后按照顺序通过串口发送给电脑,用串口助手来在收集采集到的数据
     这个单片机的程序该怎么写呢?由于自己是外行,尝试写了很久也没能搞定,这个是不是需要两个定时器才能完成,一个是来设置串口波特率,另一个用来定时50ms的定时采样,有点晕了。

先谢谢了!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
清水22
1楼-- · 2019-07-15 00:24
感谢楼主分享,好人呐
踏雁062339
2楼-- · 2019-07-15 00:51
 精彩回答 2  元偷偷看……
0906356
3楼-- · 2019-07-15 01:38
人中狼 发表于 2017-8-29 13:49
如你所想的设置好串口参数,设置好采样定时,定时到了采样发送就可以了。
可以的话,晶振换成11。0592M的。

#include"reg52.h"          //先利用定时器0定时50ms周期进行采样,进入定时中断后再通过串口中断依次发送三组数据及一组结束标志符‘9999’
#define uchar unsigned char
#define uint unsigned int
uchar i;

void TimerInit()
{
    TMOD=0x02;    //定时器1,工作方式1
        TH0=0x3C;
        TL0=0xB0;    //定时50ms
        ET0=1;
        EA=1;
        TR0=1;
}

void UART_Init()
{
        SCON=0x50;     //设置工作方式1
        TMOD=0x20;     // 计数器方式2
        PCON=0x80;           //波特率加倍
        TH1=0xF3;           //波特率4800
        TL1=0xF3;
        ES=1;
        EA=1;
        TR1=1;
}

void main()
{
    TimerInit();
        UART_Init();
        while(1);
}

       
void Timer0() interrupt 1
{
                                     
    for(i=0;i<4;i++);   //分四次发送数据,前三次为IO口状态值,最后一次发送‘9999’作为结束标志
        {
        switch(i)
        {
         case 0:
              SBUF=P0;
                  while(TI==0);
                  TI=0;
         case 1:
              SBUF=P1;
                  while(TI==0);
                  TI=0;
         case 2:
              SBUF=P2;
                  while(TI==0);
                  TI=0;
         case 3:
              SBUF=9999;
                  while(TI==0);
                  TI=0;
        }
       
        }                
}       



老师,您看看这样写问题在哪呢,为什么串口助手接收不到数据呢?谢谢!
Control8
4楼-- · 2019-07-15 05:39
0906356 发表于 2017-9-2 17:30
#include"reg52.h"          //先利用定时器0定时50ms周期进行采样,进入定时中断后再通过串口中断依次发送三组数据及一组结束标志符‘9999’
#define uchar unsigned char
#define uint unsigned int

首先,楼主写的这个串口初始化有问题,未设置串口工作模式,一般设置SM0=0,SM1=1,为10位异步收发模式(8位数据),波特率可变,若需接收还需将接收允许位REN置1,还有助手和单片机的波特率要设置相同。
Control8
5楼-- · 2019-07-15 06:07
本帖最后由 Control8 于 2017-9-2 20:09 编辑
Control8 发表于 2017-9-2 20:00
首先,楼主写的这个串口初始化有问题,未设置串口工作模式,一般设置SM0=0,SM1=1,为10位异步收发模式(8位数据),波特率可变,若需接收还需将接收允许位REN置1,还有助手和单片机的波特率要设置相同。

建议楼主在入门时先去参考别人写好的程序,弄懂每一行,有一定积累后再自己写程序。
Control8
6楼-- · 2019-07-15 11:00
Control8 发表于 2017-9-2 20:07
建议楼主在入门时先去参考别人写好的程序,弄懂每一行,有一定积累后再自己写程序。

楼主的定时器工作方式设置有误,TMOD=0x02是将定时器设为8位自动重装,而且定时器初值也设置有误,一次溢出最多能计时5ms左右,楼主却想直接设为50ms,需设置标志位计算多次中断,累计起来才能得到50ms.

一周热门 更多>