您好,您帮忙看下
while(!ROM_UARTBusy(UART2_BASE))
{
ROM_UARTCharPutNonBlocking(UART2_BASE, SendCode);//发送
}
我是想通过判断一个字节是否发送完成,如果上个字节发送完成后再接着发送下一个字节。这个用法测试时串口的数据没有发出来。
pei gong:
是这个:
while(ROM_UARTBusy(UART2_BASE))
{
ROM_UARTCharPutNonBlocking(UART2_BASE, SendCode);//发送
}
Susan Yang:
回复 pei gong:
我用TM4C123测试了一下,加了
while(ROM_UARTBusy(UART0_BASE))//add by susan { // delay here until transmission is complete }
可以成功发送,代码如下
//***************************************************************************** // // uart_echo.c - Example for reading data from and writing data to the UART in //an interrupt driven fashion. // // Copyright (c) 2012-2017 Texas Instruments Incorporated.All rights reserved. // Software License Agreement //// Texas Instruments (TI) is supplying this software for use solely and // exclusively on TI's microcontroller products. The software is owned by // TI and/or its suppliers, and is protected under applicable copyright // laws. You may not combine this software with "viral" open-source // software in order to form a larger program. //// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL // DAMAGES, FOR ANY REASON WHATSOEVER. //// This is part of revision 2.1.4.178 of the EK-TM4C123GXL Firmware Package. // //*****************************************************************************#include <stdint.h> #include <stdbool.h> #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "driverlib/debug.h" #include "driverlib/fpu.h" #include "driverlib/gpio.h" #include "driverlib/interrupt.h" #include "driverlib/pin_map.h" #include "driverlib/rom.h" #include "driverlib/sysctl.h" #include "driverlib/uart.h"//***************************************************************************** // //! \addtogroup example_list //! <h1>UART Echo (uart_echo)</h1> //! //! This example application utilizes the UART to echo text.The first UART //! (connected to the USB debug virtual serial port on the evaluation board) //! will be configured in 115,200 baud, 8-n-1 mode.All characters received on //! the UART are transmitted back to the UART. // //*****************************************************************************//***************************************************************************** // // The error routine that is called if the driver library encounters an error. // //***************************************************************************** #ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line) { } #endif//***************************************************************************** // // The UART interrupt handler. // //***************************************************************************** void UARTIntHandler(void) {uint32_t ui32Status;//// Get the interrrupt status.//ui32Status = ROM_UARTIntStatus(UART0_BASE, true);//// Clear the asserted interrupts.//ROM_UARTIntClear(UART0_BASE, ui32Status);//// Loop while there are characters in the receive FIFO.//while(ROM_UARTCharsAvail(UART0_BASE)){//// Read the next character from the UART and write it back to the UART.//ROM_UARTCharPutNonBlocking(UART0_BASE,ROM_UARTCharGetNonBlocking(UART0_BASE));//// Blink the LED to show a character transfer is occuring.//GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);//// Delay for 1 millisecond.Each SysCtlDelay is about 3 clocks.//SysCtlDelay(SysCtlClockGet() / (1000 * 3));//// Turn off the LED//GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);} }//***************************************************************************** // // Send a string to the UART. // //***************************************************************************** void UARTSend(const uint8_t *pui8Buffer, uint32_t ui32Count) {//// Loop while there are more characters to send.//while(ui32Count--){//// Write the next character to the UART.//ROM_UARTCharPutNonBlocking(UART0_BASE, *pui8Buffer++);}while(ROM_UARTBusy(UART0_BASE))//add by susan{// delay here until transmission is complete} }//***************************************************************************** // // This example demonstrates how to send a string of data to the UART. // //***************************************************************************** int main(void) {//// Enable lazy stacking for interrupt handlers.This allows floating-point// instructions to be used within interrupt handlers, but at the expense of// extra stack usage.//ROM_FPUEnable();ROM_FPULazyStackingEnable();//// Set the clocking to run directly from the crystal.//ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);//// Enable the GPIO port that is used for the on-board LED.//ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);//// Enable the GPIO pins for the LED (PF2).//ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);//// Enable the peripherals used by this example.//ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);//// Enable processor interrupts.//ROM_IntMasterEnable();//// Set GPIO A0 and A1 as UART pins.//GPIOPinConfigure(GPIO_PA0_U0RX);GPIOPinConfigure(GPIO_PA1_U0TX);ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);//// Configure the UART for 115,200, 8-N-1 operation.//ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 115200,(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE));//// Enable the UART interrupt.//ROM_IntEnable(INT_UART0);ROM_UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);//// Prompt for text to be entered.//UARTSend((uint8_t *)"\033[2JEnter text: ", 16);//// Loop forever echoing data through the UART.//while(1){} }
pei gong:
回复 Susan Yang:
好的,我按照您这样测试下。谢谢您。
pei gong:
回复 Susan Yang:
您好,您提供的这种方式确实是可行的,但是我想问下,标题中我那种方式不合理吗?还有就是我想通过判断忙闲来确定CPU是否需要去执行发送。如果该位忙,则跳出去执行其他任务。UART的发送需要占用CPU的时间对吧?
Susan Yang:
回复 pei gong:
若是可以的话,请您上传一下您的代码,谢谢。我对您的描述有些疑惑
pei gong:
回复 Susan Yang:
您好, 我明白了。下面是部分代码,单字节发送:
(1)while(1)
{
if(Uart2RX_OK==1)
{
Slave_B(Rx_Uart[UART2].RxBuffer,Rx_Uart[UART2].InPointer,UART2);
}
}
(2)void Slave_B(uint8_t * ComRecBuffer,uint16_t Length,int iPort)
{
if(ComRecBuffer[0]==Rx_Uart[iPort].self_Addr)
{
Tempaddr=(ComRecBuffer[2]<<8)+ComRecBuffer[3];
Templen=(ComRecBuffer[4]<<8)+ComRecBuffer[5];
if(ComRecBuffer[1]==0x03)
{
dataClass=CheckAdde(Tempaddr,Tempaddr+Templen-1);
if(send_count_B==0)
{
YC_YX(Tempaddr,Templen,iPort,ComRecBuffer[1],dataClass);
}
else
{
if(send_count_B<Templen*2+5)
{
YC_YX(Tempaddr,Templen,iPort,ComRecBuffer[1],dataClass);
}
else
{
send_count_B=0;
Uart2RX_OK=0;
Rx_Uart[iPort].RxCounter=0;
Rx_Uart[iPort].InPointer=0;
}
}
}
}
}
(3)void Pack_YC_YX_Modbus(uint16_t StartValue,uint16_t Length,int iPort,uint8_t FCCode,uint16_t DataClass)
{
unsigned int i=0;
uint16_t getvalue;
unsigned int CRCValue=0;
Command[0]=Rx_Uart[iPort].self_Addr;
Command[1]=FCCode;
Command[2]=Length*2;
for(i=0; i<Length; i++)
{
getvalue=SearchDataValue(StartValue+i,DataClass);
Command[3+2*i] = (getvalue>>8)&0xff;
Command[3+2*i+1] = getvalue&0xff;
}
CRCValue=CRC16(Command,Length*2+3);
Command[Length*2+3]=(CRCValue>>8)&0xff;
Command[Length*2+4]=CRCValue&0xff;
if(iPort==UART2)
{
if(send_count_B<Length*2+5)
{
TxFIFOFill_UART2(iPort,Command[send_count_B],1);
send_count_B++;
}
}
else if(iPort==UART6)
{
if(send_count_D<Length*2+5)
{
TxFIFOFill_UART6(iPort,Command[send_count_D],1);
send_count_D++;
}
}
else
{
;
}
}
(4)void TxFIFOFill_UART2(int iport,unsigned char SendCode,unsigned int Length)
{
unsigned int j=0,my_length;
my_length=Length;
UART2ENABLETX;
ROM_UARTCharPutNonBlocking(UART2_BASE, SendCode);//发送UARTCharPut ROM_UARTCharPut
while(ROM_UARTBusy(UART2_BASE))//add by susan
{
// delay here until transmission is complete
}
UART2DISABLETX;
}
我的问题是:上述代码是UART2的执行过程,UART3与UART2执行过程和方法一致,如果中断来临时间点基本一致的话(未配置中断优先级),两个串口的输出从测试结果来看,UART3的输出必须是在等UART2完成后才执行。
上图1~6的执行是否占用CPU的资源呢?
pei gong:
回复 pei gong:
应该是均占用CPU时间,UART有两个FIFO,是每个UART都具有2个FIFO,而且均是独立的是吗?但是这两个FIFO都是通过寄存器UARTDR来访问的,那要是两个独立的UART,如果是同时响应了中断后,FIFO处理时是不能同时处理的是吧?