首页 > 编程知识 正文

单片机串口数据处理,单片机多机串口通信

时间:2023-05-06 10:13:34 阅读:279121 作者:1283

目录 华大单片机---串口通信1.串口通信基本原理(1)串口通信原理:(2)华大的串口通信:(3)简单介绍下:(4)多字符发送: 2.初始化代码3.发送代码:4.接收中断代码

华大单片机—串口通信 1.串口通信基本原理 (1)串口通信原理:

这部分可以百度,或者去看下野火的stm32教程,串口通信原理基本一样。这里不再详细讲解!

(2)华大的串口通信:

这部分可以直接看用户手册的UART章节。我保证肯定讲的比我详细。里面也有各种寄存器,学会看数据手册是非常重要的,我也是工作后才明白的。之前学习stm32都是看别人的例程跑通就移植了。怎么实现压根不管。第一次用这种资料比较少的单片机,你能依靠的只有几百页的手册了。一遍不懂看多几遍。。。

(3)简单介绍下:

发送数据
发送数据时,与 UARTx_SCON.REN 的值无关,将所发送数据写入 UARTx_SBUF 寄存器中,数据就会从 TXD 移出(低位在先,高位在后)。

接收数据
接收数据时,需将 UARTx_SCON.REN 位置 1,并将 UARTx_ISR.RI 位清 0。开始接收 RXD 上数据(低位在先,高位在后),当接收完毕,可以从 UARTx_SBUF 寄存器读出。

接收缓存
通用 UART(UART0/1)接收端有一个帧长度(8/9bits)的接收缓存,也就是说当一帧数据接收完毕后,接收缓存中的数据会被一直保持,直到下一帧数据的 Stop 位接收完毕后,接收缓存才会更新为新一帧数据。

发送缓存
通用 UART(UART0/1)发送端不支持发送缓存。如果在发送数据过程中,填写UARTx_SBUF 寄存器,将会破坏当前正在发送数据。软件应该避免这种操作。

(4)多字符发送:

基本串口通信用demo都可以跑通的,但是demo都是基于一个字节的,在实际使用中,通常都是发送多个字节或者字符串的。因此我参考了野火的多字节发送和字符串发送的代码。自己写了多字节发送代码。

用中断方式,自己写发送函数,开启发送中断,只需发送第一个字节,发送完成后会进入串口中断,中断中判断是否是发送中断,如果是,判断是否已经发送最后一个字节,如果是,关闭发送中断;如果没有发送到最后一个字节,则发送下一个字节。2.查询方式,从第一个字节循环发送,查询等待发送完成标志,判断是否是最后一个字节,不是,循环发送一个字节,是最后一个字节,退出循环。要发送的内容可以放在一个数组之中 -

2.初始化代码 //串口0引脚配置代码void Uart_PortInit(void){ stc_gpio_cfg_t stcGpioCfg; DDL_ZERO_STRUCT(stcGpioCfg); Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE); //使能GPIO模块时钟 ///<URART0_TX stcGpioCfg.enDir = GpioDirOut; Gpio_Init(URART0_port, URART0_TX, &stcGpioCfg); Gpio_SetAfMode(URART0_port, URART0_TX, GpioAf1); //配置PA08 端口为URART0_TX ///<RX stcGpioCfg.enDir = GpioDirIn; Gpio_Init(URART0_port, URART0_RX, &stcGpioCfg); Gpio_SetAfMode(URART1_port, URART0_RX, GpioAf1); //配置PA10 端口为URART0_RX}//串口配置初始化void App_Uart0Cfg(void){ stc_uart_cfg_t stcCfg; DDL_ZERO_STRUCT(stcCfg); ///< 开启外设时钟 Sysctrl_SetPeripheralGate(SysctrlPeripheralUart0,TRUE);///<使能uart0模块时钟 ///<UART Init stcCfg.enRunMode = UartMskMode1; ///<模式1 stcCfg.enStopBit = UartMsk1bit; ///<1bit停止位 //stcCfg.enMmdorCk = UartMskEven; ///<偶检验 stcCfg.stcBaud.u32Baud = 9600; ///<波特率9600 stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div; ///<通道采样分频配置 stcCfg.stcBaud.u32Pclk = Sysctrl_GetPClkFreq(); ///<获得外设时钟(PCLK)频率值 Uart_Init(M0P_UART0, &stcCfg); ///<串口初始化 ///<UART中断使能 Uart_ClrStatus(M0P_UART0,UartRC); ///<清接收请求 Uart_ClrStatus(M0P_UART0,UartTC); ///<清接收请求 Uart_EnableIrq(M0P_UART0,UartRxIrq); ///<使能串口接收中断 Uart_EnableIrq(M0P_UART0,UartTxIrq); ///<使能串口接收中断 EnableNvic(UART0_IRQn, IrqLevel3, TRUE); ///<系统中断使能} 3.发送代码:

串口发送是非常重要的,在日常的调试代码中,或者单片机与其他物联网设备通讯一般都可以通过串口。

//发送一个字节void Uart_SendByte(M0P_UART_TypeDef* UARTx,uint8_t ch){Uart_SendDataIt(UARTx,ch);//库函数的发送一个字节while( Uart_GetStatus(UARTx, UartTxe)== FALSE); //获取TXE的状态,一直等于FLASE=0,表示TX buffer非空}//发送字符串void Uart_SendString(M0P_UART_TypeDef* UARTx,char *str){ uint8_t k=0;do{//if(Uart_GetStatus(M0P_UART0,UartTC))//{//Uart_ClrStatus(M0P_UART0, UartTC);//}Uart_SendByte(UARTx,*(str+k));//循环发送一个字节一个字节的发k++;}while(*(str+k)!='');//直至遇到字符串结束符 ''}

是不是很简单,如果看过野火的UART部分,就回发现思路是一样的,哈哈!我的就是参考着写的。。根据上面(4)的原理写的。采用的是查询方式,,比较好理解。一开始按stm32的思路去写老是错误,后来殷勤的心情想了下。

4.接收中断代码

串口不仅发送非常重要,串口接收也是非常重要的,在项目中有时候需要从串口传入参数,或者在网络通讯中,服务器通过联网设备在通过串口直接发送指令给单片机操作对应的外设。串口接收一般采用的是中断的方式。直接看代码!

//UART0中断函数代码void Uart0_IRQHandler(void){//先存储在数组中。if(Uart_GetStatus(M0P_UART0, UartRC)) // RC 接收完成为真,UART0数据接收,有数据来了 {Uart_ClrStatus(M0P_UART0, UartRC); //清掉接收中断标志位 置0,为下次继续接收做准备 RxBuffer[u8RxCnt] = Uart_ReceiveData(M0P_UART0); //接收数据字节,把缓存寄存器的值存储在数组中//Uart_SendDataIt(M0P_UART0,temp[u8RxCnt]); //接收回显u8RxCnt++;//依次存储 }//u8RxCnt=0;//置0,方便下次重复以上操作if(Uart_GetStatus(M0P_UART0,UartTC)) // TC 发送完成为真,发送完成一个字节{Uart_ClrStatus(M0P_UART0,UartTC); //清掉发送中断标志位。置0}}

5.总结:

基本到此,华大单片机的串口通讯是没用问题了,能实现基本的串口收发以及多字节收发。至于映射-printf打印,有兴趣可以搞下。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。