3322|13

10

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

红外通信,UART数据复用,不清楚自己思路对不对,求助TAT [复制链接]

初学UART,研究了好几天,感觉懂了个大概原理......写了个程序,不知道对不对,求教ing

13年全国电设的题目,红外通信。
发射端:硬件进行音频信号的编码,输入至单片机,但单片机需要将音频信号与采集到的温度信号复用,输出给红外发射管驱动电路。
接收端:红外接收模块接收数据,单片机将音频信号与温度信号区分开,用LCD屏显示温度,音频信号输出值后级解码电路,喇叭播放音乐

思路如下:
发射端单片机,UART接收编好码的音频信号,写入Rx_FIFO(接收缓冲区,大小设为8)。再用UART发送,Tx_FIFO发送缓冲区大小设为10Tx_FIFO[0]写入温度信号,后Tx_FIFO[1]~Tx_FIFO[8]写入音频信号,最后一位Tx_FIFO[10]定义0xFF,做标志位。

接收端单片机,UART接收信号,写入Rx_FIFO(接收缓存区,大小设为10)Rx_FIFO[0]为温度信号,Rx_FIFO[1]~Rx_FIFO[8]为音频信号,IO口依次输出八个八位高低电平给后级解码电路。
不确定这样的思路可以吗?我是把接受发送缓存区FIFO大小设为了10,相当于10个一组收发数据,第一位温度,二至八位为音频信号,最后一位为结束标志
音频信号经硬件编码后的高低电平直接输入到单片机里,单片机怎么读到它啊。。。一开始以为这也是个UART通信,现在又觉得不是,因为它只有八位数据,没有起始位,奇偶校验位之类的

然后收发速度频率之类的我都很没有概念,,,不清楚需要设成什么,按照书上的SMCLK为波特率源,波特率设为9600,可以吗?

UART通信中读八位数据,单片机如何分辨连续两位的高(低)电平啊?

问题小多,小女子在这儿叩谢各位大侠了!!

最新回复

关于串口速率,我又想推销逻辑分析仪了,淘宝30元上下买一个吧,很实用的! 代码太多,没有耐心看完,在公交车上将楼主位的说明仔细看完了,不过,由于我不知道13年竞赛的题目,所以还是没看懂这个项目要做什么。只能简单回答一下楼主提出的几个问题。 由于主从机都是楼主自己设计,所以波特率可以自行决定,两机一致就行了。 波特率的选择还需要注意就是你一秒钟需要发送多少数据,波特率过小会导致数据发不完。 串口通信的每个字节都是有起始位停止位的。只要你不是连续发送,单片机会自动识别每个字节的数据。如果连续发送,可能单片机会认错起始位,于是所有的数据都会出错。如果用逻辑分析仪能够很明确的看出管脚的时序,对于理解串口编程有很大意义。甚至于对之前提到的波特率如何选择也有参考价值,如果管脚空闲时间不多,那就有必要提高波特率了。 你将最后一字节作为一包数据的标志,这是不推荐的。建议你将起始字节作为标志,这样万一接收方中途复位,还可以通过判断起始字节并丢弃错误字节从下一包数据起重新接收数据包。而用尾字节作为校验依据,那就得接收完整包数据才能判断,极有可能会完美错过所有的数据包导致通信失败。  详情 回复 发表于 2015-7-22 20:03
 
点赞 关注

回复
举报

10

帖子

0

TA的资源

一粒金砂(中级)

推荐
 
zhaoyuyhq 发表于 2015-7-22 12:58
如果串口的波特率是9600bit/1S位的话,每一位的时间就是1/9600秒。不过,盯着算这个,对开发程序好处不大

好的,明白!谢谢
 
 

回复

10

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
以下函数都是FIFO的库函数,就不粘代码了

Tx_FIFO_WriteChar():向Tx_FIFO(发送FIFO)中写一字节数据
Tx_FIFO_ReadChar():从Tx_FIFO(发送FIFO)中读一字节数据
Tx_FIFO_Clear():复位FIFO
Rx_FIFO_WriteChar:向Rx_FIFO(接收FIFO)中写一字节数据
Rx_FIFO_ReadChar:从Rx_FIFO(接收FIFO)中读一字节数据
Rx_FIFO_Clear():复位FIFO
 
 
 

