精华内容
下载资源
问答
  • STM32f103做一个项目,使用串口中断发送数据时,数据出现了断帧,断帧的间隔时间从串口打印log来看,最大的达到40多ms,小的时间间隔也有20ms左右,不知道是不是因为操作系统造成了。1.系统是用的ucos ii2.串口使用...

    STM32f103做一个项目,使用串口中断发送数据时,数据出现了断帧,断帧的间隔时间从串口打印log来看,最大的达到40多ms,小的时间间隔也有20ms左右,不知道是不是因为操作系统造成了。

    1.系统是用的ucos ii

    2.串口使用了串口1 和 2 都是利用串口中断接收和发送

    3.部分驱动代码

    谢谢各位

    /*=======================================================================================================

    *Function:  Bsp_UartNVIC_Config( ) =>

    *Input   :  *Uart

    *Output  :  None

    ========================================================================================================*/

    void Bsp_UartNVIC_Config( UART_Def *Uart  )

    {

    NVIC_InitTypeDef NVIC_InitStructure;

    NVIC_InitStructure.NVIC_IRQChannel = Uart->UARTx_IRQn;                      //Enable the USARTy Interrupt

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = Uart->PreemPriority;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = Uart->SubPriority;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

    }

    /*=======================================================================================================

    *Function:  Bsp_UartConfig( ) =>

    *Input   :  *Uart

    *Output  :  None

    ========================================================================================================*/

    void Bsp_UartConfig( UART_Def *Uart )

    {

    USART_InitTypeDef USART_InitStructure1;

    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphclockCmd( Uart->RCC_PinPort, ENABLE );                        // config USARTx Pin clock

    if( Uart->USARTx == USART2 || Uart->USARTx == USART3 )                      // config USARTx clock

    {

    RCC_APB1PeriphClockCmd( Uart->RCC_Uartx, ENABLE );

    }

    else if( Uart->USARTx == USART1 )                                          // config USARTx clock

    {

    RCC_APB2PeriphClockCmd( Uart->RCC_Uartx, ENABLE );

    }

    GPIO_InitStructure.GPIO_Pin = Uart->Rx_Pinx;                                // Configure USARTy Rx as input floating

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_Init( Uart->PinPort, &GPIO_InitStructure );

    GPIO_InitStructure.GPIO_Pin = Uart->Tx_Pinx;                                //Configure USARTy Tx as alternate function push-pull

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init( Uart->PinPort, &GPIO_InitStructure );

    USART_InitStructure1.USART_BaudRate = Baud_Table[ Uart->Baud_Rate ];        //USART1 mode config

    USART_InitStructure1.USART_WordLength = USART_WordLength_8b;

    USART_InitStructure1.USART_StopBits = USART_StopBits_1;

    USART_InitStructure1.USART_Parity = Parity_Table[ Uart->Parity ] ;

    USART_InitStructure1.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

    USART_InitStructure1.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_Init( Uart->USARTx, &USART_InitStructure1 );

    USART_ITConfig( Uart->USARTx, USART_IT_RXNE , ENABLE );

    USART_ITConfig( Uart->USARTx, USART_IT_IDLE , ENABLE );

    USART_ITConfig( Uart->USARTx, USART_IT_TXE , DISABLE );

    USART_Cmd( Uart->USARTx, ENABLE );

    }

    /*=======================================================================================================

    *Function:  Bsp_UartRingSend( ) => USARTx send data from ring buff

    *Input   :  *Uart, data

    *Output  :  None

    ========================================================================================================*/

    void Bsp_UartIntRingSend( UART_Def *Uart )

    {

    uint8_t data;

    if( Get_bytes_count( &Uart->T_RingBuff ) != 0 )

    {

    #if rs485_EN_USE == true

    RS485_TX_EN();

    #endif

    Read_ring_buffer( &Uart->T_RingBuff, &data, 1 );

    Bsp_UartSendData( Uart, data );

    if( Uart->TxBusy == false )

    {

    Uart->TxBusy = true;

    USART_ITConfig( Uart->USARTx, USART_IT_TXE , ENABLE );

    }

    }

    else

    {

    #if RS485_EN_USE == true

    g_Time3Count.rxdelay = RS485_RxDelayTable[ Uart->Baud_Rate ];

    #endif

    Uart->TxBusy = false;

    USART_ITConfig( Uart->USARTx, USART_IT_TXE , DISABLE );

    }

    }

    699ba7046c51816a17b33a7caa85f179.png

    0

    97b4b3417991aabde46fdac613e34292.png

    展开全文
  • 大家好,由于我刚学单片机,很多不懂,需要一个问题 两个单片机串口通讯,a发射1给b b点亮小灯,现在测试b接收程序没有问题,发射有问题自己,无法解决请求大家解答。以下是程序接收和发射#include "reg52.h" //此...

    大家好,由于我刚学单片机,很多不懂,

    需要一个问题 两个单片机串口通讯,a发射1

    给b b点亮小灯,现在测试b接收程序没有问题,发射有问题自己,无法解决请求大家解答。

    以下是程序

    接收和发射

    #include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器

    typedef unsigned int u16;          //对数据类型进行声明定义

    typedef unsigned char u8;

    sbit led=P2^6;

    void UsartInit()

    {

    SCON=0X50;                        //设置为工作方式1

    TMOD=0X20;                        //设置计数器工作方式2

    PCON=0X80;                        //波特率加倍

    TH1=0XF3;                                //计数器初始值设置,注意波特率是4800的

    TL1=0XF3;

    ES=1;                                                //打开接收中断

    EA=1;                                                //打开总中断

    TR1=1;                                        //打开计数器

    }

    void main()

    {

    UsartInit();  //        串口初始化

    while(1);

    }

    void Usart() interrupt 4

    {

    u8 receiveData;

    receiveData=SBUF;//出去接收到的数据

    if(        receiveData=='1' )

    {

    led=0;

    }

    RI = 0;//清除接收中断标志位

    }

    接收是上面,发射是下面

    #include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器

    typedef unsigned int u16;          //对数据类型进行声明定义

    typedef unsigned char u8;

    sbit k1=P3^1;

    void delay(u16 i)

    {

    while(i--);

    }

    void UsartInit()

    {

    SCON=0X50;                        //设置为工作方式1

    TMOD=0X20;                        //设置计数器工作方式2

    PCON=0X80;                        //波特率加倍

    TH1=0XF3;                                //计数器初始值设置,注意波特率是4800的

    TL1=0XF3;

    ES=1;                                                //打开接收中断

    EA=1;                                                //打开总中断

    TR1=1;                                        //打开计数器

    }

    void main()

    {

    UsartInit();  //        串口初始化

    while(1);

    }

    void Usart() interrupt 4

    {

    u8 receiveData;

    SBUF=receiveData;//将接收到的数据放入到发送寄存器

    {

    if(k1==0)                  //检测按键K1是否按下

    {

    delay(1000);   //消除抖动 一般大约10ms

    if(k1==0)         //再次判断按键是否按下

    {

    SBUF='1';

    }

    while(!k1);         //检测按键是否松开

    }

    }

    TI=0;                                                 //清除发送完成标志位

    }

    展开全文
  • SDK给PL串口数据 1,platform_config.h #ifndef __PLATFORM_CONFIG_H_ #define __PLATFORM_CONFIG_H_ #define STDOUT_IS_PS7_UART #define UART_DEVICE_ID 0 #endif 2,platform.h #ifndef __PLATFORM_H_ #...

    一,vivado工程搭建

    1,共享中断配置

    2,vivado工程效果

    二,SDK给PS串口发数据

    1,第一种不使用中断

    (1)uart_intr.h和uart_intr.c

    1,UART_Intr.h
    #ifndef SRC_UART_INTR_H_
    #define SRC_UART_INTR_H_
    #include "xparameters.h"
    #include "xuartps.h"
    #include "xil_printf.h"
    #include "sleep.h"
    #define UART_DEVICE_ID                  XPAR_XUARTPS_0_DEVICE_ID
    int Uart_Send(XUartPs* Uart_Ps, u8 *sendbuf, int length);
    int Uart_Init(XUartPs* Uart_Ps, u16 DeviceId);
    #endif
    
    2,UART_Intr.c
    #include "UART_Intr.h"
    // UART格式
    XUartPsFormat uart_format =
    {
    	9600,
    	//XUARTPS_DFT_BAUDRATE,   //默认波特率 115200
    	XUARTPS_FORMAT_8_BITS,
    	XUARTPS_FORMAT_NO_PARITY,
    	XUARTPS_FORMAT_1_STOP_BIT,
    };
    
    //--------------------------------------------------------------
    //                     UART初始化函数
    //--------------------------------------------------------------
    int Uart_Init(XUartPs* Uart_Ps, u16 DeviceId)
    {
    	int Status;
    	XUartPs_Config *Config;
    
    	/*  初始化UART设备    */
    	Config = XUartPs_LookupConfig(DeviceId);
    	if (NULL == Config) 
            {
    		return XST_FAILURE;
    	}
    	Status = XUartPs_CfgInitialize(Uart_Ps, Config, Config->BaseAddress);
    	if (Status != XST_SUCCESS) 
            {
    		return XST_FAILURE;
    	}
    
    	/*  UART设备自检  */
    	Status = XUartPs_SelfTest(Uart_Ps);
    	if (Status != XST_SUCCESS) 
            {
    		return XST_FAILURE;
    	}
    
    	/*  设置UART模式与参数   */
    	XUartPs_SetOperMode(Uart_Ps, XUARTPS_OPER_MODE_NORMAL); //正常模式
    	XUartPs_SetDataFormat(Uart_Ps, &uart_format);    //设置UART格式
    	return XST_SUCCESS;
    }
    
    int Uart_Send(XUartPs* Uart_Ps, u8 *sendbuf, int length)
    {
    	int SentCount = 0;
    	while (SentCount < length) 
            {
    		SentCount += XUartPs_Send(Uart_Ps, &sendbuf[SentCount], 1);
    	}
    
    	return SentCount;
    }
    
    

    (2)主函数

    #include "UART_Intr.h"
    XUartPs Uart_Ps; /* The instance of the UART Driver */
    int main(void)
    {
    	int Status;
    	u8 sendbuf[]={0xEB,0x90,0x0A,0x00,0x00,0x0A,0x99,0x01,0x03,0x05,0x01};
    	/* 串口初始化 */
    	Status = Uart_Init(&Uart_Ps, UART_DEVICE_ID);
    	if (Status == XST_FAILURE)
    	{
    		xil_printf("Uartps Failed\r\n");
    		return XST_FAILURE;
    	}
    	while (1)
    	{
    		sleep(1);
    		Uart_Send(&Uart_Ps, sendbuf, 14);
    	}
    	return Status;
    }
    

    2,第二种,使用中断号检测中断

    (1)头文件uart_paramter.h

    #ifndef UART_PARAMETER_H_
    #define UART_PARAMETER_H_
    #include "xuartps.h"
    u8 TxString[14] =
    {
    		"Hello world!\r\n"
    };
    XUartPsFormat UartFormat =
    {
    		115200,
    		XUARTPS_FORMAT_8_BITS,
    		XUARTPS_FORMAT_NO_PARITY,
    		XUARTPS_FORMAT_1_STOP_BIT
    };
    #endif 

    (2)主函数

    #include "xparameters.h"
    #include <stdio.h>
    #include "xil_printf.h"
    #include "sleep.h"
    #include "xscugic.h"
    #include "uart_parameter.h"
    
    #define UART_DEVICE_ID      XPAR_XUARTPS_0_DEVICE_ID
    #define INTC_DEVICE_ID		XPAR_SCUGIC_SINGLE_DEVICE_ID
    #define UART_INT_IRQ_ID		XPAR_XUARTPS_1_INTR
    /* Statement */
    #define UART_TX      0
    #define UART_RXCHECK 1
    #define UART_WAIT    2
    
    /* maximum receiver length */
    #define MAX_LEN    2000
    /************************** Variable Definitions *****************************/
    XUartPs Uart_PS;		//Instance of the UART Device 
    XScuGic IntcInstPtr ;
    /* UART receiver buffer */
    u8 ReceivedBuffer[MAX_LEN] ;
    /* UART receiver buffer pointer*/
    u8 *ReceivedBufferPtr ;
    /* UART receiver byte number */
    volatile u32 ReceivedByteNum ;
    volatile u32 ReceivedFlag  ;
    int UartPsSend(XUartPs *InstancePtr, u8 *BufferPtr, u32 NumBytes) ;
    int UartPsRev (XUartPs *InstancePtr, u8 *BufferPtr, u32 NumBytes) ;
    int SetupInterruptSystem(XScuGic *IntcInstancePtr,	XUartPs *UartInstancePtr, u16 UartIntrId);
    void Handler(void *CallBackRef);
    
    int main(void)
    {
    	int Status;
    	XUartPs_Config *Config;
    
    	u32 SendByteNum ;
    	u8 *SendBufferPtr ;
    	u8 state = UART_TX ;
    
    	ReceivedBufferPtr = ReceivedBuffer ;
    
    	ReceivedFlag = 0 ;
    	ReceivedByteNum = 0 ;
    
    	Config = XUartPs_LookupConfig(UART_DEVICE_ID);
    	if (NULL == Config)
       {
    		return XST_FAILURE;
    	}
    	Status = XUartPs_CfgInitialize(&Uart_PS, Config, Config->BaseAddress);
    	if (Status != XST_SUCCESS)
    	{
    		return XST_FAILURE;
    	}
    	/* Use Normal mode. */
    	XUartPs_SetOperMode(&Uart_PS, XUARTPS_OPER_MODE_NORMAL);
    	/* Set uart mode Baud Rate 115200, 8bits, no parity, 1 stop bit */
    	XUartPs_SetDataFormat(&Uart_PS, &UartFormat) ;
    	/*Set receiver FIFO interrupt trigger level, here set to 1*/
    	XUartPs_SetFifoThreshold(&Uart_PS,1) ;
    	/* Enable the receive FIFO trigger level interrupt and empty interrupt for the device */
    	XUartPs_SetInterruptMask(&Uart_PS,XUARTPS_IXR_RXOVR|XUARTPS_IXR_RXEMPTY);
    	SetupInterruptSystem(&IntcInstPtr, &Uart_PS, UART_INT_IRQ_ID) ;
    
    	while(1)
    	{
    		switch(state)
    		{
    		case UART_TX :          /* Send string to pc */
    		{
    			SendBufferPtr = TxString ;
    			SendByteNum = sizeof(TxString) ;
    			//UartPsSend(&Uart_PS, SendBufferPtr, SendByteNum);
    			state = UART_RXCHECK ;
    			break ;
    		}
    		case UART_RXCHECK :    /* Check receiver flag, send received data */
    		{
    			if (ReceivedFlag)
    			{
    				/* Reset receiver pointer, flag, byte number */
    				ReceivedBufferPtr = ReceivedBuffer ;
    				SendBufferPtr = ReceivedBuffer ;
    				SendByteNum = ReceivedByteNum ;
    				ReceivedFlag = 0 ;
    				ReceivedByteNum = 0 ;
    				//-----------------------------
    				uint8_t abc[8]={0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88};
    				UartPsSend(&Uart_PS, abc, 8);
    				//UartPsSend(&Uart_PS, SendBufferPtr, SendByteNum);
    
    			}
    			else
    			{
    				state = UART_WAIT ;
    			}
    			break ;
    		}
    		case UART_WAIT :		/* Wait for 1s */
    		{
    			sleep(1) ;
    			state = UART_TX ;
    			break ;
    		}
    		default : break ;
    		}
    	}
    }
    
    int SetupInterruptSystem(XScuGic *IntcInstancePtr,	XUartPs *UartInstancePtr, u16 UartIntrId)
    {
    	int Status;
    	/* Configuration for interrupt controller */
    	XScuGic_Config *IntcConfig;
    
    	/* Initialize the interrupt controller driver */
    	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
    	if (NULL == IntcConfig)
    	{
    		return XST_FAILURE;
    	}
    
    	Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);
    	if (Status != XST_SUCCESS)
    	{
    		return XST_FAILURE;
    	}
    
    	/*
    	 * Connect the interrupt controller interrupt handler to the
    	 * hardware interrupt handling logic in the processor.
    	 */
    	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler) XScuGic_InterruptHandler,IntcInstancePtr);
    	Status = XScuGic_Connect(IntcInstancePtr, UartIntrId,(Xil_ExceptionHandler) Handler,(void *) UartInstancePtr);
    	if (Status != XST_SUCCESS)
    	{
    		return XST_FAILURE;
    	}
    	XScuGic_Enable(IntcInstancePtr, UartIntrId);
    	Xil_ExceptionEnable();
    	return Status ;
    }
    
    
    void Handler(void *CallBackRef)
    {
    	XUartPs *UartInstancePtr = (XUartPs *) CallBackRef ;
    	u32 ReceivedCount = 0 ;
    	u32 UartSrValue ;
    	UartSrValue = XUartPs_ReadReg(UartInstancePtr->Config.BaseAddress, XUARTPS_SR_OFFSET) & (XUARTPS_IXR_RXOVR|XUARTPS_IXR_RXEMPTY);
    	ReceivedFlag = 0 ;
    
    	if (UartSrValue & XUARTPS_IXR_RXOVR)   /* check if receiver FIFO trigger */
    	{
    		ReceivedCount = UartPsRev(&Uart_PS, ReceivedBufferPtr, MAX_LEN) ;
    		ReceivedByteNum += ReceivedCount ;
    		ReceivedBufferPtr += ReceivedCount ;
    		/* clear trigger interrupt */
    		XUartPs_WriteReg(UartInstancePtr->Config.BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_RXOVR) ;
    	}
    	else if (UartSrValue & XUARTPS_IXR_RXEMPTY) //check if receiver FIFO empty 
    	{
    		/* clear empty interrupt */
    		XUartPs_WriteReg(UartInstancePtr->Config.BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_RXEMPTY) ;
    		ReceivedFlag = 1 ;
    	}
    }
    
    
    
    
    int UartPsSend(XUartPs *InstancePtr, u8 *BufferPtr, u32 NumBytes)
    {
    	u32 SentCount = 0U;
    	/* Setup the buffer parameters */
    	InstancePtr->SendBuffer.RequestedBytes = NumBytes;
    	InstancePtr->SendBuffer.RemainingBytes = NumBytes;
    	InstancePtr->SendBuffer.NextBytePtr = BufferPtr;
    
    
    	while (InstancePtr->SendBuffer.RemainingBytes > SentCount)
    	{
    		/* Fill the FIFO from the buffer */
    		if (!XUartPs_IsTransmitFull(InstancePtr->Config.BaseAddress))
    		{
    			XUartPs_WriteReg(InstancePtr->Config.BaseAddress,XUARTPS_FIFO_OFFSET,((u32)InstancePtr->SendBuffer.NextBytePtr[SentCount]));
    
    			/* Increment the send count. */
    			SentCount++;
    		}
    	}
    
    	/* Update the buffer to reflect the bytes that were sent from it */
    	InstancePtr->SendBuffer.NextBytePtr += SentCount;
    	InstancePtr->SendBuffer.RemainingBytes -= SentCount;
    
    
    	return SentCount;
    }
    
    int UartPsRev(XUartPs *InstancePtr, u8 *BufferPtr, u32 NumBytes)
    {
    	u32 ReceivedCount = 0;
    	u32 CsrRegister;
    
    	/* Setup the buffer parameters */
    	InstancePtr->ReceiveBuffer.RequestedBytes = NumBytes;
    	InstancePtr->ReceiveBuffer.RemainingBytes = NumBytes;
    	InstancePtr->ReceiveBuffer.NextBytePtr = BufferPtr;
    
    	/*
    	 * Read the Channel Status Register to determine if there is any data in
    	 * the RX FIFO
    	 */
    	CsrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
    			XUARTPS_SR_OFFSET);
    
    	/*
    	 * Loop until there is no more data in RX FIFO or the specified
    	 * number of bytes has been received
    	 */
    	while((ReceivedCount < InstancePtr->ReceiveBuffer.RemainingBytes)&&
    			(((CsrRegister & XUARTPS_SR_RXEMPTY) == (u32)0)))
    	{
    		InstancePtr->ReceiveBuffer.NextBytePtr[ReceivedCount] =
    				XUartPs_ReadReg(InstancePtr->Config.BaseAddress,XUARTPS_FIFO_OFFSET);
    
    		ReceivedCount++;
    		CsrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,XUARTPS_SR_OFFSET);
    	}
    	InstancePtr->is_rxbs_error = 0;
    	/*
    	 * Update the receive buffer to reflect the number of bytes just
    	 * received
    	 */
    	if(InstancePtr->ReceiveBuffer.NextBytePtr != NULL)
            {
    		InstancePtr->ReceiveBuffer.NextBytePtr += ReceivedCount;
    	}
    	InstancePtr->ReceiveBuffer.RemainingBytes -= ReceivedCount;
    
    	return ReceivedCount;
    }
    
    
    

    3,比较复杂的一种带中断的写法

    (1)uartps_intr.h和uart_intr.c

    1,uartps_intr.h
    #ifndef UARTPS_INTR_H_
    #define UARTPS_INTR_H_
    #include "xparameters.h"
    #include "xplatform_info.h"
    #include "xuartps.h"
    #include "xil_exception.h"
    #include "xil_printf.h"
    #include "xscugic.h"
    int Init_UartPsIntr(XUartPs *UartInstPtr,u16 DeviceId);
    int UartPs_Setup_IntrSystem(XScuGic *IntcInstancePtr,XUartPs *UartInstancePtr,u16 UartIntrId);
    void UartPs_Intr_Handler(void *CallBackRef, u32 Event, unsigned int EventData);
    #define UART_DEVICE_ID		XPAR_XUARTPS_0_DEVICE_ID
    #define INTC_DEVICE_ID		XPAR_SCUGIC_SINGLE_DEVICE_ID
    #define UART_INT_IRQ_ID		XPAR_XUARTPS_1_INTR
    #define TEST_BUFFER_SIZE	10
    XUartPs UartPs;//uart
    static u8 SendBuffer[TEST_BUFFER_SIZE];	/* Buffer for Transmitting Data */
    static u8 RecvBuffer[TEST_BUFFER_SIZE];	/* Buffer for Receiving Data */
    volatile int TotalReceivedCount;
    volatile int TotalSentCount;
    int TotalErrorCount;
    #endif /* SRC_UARTPS_INTR_H_ */
    
    
    
    
    2,uartps_intr.c
    #include "uartps_intr.h"
    int Init_UartPsIntr(XUartPs *UartInstPtr,u16 DeviceId )
    {
    	int Status;
    	XUartPs_Config *Config;
    	u32 IntrMask;
    
    	if (XGetPlatform_Info() == XPLAT_ZYNQ_ULTRA_MP)
    	{
    #ifdef XPAR_XUARTPS_1_DEVICE_ID
    		DeviceId = XPAR_XUARTPS_1_DEVICE_ID;
    #endif
    	}
    
    	Config = XUartPs_LookupConfig(DeviceId);
    	if (NULL == Config)
    	{
    		return XST_FAILURE;
    	}
    
    	Status = XUartPs_CfgInitialize(UartInstPtr, Config, Config->BaseAddress);
    	if (Status != XST_SUCCESS)
    	{
    		return XST_FAILURE;
    	}
    
    	
    	 /* Setup the handlers for the UART that will be called from the
    	 * interrupt context when data has been sent and received, specify
    	 * a pointer to the UART driver instance as the callback reference
    	 * so the handlers are able to access the instance data*/
    	XUartPs_SetHandler(UartInstPtr, (XUartPs_Handler)UartPs_Intr_Handler, UartInstPtr);
    
    	/*
    	 * Enable the interrupt of the UART so interrupts will occur, setup
    	 * a local loopback so data that is sent will be received.
    	 */
    	IntrMask =
    		XUARTPS_IXR_TOUT | XUARTPS_IXR_PARITY | XUARTPS_IXR_FRAMING |
    		XUARTPS_IXR_OVER | XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_RXFULL |
    		XUARTPS_IXR_RXOVR;
    
    	if (UartInstPtr->Platform == XPLAT_ZYNQ_ULTRA_MP)
    	{
    		IntrMask |= XUARTPS_IXR_RBRK;
    	}
    	XUartPs_SetInterruptMask(UartInstPtr, IntrMask);
    	XUartPs_SetRecvTimeout(UartInstPtr, 8);
    	return XST_SUCCESS;
    }
    
    
    void UartPs_Intr_Handler(void *CallBackRef, u32 Event, unsigned int EventData)
    {
    	int i = 0;
    	/* All of the data has been sent */
    	if (Event == XUARTPS_EVENT_SENT_DATA)
    	{
    		TotalSentCount = EventData;
    	}
    	/* All of the data has been received */
    	if (Event == XUARTPS_EVENT_RECV_DATA)
    	{
    		TotalReceivedCount = EventData;
    		if(TotalReceivedCount == TEST_BUFFER_SIZE)
    		{
    			for(i=0;i<TotalReceivedCount;i++)
    			{
    				SendBuffer[i] = RecvBuffer[i];
    			}
    			XUartPs_Send(&UartPs, SendBuffer, TotalReceivedCount);
    			XUartPs_Recv(&UartPs, RecvBuffer, TEST_BUFFER_SIZE);
    			TotalReceivedCount=0;
    		}
    	}
    	/*
    	 * Data was received, but not the expected number of bytes, a
    	 * timeout just indicates the data stopped for 8 character times
    	 */
    	if (Event == XUARTPS_EVENT_RECV_TOUT)
    	{
    		TotalReceivedCount = EventData;
    			for(i=0;i<TotalReceivedCount;i++)
    			{
    				SendBuffer[i] = RecvBuffer[i];
    			}
    		XUartPs_Send(&UartPs, SendBuffer, TotalReceivedCount);
    		XUartPs_Recv(&UartPs, RecvBuffer, TEST_BUFFER_SIZE);
    		TotalReceivedCount=0;
    	}
    
    	/*
    	 * Data was received with an error, keep the data but determine
    	 * what kind of errors occurred
    	 */
    	if (Event == XUARTPS_EVENT_RECV_ERROR) 
            {
    		TotalReceivedCount = EventData;
    		TotalErrorCount++;
    	}
    	 /* Data was received with an parity or frame or break error, keep the data
    	 * but determine what kind of errors occurred. Specific to Zynq Ultrascale+
    	 * MP.*/
    	if (Event == XUARTPS_EVENT_PARE_FRAME_BRKE) 
            {
    		TotalReceivedCount = EventData;
    		TotalErrorCount++;
    	}
    	/*
    	 * Data was received with an overrun error, keep the data but determine
    	 * what kind of errors occurred. Specific to Zynq Ultrascale+ MP.
    	 */
    	if (Event == XUARTPS_EVENT_RECV_ORERR) 
           {
    		TotalReceivedCount = EventData;
    		TotalErrorCount++;
    	}
    }
    
    int UartPs_Setup_IntrSystem(XScuGic *IntcInstancePtr,XUartPs *UartInstancePtr,u16 UartIntrId)
    {
    	int Status;
    	XScuGic_Config *IntcConfig; /* Config for interrupt controller */
    	/* Initialize the interrupt controller driver */
    	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
    	if (NULL == IntcConfig)
    	{
    		return XST_FAILURE;
    	}
    	Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);
    	if (Status != XST_SUCCESS)
    	{
    		return XST_FAILURE;
    	}
    	/*
    	 * interrupt for the device occurs, the device driver handler
    	 * performs the specific interrupt processing for the device
    	 */
    	Status = XScuGic_Connect(IntcInstancePtr, UartIntrId,
    	(Xil_ExceptionHandler) XUartPs_InterruptHandler,(void *) UartInstancePtr);
    	if (Status != XST_SUCCESS) 
            {
    		return XST_FAILURE;
    	}

    (2)sys_intr.h和sys_intr.c

    #ifndef SYS_INTR_H_
    #define SYS_INTR_H_
    #include "xparameters.h"
    #include "xil_exception.h"
    #include "xdebug.h"
    #include "xscugic.h"
    #define INTC_DEVICE_ID          XPAR_SCUGIC_SINGLE_DEVICE_ID
    XScuGic Intc; //GIC
    int Init_Intr_System(XScuGic * IntcInstancePtr);
    void Setup_Intr_Exception(XScuGic * IntcInstancePtr);
    #endif 
    
    
    
    
    #include "sys_intr.h"
    void Setup_Intr_Exception(XScuGic * IntcInstancePtr)
    {
    	//从硬件使能中断
    	Xil_ExceptionInit();
    	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
    			(Xil_ExceptionHandler)XScuGic_InterruptHandler,
    			(void *)IntcInstancePtr);
    	Xil_ExceptionEnable();
    }
    
    int Init_Intr_System(XScuGic * IntcInstancePtr)
    {
    	int Status;
    	XScuGic_Config *IntcConfig;
    	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
    	if (NULL == IntcConfig)
    	{
    		return XST_FAILURE;
    	}
    	Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);
    	if (Status != XST_SUCCESS)
    	{
    		return XST_FAILURE;
    	}
    	return XST_SUCCESS;
    }

    (3)主函数

    #include "sys_intr.h"
    #include "uartps_intr.h"
    void init_intr_sys(void)
    {
    	Init_UartPsIntr(&UartPs,UART_DEVICE_ID);
    	Init_Intr_System(&Intc);
    	Setup_Intr_Exception(&Intc);
    	UartPs_Setup_IntrSystem(&Intc, &UartPs, UART_INT_IRQ_ID);
    }
    int main(void)
    {
    	init_intr_sys();
    	XUartPs_Recv(&UartPs, RecvBuffer, TEST_BUFFER_SIZE);
        while(1);
    	return 0;
    }

    三,SDK给PL axi_uartlitle串口发数据执行流程

    1,PL串口把收到的数据回发,不加中断

    #include "xuartlite.h"
    #include "xparameters.h"
    #include "sleep.h"
    #include "xil_printf.h"
    #include "string.h"
    int main()
    {
    	//实例化xuart2
    	XUartLite  xuart2;//uart对象
    	//查找uart配置
    	XUartLite_Config *XUARTConfigPtr;
    	XUARTConfigPtr = XUartLite_LookupConfig(XPAR_UARTLITE_0_DEVICE_ID);//ID来源于xparameters.h
    	if (XUARTConfigPtr == NULL)
    	{
    		//在bsp中设置为uartlite0负责stdout
    		//print("failed XUartlite_LookupConfig\n\r");
    		return XST_FAILURE;
    	}
    	else
    	{
    		//print("succeed XUartlite_LookupConfig\n\r");
    	}
    	//uart初始化
    	int Status;
    	Status = XUartLite_Initialize(&xuart2, XPAR_UARTLITE_0_DEVICE_ID);
    	if (Status != XST_SUCCESS)
    	{
    		return XST_FAILURE;
    	}
    	//接收缓冲
    	u8 buf[64]={0x55,0x55,0x55,0x55,0x55};
    	u8 buf2[64]={0};
    	//接收字节数
    	u32 recv_cnt = 0;
    	while (TRUE)
    	{
    		usleep(500000);//等待500ms
    		recv_cnt = XUartLite_Recv(&xuart2, buf2, 64);//接收数据
    		if(recv_cnt>0)
    		{
    			XUartLite_Send(&xuart2, buf2,recv_cnt);
    			memset(buf2, 0, 64);
    			recv_cnt = 0;
    		}
    	}
    	return 0;
    }

    2,使用中断号触发,从SDK空工程把串口号切换到PL串口

    #include "stdio.h"
    #include "xil_printf.h"
    #include "xparameters.h"
    #include "sleep.h"
    #include "xuartlite.h"
    #include "xuartlite_i.h"
    #include "xscugic.h"
    ///xxx#include "xuartps.h"
    #define SEND_BUFF_SIZE 128
    #define RECV_BUFF_SIZE 1
    //函数声明
    void ScuGic_UartLite_handle(void *CallbackRef);
    void SendENDHandle(void *CallbackRef,unsigned int ByteCount);
    void RecvENDHandle(void *CallbackRef,unsigned int ByteCount);
    //全局变量
    XScuGic scugic_inst;
    XScuGic_Config *scugic_cfg_ptr;
    XUartLite PL_Extend_Uart_inst;
    unsigned char SendBuff[SEND_BUFF_SIZE]={"FUCK THE WORLD ONCE,FUCK THE WORLD TWICE\r\n"};
    unsigned char RecvBuff[RECV_BUFF_SIZE]={0};
    unsigned int recvcount=0;
    int main()
    {
    	unsigned int state = 0;
    	//初始化实例
    	//state = XUartLite_Initialize( &PL_Extend_Uart_inst , XPAR_UARTLITE_0_DEVICE_ID );
    	state = XUartLite_Initialize( &PL_Extend_Uart_inst , XPAR_XUARTPS_0_DEVICE_ID  );
    	xil_printf("initialize state=%d\r\n",state);
    	//设置发送buffer结束或接收buffer结束时的处理函数
    	XUartLite_SetSendHandler( &PL_Extend_Uart_inst, SendENDHandle, &PL_Extend_Uart_inst );
    	XUartLite_SetRecvHandler( &PL_Extend_Uart_inst, RecvENDHandle, &PL_Extend_Uart_inst );
    	PL_Extend_Uart_inst.ReceiveBuffer.NextBytePtr = RecvBuff;
    	PL_Extend_Uart_inst.ReceiveBuffer.RemainingBytes = RECV_BUFF_SIZE;
    	//自检
    	state = XUartLite_SelfTest( &PL_Extend_Uart_inst );
    	xil_printf("selftest state=%d\r\n",state);
    	//串口使能中断
    	XUartLite_EnableInterrupt( &PL_Extend_Uart_inst );
    	//scugic中断控制器初始化
    	scugic_cfg_ptr = XScuGic_LookupConfig( XPAR_PS7_SCUGIC_0_DEVICE_ID );
    	XScuGic_CfgInitialize( &scugic_inst,scugic_cfg_ptr,scugic_cfg_ptr->CpuBaseAddress );
    	//设置优先级,中断触发类型
    	XScuGic_SetPriorityTriggerType( &scugic_inst , XPAR_FABRIC_UARTLITE_0_VEC_ID , 0x0a , 0x03 );
    	//将中断ID与中断处理函数相关联
    	XScuGic_Connect( &scugic_inst,XPAR_FABRIC_UARTLITE_0_VEC_ID,ScuGic_UartLite_handle,&PL_Extend_Uart_inst );
    	//使能AXI_GPIO中断
    	XScuGic_Enable( &scugic_inst,XPAR_FABRIC_UARTLITE_0_VEC_ID );
    	//设置并打开中断异常处理功能
    	Xil_ExceptionInit();
    	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler, &scugic_inst);
    	Xil_ExceptionEnable();
    	//xil_printf("len=%d\r\n",strlen((char *)SendBuff));
    	while(1)
    	{
    		//将buffer中的数据全发送出去
    	//XUartLite_Send( &PL_Extend_Uart_inst,SendBuff,strlen((char *)SendBuff));
    		sleep(1);
    
    		//xil_printf("RemainingBytes=%d\r\n",PL_Extend_Uart_inst.SendBuffer.RemainingBytes);
    		state = XUartLite_ReadReg(PL_Extend_Uart_inst.RegBaseAddress,XUL_STATUS_REG_OFFSET);
    		xil_printf("state=%d recvcount=%d\r",state,recvcount);
    		XUartLite_Send( &PL_Extend_Uart_inst,RecvBuff,strlen((char *)RecvBuff));
    		sleep(1);
    	}
    
    	return 0;
    }
    
    //该函数内部最好不要放打印函数,因为打印函数速度慢,会导致接收异常
    void ScuGic_UartLite_handle(void *CallbackRef)
    {
    	//xil_printf("enter intr\r\n");
    	XUartLite_InterruptHandler( &PL_Extend_Uart_inst );
    }
    //该函数内部最好不要放打印函数,尤其是需要使用扩展串口向外传输大量连续数据的时候,因为打印函数速度慢,会导致发送异常
    void SendENDHandle(void *CallbackRef,unsigned int ByteCount)
    {
    	xil_printf("send end\r\n");
    }
    //该函数内部最好不要放打印函数,因为打印函数速度慢,会导致接收异常
    void RecvENDHandle(void *CallbackRef,unsigned int ByteCount)
    {
    	recvcount++;
    	xil_printf( "%s\n",RecvBuff );
    	memset(RecvBuff,0,RECV_BUFF_SIZE);
    	PL_Extend_Uart_inst.ReceiveBuffer.RemainingBytes = RECV_BUFF_SIZE;
    	PL_Extend_Uart_inst.ReceiveBuffer.NextBytePtr = RecvBuff;
    	XUartLite_EnableInterrupt( &PL_Extend_Uart_inst );
    }

    3,INTC带中断控制的方法,从SDK空工程把串口号切换到PL串口,使用microblaze软盒加中断控制器INTC模块

    (1)sys_intr.h和sys_intr.c

    #ifndef SYS_INTR_H_
    #define SYS_INTR_H_
    #include "xparameters.h"
    #include "xil_exception.h"
    #include "xdebug.h"
    #include "XIntc.h"
    int Init_Intr_System(XIntc * IntcInstancePtr);
    void Intc_Enable(XIntc *IntcInstancePtr,u16 Intr_Id);
    int Intc_Start(XIntc *IntcInstancePtr);
    void setup_Intr_Exception(XIntc * IntcInstancePtr);
    #endif 
    
    
    
    #include "sys_intr.h"
    #define INTC_DEVICE_ID          XPAR_INTC_0_DEVICE_ID
    void Setup_Intr_Exception(XIntc * IntcInstancePtr)
    {
    	/* Enable interrupts from the hardware */
    	Xil_ExceptionInit();
    	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
    			(Xil_ExceptionHandler)XIntc_InterruptHandler,
    			(void *)IntcInstancePtr);
    	Xil_ExceptionEnable();
    }
    int Init_Intr_System(XIntc * IntcInstancePtr)
    {
    	int Status;
    	Status = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID);
    		if (Status != XST_SUCCESS) 
    		{
    			return XST_FAILURE;
    		}
    	return XST_SUCCESS;
    }
    void Intc_Enable(XIntc *IntcInstancePtr,u16 Intr_Id)
    {
    	XIntc_Enable(IntcInstancePtr, Intr_Id);
    }
    int Intc_Start(XIntc *IntcInstancePtr)
    {
    	int Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
    	if(Status != XST_SUCCESS)
    	{
    		return XST_FAILURE;
    	}
    	return XST_SUCCESS;
    }

    (2)UART_Intr.h和UART_Intr.c

    #ifndef SRC_UART_INTR_H_
    #define SRC_UART_INTR_H_
    #include "xintc.h"
    #include "xuartlite.h"
    #include "xuartlite_l.h"
    void uart_intr_handler(void *CallbackRef);
    int Uart_SetupIntrSystem(XIntc* IntcInstancePtr,XUartLite* UartInstancePtr,u16 IntrId);
    #endif
    
    
    
    #include "UART_Intr.h"
    void uart_intr_handler(void *CallbackRef)//中断函数
    {
    	u8 ReadByte;
    	u32 IsrStatus;
    	XUartLite *InstancePtr= (XUartLite *)CallbackRef;
    	//读取状态寄存器
    	IsrStatus = XUartLite_ReadReg(InstancePtr->RegBaseAddress,XUL_STATUS_REG_OFFSET);//读取状态寄存器
    	while(IsrStatus & XUL_SR_RX_FIFO_VALID_DATA)
    	{
    		//读取数据
    		ReadByte=XUartLite_ReadReg(InstancePtr->RegBaseAddress,XUL_RX_FIFO_OFFSET);
    		//发送数据
    		XUartLite_WriteReg(InstancePtr->RegBaseAddress,XUL_TX_FIFO_OFFSET,ReadByte);
    		//读取状态寄存器
    		IsrStatus = XUartLite_ReadReg(InstancePtr->RegBaseAddress,XUL_STATUS_REG_OFFSET);
    	}
    }
    int Uart_SetupIntrSystem(XIntc* IntcInstancePtr,XUartLite* UartInstancePtr,u16 IntrId)
    {
    	int Status;
    
    	Status = XIntc_Connect(IntcInstancePtr, IntrId,(XInterruptHandler)uart_intr_handler,(void *)UartInstancePtr);
    	if (Status != XST_SUCCESS) 
    	{
    		return XST_FAILURE;
    	}
    	XUartLite_EnableInterrupt(UartInstancePtr);
    	return XST_SUCCESS;
    }

    (3)主函数

    #include "UART_Intr.h"
    #include "xparameters.h"
    #include "sys_intr.h"
    #define UART_DEV_ID		XPAR_UARTLITE_0_DEVICE_ID
    #define UART_INTR_ID	XPAR_INTC_0_UARTLITE_0_VEC_ID
    static XIntc Intc; //GIC
    static XUartLite Uart;//timer
    int main(void)
    {
    	XUartLite_Initialize(&Uart, UART_DEV_ID);
    	Init_Intr_System(&Intc); // initial DMA interrupt system
    	Uart_SetupIntrSystem(&Intc,&Uart,UART_INTR_ID);
    	Intc_Start(&Intc);
    	Intc_Enable(&Intc,UART_INTR_ID);
    	Setup_Intr_Exception(&Intc);
    	while(1);
    }

    4, 使用寄存器方法

    (1)功能:AXI-UART模块配置

    void AxiUartConfig(void)
    {
        PsWriteWord(ADDR_INTR_CLEAR, 0);
        PsWriteWord(ADDR_INTR_CLEAR, 1);
        PsWriteWord(ADDR_INTR_CLEAR, 2);
        PsWriteWord(ADDR_INTR_CLEAR, 3);
        PsWriteWord(ADDR_INTR_EN, 0xFFFF); // interrupt enable
    
        // TEST_UART   TTL   
        PsWriteWord(ADDR_UART0_RST, 1);
        DelayUs(1);
        PsWriteWord(ADDR_UART0_RST, 0);
        PsWriteWord(ADDR_UART0_BAUD, 52); // 12 = 460800   =  100M  / 460800 / 16 - 1
        PsWriteWord(ADDR_UART0_PARITY, 0);
        PsWriteWord(ADDR_UART0_STOP, 0);
        PsWriteWord(ADDR_UART0_EN, 1);
    
        // PL_UART1    RS422  
        PsWriteWord(ADDR_UART1_RST, 1);
        DelayUs(1);
        PsWriteWord(ADDR_UART1_RST, 0);
        PsWriteWord(ADDR_UART1_BAUD, 52); // 52 = 115200
        PsWriteWord(ADDR_UART1_PARITY, 0);
        PsWriteWord(ADDR_UART1_STOP, 0);
        PsWriteWord(ADDR_UART1_EN, 1);
    
        // PL_UART2    RS422  
        PsWriteWord(ADDR_UART2_RST, 1);
        DelayUs(1);
        PsWriteWord(ADDR_UART2_RST, 0);
        PsWriteWord(ADDR_UART2_BAUD, 52); // 52 = 115200
        PsWriteWord(ADDR_UART2_PARITY, 0);
        PsWriteWord(ADDR_UART2_STOP, 0);
        PsWriteWord(ADDR_UART2_EN, 1);
    }

    (2)获取串口控制台数据

    Uint8 ConsoleAcquireData(int port)
    {
        Uart_stu *mUart;
        Uint8   rXor = 0;  // 异或校验码
        Uint16  ckSum = 0;  // 校验和
        uint16_t i;
        uint8_t *buf;
        comm2upper_stu *comm_pt;
        if(port == IF_UART)
       { 
     if(!(Ctl_param.comm2upper.if_sw & uart_enable))
    	return 0;
    mUart = &Ctl_param.uart_console;
    Ctl_param.comm2upper.err = 0;
    
    while (mUart->rb.rx_head != mUart->rb.rx_tail )
    {
    	mUart->frm_rx_buf[mUart->frm_rx_idx] = mUart->rb.rx[mUart->rb.rx_tail];
    	__BUF_INCR(mUart->rb.rx_tail);
    	mUart->frm_rx_idx++;
    
    	switch(mUart->frm_rx_idx)
    	{
    		// 长度码
    		case 1: if(mUart->frm_rx_buf[0]  != 0x55)
    					mUart->frm_rx_idx = 0;
    			break;
    		case 2: if(mUart->frm_rx_buf[1]  != 0xAA)
    					mUart->frm_rx_idx = 0;
    			break;
    		case 3: if(mUart->frm_rx_buf[2]  != 0x01)
    					mUart->frm_rx_idx = 0;
    			break;
    		case 4: if(mUart->frm_rx_buf[3]  != 0x36)
    					mUart->frm_rx_idx = 0;
    				else
    					mUart->frm_length = 0x36;
    			break;
    		default:
    				if(mUart->frm_rx_idx == mUart->frm_length)   // 数据段读完
    				{
    					for(i=2; i<53; i++)//3~52字节求和
    					{
    						ckSum += mUart->frm_rx_buf[i];
    					}
    					ckSum &= 0xFF; // 取低八位
    
    					if(ckSum == mUart->frm_rx_buf[mUart->frm_length - 2] &&
    					   0x0D == mUart->frm_rx_buf[mUart->frm_length - 1]) // success
    					{
    						comm_pt = &Ctl_param.comm2upper;
    						buf = &mUart->frm_rx_buf[0];
    						comm_pt->load_info.missile_longitude = *(int32_t *)(buf+5);
    						comm_pt->load_info.latitude = *(int32_t *)(buf+9);
    						comm_pt->load_info.height = *(int32_t *)(buf+13);
    						comm_pt->load_info.nVelocity = *(int32_t *)(buf+15);
    						comm_pt->load_info.sVelocity = *(int32_t *)(buf+17);
    						comm_pt->load_info.eVelocity = *(int32_t *)(buf+19);
    						comm_pt->load_info.target_longitude = *(int32_t *)(buf+21);
    						comm_pt->load_info.target_latitude = *(int32_t *)(buf+25);
    						comm_pt->load_info.target_height = *(int32_t *)(buf+29);
    						comm_pt->load_info.pitch = *(int32_t *)(buf+31);
    						comm_pt->load_info.yaw = *(int32_t *)(buf+33);
    						comm_pt->load_info.roll = *(int32_t *)(buf+35);
    						comm_pt->load_info._wx = *(int32_t *)(buf+37) & 0x00FFFFFF;
    						comm_pt->load_info._wy = *(int32_t *)(buf+40) & 0x00FFFFFF;
    						comm_pt->load_info._wz = *(int32_t *)(buf+43) & 0x00FFFFFF;
    						comm_pt->load_info.target_distance = *(int32_t *)(buf+46);
    						comm_pt->load_info.frm_cnt = *(int32_t *)(buf+50);
    						mUart->frm_rx_idx = 0;
    					}
    				}
    			break;
    	}
    }
    mUart->frm_rx_idx = 0;
    mUart->rb.rx_head = 0;
    mUart->rb.rx_tail = 0;

     

     

    展开全文
  • 这里写自定义目录标题前言所涉及的芯片STM32F103RCT6MAX3483主要特点使用说明代码部分初始化相关代码.h文件.C文件与MAX3483相关的代码部分.h文件.c文件中断服务代码.c文件末尾 前言 这是我的第一篇CSDN,记录一些...

    一、前言

    这是我的第一篇CSDN,记录一些代码总结,一方面与大家分享交流,另一方面方便以后再次使用能够快速回忆,再就是提高自身写作水平。如有错误之处,欢迎各位大佬批评指正。

    二、所涉及的芯片

    1、STM32F103RCT6

    2、MAX3483

    MAX3483

    a、主要特点

    传输方式:半双工
    速率:10Mbps
    限摆率:NO
    接收允许控制:YES
    关断电流:2 nA
    引脚数:8

    b、使用说明

    MAX3483
    当RE与DE都拉高时,由TTL电平向RS232电平发送;(发送)
    当RE与DE都拉低时,由RS232电平向TTL电平发送;(接收)

    三、代码部分

    1、初始化相关代码

    .h文件

    这个文件放置相关声明与宏定义

    #ifndef __USART_INIT_H
    #define __USART_INIT_H
    #include "stm32f10x.h"
    
    //串口2和产品通信
    //TXD
    #define USART2_TXD_GPIO_PORT    GPIOA
    #define USART2_TXD_GPIO_PIN     GPIO_Pin_2
    //RXD
    #define USART2_RXD_GPIO_PORT    GPIOA
    #define USART2_RXD_GPIO_PIN	    GPIO_Pin_3
    
    #define CD4067_USART 			USART2
    #define MCD4067_USART_IRQn		USART2_IRQn
    
    //串口3和上位机通信
    //TXD
    #define USART3_TXD_GPIO_PORT    GPIOB
    #define USART3_TXD_GPIO_PIN     GPIO_Pin_10
    //RXD
    #define USART3_RXD_GPIO_PORT    GPIOB
    #define USART3_RXD_GPIO_PIN     GPIO_Pin_11
    
    #define MAX3483_USART 			USART3
    #define MAX3483_USART_IRQn		USART3_IRQn
    
    static void NVIC_Config( uint32_t NVIC_PriorityGroup , \
    	
    						 IRQn_Type NVIC_IRQChannel ,   \
    
    						 uint8_t PreemptionPriority ,  \
    
    						 uint8_t SubPriority );//NVIC配置
    void USART_2_3_Init(void);//串口2、串口3初始化
    void Usart_SendByte(USART_TypeDef* USARTx, uint8_t data);//发送一个字节
    void Usart_SendHalfWord(USART_TypeDef* USARTx, uint16_t data);//发送二个字节
    void Usart_SendStr(USART_TypeDef* USARTx, uint8_t *str);//发送字符串 
    
    
    #endif /* __USART_INIT_H */
    

    .C文件

    这部分代码用来初始化USART3接口(代码中有USART2是他用,还将与下面另一台设备进行通信,此处略去)

    /*******************************************************************************
    * Function Name  : USART_2_3_Init 
    * Description    : 串口2、串口3初始化,优先级组使用组1,串口2(1,2),串口3(1,1),串口3优先级高于串口2
    * Input          : 无
    * Output         : 无
    * Return         : 无
    *******************************************************************************/
    void USART_2_3_Init(void)
    {
    	GPIO_InitTypeDef GPIO_InitStructure;
    	USART_InitTypeDef USART_InitStructure;
    /*********************************************************************************/
    	// 打开串口GPIO的时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    	
    	// 打开串口外设的时钟
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);	
    	
    	// 将USART2的TXD配置为推挽复用模式
    	GPIO_InitStructure.GPIO_Pin    = USART2_TXD_GPIO_PIN;
    	GPIO_InitStructure.GPIO_Mode   = GPIO_Mode_AF_PP;
    	GPIO_InitStructure.GPIO_Speed  = GPIO_Speed_50MHz;
    	GPIO_Init(USART2_TXD_GPIO_PORT, &GPIO_InitStructure);
      
    	// 将USART2的RXD配置为浮空输入模式
    	GPIO_InitStructure.GPIO_Pin    = USART2_RXD_GPIO_PIN;
    	GPIO_InitStructure.GPIO_Mode   = GPIO_Mode_IN_FLOATING;
    	GPIO_Init(USART2_RXD_GPIO_PORT, &GPIO_InitStructure);
    	
    	// 配置串口2的工作参数
    	// 配置波特率19200
    	USART_InitStructure.USART_BaudRate = 19200;
    	// 配置 帧数据字长
    	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;
    	
    	// 完成串口2的初始化配置
    	USART_Init(CD4067_USART, &USART_InitStructure);
        
    	// 串口2中断优先级配置
    	NVIC_Config(NVIC_PriorityGroup_1 ,MCD4067_USART_IRQn ,1 ,2);
        
    	// 使能串口2接收中断
    	USART_ITConfig(CD4067_USART, USART_IT_RXNE, ENABLE);
    	USART_ITConfig(CD4067_USART, USART_IT_IDLE, ENABLE);//USART_IT_IDLE为帧数据接收
        
    	// 使能串口2
    	USART_Cmd(CD4067_USART, ENABLE);
    	
    /*********************************************************************************/
    
    	// 打开串口GPIO的时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    	
    	// 打开串口外设的时钟
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
    
    	// 将USART3的TXD配置为推挽复用模式
    	GPIO_InitStructure.GPIO_Pin    = USART3_TXD_GPIO_PIN;
    	GPIO_InitStructure.GPIO_Mode   = GPIO_Mode_AF_PP;
    	GPIO_InitStructure.GPIO_Speed  = GPIO_Speed_50MHz;
    	GPIO_Init(USART3_TXD_GPIO_PORT, &GPIO_InitStructure);
        
      // 将USART3的RXD配置为浮空输入模式
    	GPIO_InitStructure.GPIO_Pin    = USART3_RXD_GPIO_PIN;
    	GPIO_InitStructure.GPIO_Mode   = GPIO_Mode_IN_FLOATING;
    	GPIO_Init(USART3_RXD_GPIO_PORT, &GPIO_InitStructure);
        
    	// 配置串口3的工作参数
    	// 配置波特率115200
    	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;
        
    	// 完成串口3的初始化配置
    	USART_Init(MAX3483_USART, &USART_InitStructure);
        
    	// 串口3中断优先级配置
    	NVIC_Config(NVIC_PriorityGroup_1 ,MAX3483_USART_IRQn ,1 ,1);
        
    	// 使能串口3接收中断
    	USART_ITConfig(MAX3483_USART, USART_IT_RXNE, ENABLE);
    	USART_ITConfig(MAX3483_USART, USART_IT_IDLE, ENABLE);//USART_IT_IDLE为帧数据接收
        
    	// 使能串口3
    	USART_Cmd(MAX3483_USART, ENABLE);	
    }
    /*******************************************************************************
    * Function Name  : NVIC_Config
    * Description    : NVIC配置
    * Input          : @arg NVIC_PriorityGroup_x(x:0~4)
    *				   @ref IRQn_Type
    *				   @ref NVIC_Priority_Table
    *                  @ref NVIC_Priority_Table
    * Output         : 无
    * Return         : 无
    *******************************************************************************/
    static void NVIC_Config( uint32_t NVIC_PriorityGroup , \
    	
    												 IRQn_Type NVIC_IRQChannel ,   \
    
    												 uint8_t PreemptionPriority ,  \
    
    												 uint8_t SubPriority )
    {
      NVIC_InitTypeDef NVIC_InitStructure;
      
      /* 嵌套向量中断控制器组选择 */
      NVIC_PriorityGroupConfig(NVIC_PriorityGroup);
      
      /* 配置为中断源 */
      NVIC_InitStructure.NVIC_IRQChannel = NVIC_IRQChannel;
      /* 抢断优先级*/
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriority;
      /* 子优先级 */
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = SubPriority;
      /* 使能中断 */
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      /* 初始化配置NVIC */
      NVIC_Init(&NVIC_InitStructure);
    }
    

    这是三个用来发送不同数据的函数

    /*******************************************************************************
    * Function Name  : Usart_SendByte 
    * Description    : 发送一个字节
    * Input          : @arg USARTx
    *                  @arg data(8位)
    * Output         : 无
    * Return         : 无
    *******************************************************************************/
    void Usart_SendByte(USART_TypeDef* USARTx, uint8_t data)
    {
    	USART_SendData(USARTx, data);
    	while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
    }
    
    /*******************************************************************************
    * Function Name  : Usart_SendHalfWord 
    * Description    : 发送二个字节
    * Input          : @arg USARTx
    *                  @arg data(16位)
    * Output         : 无
    * Return         : 无
    *******************************************************************************/
    void Usart_SendHalfWord(USART_TypeDef* USARTx, uint16_t data)
    {
    	uint8_t temp_h,temp_l;
    	
    	temp_h = (data&0xFF00) >> 8 ;
    	temp_l = data&0xFF;
    	
    	USART_SendData(USARTx, temp_h);
    	while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
    	
    	USART_SendData(USARTx, temp_l);
    	while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
    }
    
    /*******************************************************************************
    * Function Name  : Usart_SendStr
    * Description    : 发送字符串 
    * Input          : @arg USARTx
    *                  @arg *str
    * Output         : 无
    * Return         : 无
    *******************************************************************************/
    void Usart_SendStr(USART_TypeDef* USARTx, uint8_t *str)
    {
    	uint8_t i=0;
    	do
    	{
    		Usart_SendByte(USARTx, *(str+i));
    		i++;
    	}while(*(str+i)!='\0');
    	while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );//TC是一连串数据发送完毕的标志位
    }
    

    2、与MAX3483相关的代码部分

    .h文件

    #ifndef __OUT_DATA_232_H
    #define __OUT_DATA_232_H
    #include "stm32f10x.h"
    
    void set_MAX3483_out(void);//设置MAX3483芯片使得能够发送数据
    void set_MAX3483_in(void);//设置MAX3483芯片使得能够接收中断和数据
    
    
    #endif /* __OUT_DATA_232_H */
    

    .c文件

    #include "out_data_232.h"
    #include "main.h"
    
    /*******************************************************************************
    * Function Name  : set_MAX3483_out
    * Description    : 设置MAX3483芯片使得能够发送数据
    * Input          : 无
    * Output         : 无
    * Return         : 无
    *******************************************************************************/
    void set_MAX3483_out(void)
    {
    	GPIO_SetBits(MAX3483_485_DE_PORT, MAX3483_485_DE_PIN);//设置MAX3483芯片使得能够发送数据
    	GPIO_SetBits(MAX3483_485_RE_PORT, MAX3483_485_RE_PIN);//设置MAX3483芯片使得能够发送数据
    }
    
    /*******************************************************************************
    * Function Name  : set_MAX3483_in
    * Description    : 设置MAX3483芯片使得能够接收中断和数据
    * Input          : 无
    * Output         : 无
    * Return         : 无
    *******************************************************************************/
    void set_MAX3483_in(void)
    {
    	GPIO_ResetBits(MAX3483_485_DE_PORT, MAX3483_485_DE_PIN);//设置MAX3483芯片使得能够接收中断和数据
    	GPIO_ResetBits(MAX3483_485_RE_PORT, MAX3483_485_RE_PIN);//设置MAX3483芯片使得能够接收中断和数据
    }
    

    3、中断服务代码

    关键的代码部分在这hhhh,具体解释就略去了,代码注释很详细。
    调试过程中的插曲

    while( USART_GetFlagStatus(MAX3483_USART, USART_FLAG_TC) == RESET );//TC是一连串数据发送完毕的标志位
    

    下面.c文件中的此处,不能使用库函数USART_GetITStatus,否则会卡死,具体没深究了,待有空了慢慢DEBUG。
    注:数据回传功能最好不要写在中断中,因为要考虑其他情况,要遵守“中断处理函数越短越好,越简单越好 ”的原则。

    .c文件

    uint8_t ch[10];//串口接收缓存数组
    uint8_t RxCounter = 0;//缓存数组计数标志
    
    // 串口3中断服务函数
    void USART3_IRQHandler(void)
    {
    	//一个字节进一次中断,一帧结束进一次中断
    	if(USART_GetITStatus(MAX3483_USART, USART_IT_RXNE) != RESET)//接收到一个字节,标志位置位
    	{
    		ch[RxCounter++] = USART_ReceiveData(MAX3483_USART);//接收到一个字节,缓存进数组
    	} 
    	else if(USART_GetITStatus(MAX3483_USART,USART_IT_IDLE) != RESET)//接收到一帧数据,标志位置位
    	{
    		MAX3483_USART->SR;//先读SR
    		MAX3483_USART->DR;//再读DR
    		RxCounter = 0;//一帧数据接收结束,标志重置
    		
    /******************************************************************************/
    /*                                  DEBUG                                     */
    /******************************************************************************/
    		set_MAX3483_out();//设置MAX3483芯片使得能够发送数据
    		for(uint8_t j = 0;j < 10 ;j++)
    		{
    			Usart_SendByte(MAX3483_USART, ch[j]);//DEBUG
    		}
    		while( USART_GetFlagStatus(MAX3483_USART, USART_FLAG_TC) == RESET );//TC是一连串数据发送完毕的标志位
    		set_MAX3483_in();//设置MAX3483芯片使得能够接收中断和数据
    /******************************************************************************/
    /*                                  DEBUG                                     */
    /******************************************************************************/
    	}
    }
    

    main函数记得默认打开接收,否则无法接收数据产生中断

    set_MAX3483_in();//设置MAX3483,上位机向单片机发送数据
    			//(默认保持接收状态,才可进入串口中断服务)
    

    四、末尾

    写完发现其实没啥语言描述,哈哈哈哈哈.
    经典CV工程师,CTRL+C/CTRL+V。

    展开全文
  • 文章目录前言第一步:用于保存数据的数组和变量第二步:定义串口初始化函数第三步:定义串口数据发送函数第四步:重写中断服务函数第五步:在 main 函数中处理接收到的数据并通过串口发送出去 前言 测试过程中使用...
  • 文章目录一:STM32中断介绍二:高低电平控制控制LED灯亮和灭 一:STM32中断介绍 ...速度匹配:可以解决快速的CPU与慢速的外部设备之间传送数据的矛盾。 分时操作:CPU可以分时为多个外部设备服务,提高计算机的
  • 串口中断 SM2:多机通信控制位, (0:数据直接进入SBUF,并同时使R1致1) T1:发送中断标志位,(收到数据自动由硬件致1,并且同时执行中断程序,也必须在中断程序中写0) RI:接收中断标志位,(收到数据自动由...
  • 想写一个简单的串口通信程序(中断接收pc发送数据,并随之发送给pc),大概内容如下:初始化USART1和NVIC,USART1_Config();NVIC_Config();中断函数如下:voidUSART1_IRQHandler(vo...想写一个简单的串口通信程序...
  • 串口中断发送 首先定义一个数组,把你想发的数据存里面 然后发就完事了,很简单,就一行代码!巨简单有木有 我们看一下发送函数的源码 发送函数有三个参数,第一个是结构体UART_HandleTypeDef类型的指针,在usart.c...
  • 串口中断测试程序

    2021-05-26 02:53:11
     //开串口收的中断 } /* ************************************************************************************************************* - 函数名称 : void UartInit(void) - 函数说明 : 串口0的初始化函数 - ...
  • CubeMX,HAL库使用串口...打开串口中断 二、MDK代码 在/* Private define */出定义一个接收中断缓冲区 /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD *
  • 原来调过STM8L的串口,逻辑简单,中断清晰,换成STM8S105K4后,虽然也是用STD库,除去函数名、宏名等语言层面的差异以外,中断处理方面也有些不一样的地方,特此记之。和此篇【STM8L USART串口使用】结构相同,也是...
  • 串口调用DMA发送数据后,必须等待数据发送完成才能修改发送DMA缓冲区中的数据启动下一次发送,否则会导致上次发送被覆盖。实际发送后有等待DMA发送完成,但是连续两个数据发送依旧会导致丢失。 HAL_UART_Transmit_
  • 这里使用USART1串口 usart.c中添加 (1)添加全局变量 uint8_t USART1_Buff[100] = {0}; //接收帧缓存,自己定义大小 uint8_t USART1_STA = 0; bool USART1_Receive_Flag = false; uint8_t res = 0; (2)在MX...
  • STM32串口DMA发送数据

    2021-10-30 10:16:07
    了解了DMA之后,我们做一个实验:STM32采用串口DMA方式,用115200bps或更高速率向上位机连续发送数据 1.建立工程 使用STM32CubeMX可以配置代码,省时省力,首先打开STMCubeMX新建一个工程,然后选择对应的芯片 2....
  • } / *函数名称:Send_UART_String *函数功能:数据发送 *入口函数:Receive_UART_String() *出口函数: **********************/ void Send_UART_String(char c) { LED1=0; LED2=1; U0DBUF=c; while(UTX0IF==0); ...
  • 这里写目录标题串口发送数据串口接受数据 串口发送数据 1、串口发送数据最直接的方式就是标准调用库函数 。 void USART_SendData(USART_TypeDef* USARTx, uint16_t Data); 第一个参数是发送的串口号,第二个参数是...
  • 在进行PID参数整定的工作过程中,我需要...在整个过程中采用了Matlab来进行串口数据的读写。目前整个流程已经走通,在此将实现过程中遇到的问题,解决方法,以及尚未解决的疑问进行总结。首先声明本人是一个初学Mat...
  • STM32如何利用串口发送接收数据

    千次阅读 热门讨论 2021-05-08 11:38:49
    1、我先利用正点原子向串口助手发送数据: (1)发送单字节 利用正点原子开发板自己程序就可以实现了。 点击“发送”后,单字符“a”会发送到开发板的MCU中,然后又重新发送到XCOM中。但是有时候点击发送后,字符...
  • 51串口发送数据

    千次阅读 2021-01-20 15:33:45
    串口通信为串行通信方式,即每次只能发送一位,且为单工,一端固定为发送端,另一端为接收端。 51单片机的串口需要配置的寄存器可以直接通过STC-ISP这个软件配置,选择好晶振的频率和波特率直接生成就可以了 下面...
  • 可以改成下面这样/* UART in mode Receiver -------------------------------------------------*/if ((__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_RXNE) != RESET) &&(__HAL_UART_GET_IT_...
  • //再开启接收中断 } /* USER CODE END 4 */ (6)编译运行,进行烧录 (7)串口通信结果 进行通信,boot0接0 串口每隔0.5s输出Hello windows 四、总结 中断方式不必等待数据的传输过程,只需要在每字节数据收发完成...
  • STM32串口发送接收数据

    千次阅读 热门讨论 2021-07-14 18:56:39
    目录串口通信串口的结构体如何配置串口发送通过串口向电脑发送ok字符 串口通信 我用的32是stm32f10x最小系统没有UART4和UART5 USART : 通用同步异步收发器 UART : 通用异步收发器 nRTS : 请求发送 nCTS : 请求...
  • 串口三种方式工作,轮询、中断和DMA;...**中断发送:**发送完一个字节CPU响应中断将下个字节放到外设寄存器,直到整个字符串发完,发完后再相应中断,补货…,这样的话发送中断就只有在中断时占用CPU资源; ...
  • 如果串口接收数据,数据传输的比较快,这个时候还要使用同一个串口发送数据。 如果是在主函数中使用HAL_UART_Receive();,这个时候不管使用HAL_UART_Transmit();还是使用HAL_UART_Transmit_DMA();发送的数据都不完整...
  • 由于项目上用的STM32单片机串口资源不够用,但是还是想看调试输出,所以就多引出了一个IO,使用IO模拟串口发送数据的时序来当做串口打印用了,本章实验工程以8bit数据位、1bit停止位,无奇偶校验、无流控,波特率...
  • 并不是说不使能串口接受中断就无法接收数据,只是为了在串口接收数据的时候防止其程序打扰串口数据的接收,所以跑到中断中去接收数据。 不使用串口接收中断的情况下,数据会到DR,然后你及时把DR的数据读出来,不然...
  • 校验位(无校验) 数据位(8) 停止位默认(1) USCI——Ax模块:支持 USCI——Bx模块 定时器模式选择 计数模式 四种工作模式 两种:捕捉/比较 三种用途:定时、产生PWM波(脉冲宽度调制)、测量频率(两个信号时间...
  • 下面的代码K210发送的是一个不大于三位数的ASCII码数据,使用STM32串口中断服务函数进行接收并进行转化为int型。 void X_USART_IRQHandler(void) { uint8_t xieding=0; ```c if(USART_GetITStatus(X_USART,USART...
  • STM32串口中断接收一帧数据

    千次阅读 2021-01-03 22:52:57
    STM32串口中断接收一帧数据 IDLE即串口空闲中断,串口收到一帧数据后,发生的中断。比如说给单片机一次发来1个字节,或者一次发来8个字节,这些一次发来的数据,就称为一帧数据,也可以叫做一包数据。因为只有接收...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 34,219
精华内容 13,687
关键字:

串口中断发送数据