回复

10

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
部分代码如下,再次感谢各位大侠!!!

//红外发射管发送端单片机,接收编码完成的音频信号
void UART_OnRx(void)
{
        unsigned char Temp;
        static unsigned int i;
        //接收编码完成的音频信号,调用FIFO库函数,将音频信号写入Rx_FIFO
        Temp_R=UCA0RXBUF;
        Rx_FIFO_WriteChar(Temp_R);
        //将Rx_FIFO中的数据读入数组
        Rx_FIFO_ReadChar(&Temp);
        Music[i]=Temp;//Music[]音频信号数组,八位
        i++;
        if(i=8)
                i=0;
}

//红外发射管发送端单片机,将音频信号与温度复用,发送
void UART_OnTx(void)
{
        unsigned char Temp;
        static unsigned int i;
        //将温度、音频信号写入Tx_FIFO
        if (i==0)
                Tx_FIFO_WriteChar(TMPRT_T);//调用FIFO库函数,TX_FIFO[0]写入温度信号
        else if(i==9)
        {
                Tx_FIFO_WriteChar(END);//TX_FIFO[9]最后一位写入结束标志位
        }
        else
        {
                Tx_FIFO_WriteChar(Music[i-1]);//调用FIFO库函数,TX_FIFO[1]~TX_FIFO[8]写入音频信号
        }
        i++;
        if(i==10)
                i=0;

        //将发送FIFO中的数据读入发送缓存
        if(Tx_FIFO_DataNum>0)
        {
                Tx_FIFO_ReadChar(&Temp);//调用FIFO库函数,将发送FIFO中的数据读入发送缓存
                UCA0TXBUF= Temp;
                //发送完最后标志位整体清空
                if(Temp=END)
                {
                        Rx_FIFO_Clear();
                        Tx_FIFO_Clear();
                }
        }
}
 
 
 

回复

10

帖子

0

TA的资源

一粒金砂(中级)

4
 
//接收端单片机区分音频信号与温度
void UART_OnRx(void)
{
        unsigned char Temp_R,Temp;
        unsigned int n;
        static unsigned int i;

        //将数据从缓存器里读进Rx_FIFO
        Temp_R=UCA0RXBUF;
        if(Temp=END)
                Rx_FIFO_Clear();
        else
        {
        Rx_FIFO_WriteChar(Temp_R);

        //将数据从Rx_FIFO中读出并区分音频信号与温度
        if (i==0)
                TMPRT_R=Rx_FIFO[0];
        else
        {
                //P1.4依次输出八位二进制数
                Temp=Rx_FIFO[i];
                for(n=0;n<8;n++)
                {
                if (Temp&BIT7==1)
                        P1OUT=BIT4;
                else
                        P1OUT&=~BIT4;
                Temp=Temp<<1;
                }
        }
        i++;
        if(i=9)//结束标志位不会进入i++,固只到9
                i=0;
        }
}
 
 
 

回复

14

帖子

0

TA的资源

一粒金砂(初级)

5
 
UART通信中读八位数据,单片机如何分辨连续两位的高(低)电平啊?
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

6
 
得到的数据与十六进制 2、4、8 等相与,不就知道了,相与结果不为0,那相应位就为1了

点评

恩,明白了你读数据的方法,但是我主要不清楚这个时钟问题,多长时间的高电平算一位高电平,,,,  详情 回复 发表于 2015-7-22 10:51
 
 
 

回复

10

帖子

0

TA的资源

一粒金砂(中级)

7
 
zhaoyuyhq 发表于 2015-7-22 09:36
得到的数据与十六进制 2、4、8 等相与,不就知道了,相与结果不为0,那相应位就为1了

恩,明白了你读数据的方法,但是我主要不清楚这个时钟问题,多长时间的高电平算一位高电平,,,,
 
 
 

回复

14

帖子

0

TA的资源

一粒金砂(初级)

8
 
问题小多,小女子在这儿叩谢各位大侠了!!
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

9
 
多长时间的高电平算一位高电平
这个是单片机的UART自已来分辨的,你只需要从UART的寄存器中读就OK
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

10
 
如果串口的波特率是9600bit/1S位的话,每一位的时间就是1/9600秒。不过,盯着算这个,对开发程序好处不大

点评

能帮忙看下程序思路吗???我把发送FIFO里面的数据看做一组,第一位放温度,第二至八位放音频信号,最后一位结束标志位,可以嘛?谢!!!  详情 回复 发表于 2015-7-22 14:29
好的,明白!谢谢  详情 回复 发表于 2015-7-22 14:26
 
 
 

回复

10

帖子

0

TA的资源

一粒金砂(中级)

12
 
zhaoyuyhq 发表于 2015-7-22 12:58
如果串口的波特率是9600bit/1S位的话,每一位的时间就是1/9600秒。不过,盯着算这个,对开发程序好处不大

能帮忙看下程序思路吗???我把发送FIFO里面的数据看做一组,第一位放温度,第二至八位放音频信号,最后一位结束标志位,可以嘛?谢!!!
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

13
 
你这个采用UART接收到数据之后,可以加入DMA,一个回合后,你从DMA里面把数据读出来分析就行了,
你看看我这里有一个UART和DMA初始化的部分代码,希望对你有启示
          
          USART_InitTypeDef USART_InitStructure;

          USART_InitStructure.USART_BaudRate = 115200;
          USART_InitStructure.USART_WordLength = USART_WordLength_8b;
          USART_InitStructure.USART_StopBits = USART_StopBits_1;
          USART_InitStructure.USART_Parity = USART_Parity_No;
          USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
          USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

          /* Configure USART2 */
          USART_Init(USART2, &USART_InitStructure);

          /* Enable USART2 Receive and Transmit interrupts */
          //USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

          /* Enable the USART2 USART1*/
                USART_Cmd(USART2, ENABLE);
////////以上是UART的初始化      以下是DMA的
        pATFifo = dmafifo_init();                       
        _fifobuffer = pATFifo;

        DMA_DeInit(DMA1_Channel6);  
        DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART2->DR;         
        DMA_InitStructure.DMA_MemoryBaseAddr = (u32)_fifobuffer->data;   
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;   
        DMA_InitStructure.DMA_BufferSize = FIFOBUF_LEN;                                               
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                         
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;          
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                                        
        DMA_InitStructure.DMA_Priority = DMA_Priority_Low;  
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;   
        DMA_Init(DMA1_Channel6, &DMA_InitStructure);

        USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);
        USART_Cmd(USART2,ENABLE);

        DMA_Cmd(DMA1_Channel6, ENABLE);



 
 
 

回复

1193

帖子

0

TA的资源

纯净的硅(高级)

14
 
关于串口速率,我又想推销逻辑分析仪了,淘宝30元上下买一个吧,很实用的!
代码太多,没有耐心看完,在公交车上将楼主位的说明仔细看完了,不过,由于我不知道13年竞赛的题目,所以还是没看懂这个项目要做什么。只能简单回答一下楼主提出的几个问题。
由于主从机都是楼主自己设计,所以波特率可以自行决定,两机一致就行了。
波特率的选择还需要注意就是你一秒钟需要发送多少数据,波特率过小会导致数据发不完。

串口通信的每个字节都是有起始位停止位的。只要你不是连续发送,单片机会自动识别每个字节的数据。如果连续发送,可能单片机会认错起始位,于是所有的数据都会出错。如果用逻辑分析仪能够很明确的看出管脚的时序,对于理解串口编程有很大意义。甚至于对之前提到的波特率如何选择也有参考价值,如果管脚空闲时间不多,那就有必要提高波特率了。

你将最后一字节作为一包数据的标志,这是不推荐的。建议你将起始字节作为标志,这样万一接收方中途复位,还可以通过判断起始字节并丢弃错误字节从下一包数据起重新接收数据包。而用尾字节作为校验依据,那就得接收完整包数据才能判断,极有可能会完美错过所有的数据包导致通信失败。
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表